xref: /aosp_15_r20/frameworks/av/media/module/foundation/ALooperRoster.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ALooperRoster"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <utils/String8.h>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker #include "ALooperRoster.h"
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker #include "ADebug.h"
27*ec779b8eSAndroid Build Coastguard Worker #include "AHandler.h"
28*ec779b8eSAndroid Build Coastguard Worker #include "AMessage.h"
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker namespace android {
31*ec779b8eSAndroid Build Coastguard Worker 
32*ec779b8eSAndroid Build Coastguard Worker static bool verboseStats = false;
33*ec779b8eSAndroid Build Coastguard Worker 
ALooperRoster()34*ec779b8eSAndroid Build Coastguard Worker ALooperRoster::ALooperRoster()
35*ec779b8eSAndroid Build Coastguard Worker     : mNextHandlerID(1) {
36*ec779b8eSAndroid Build Coastguard Worker }
37*ec779b8eSAndroid Build Coastguard Worker 
registerHandler(const sp<ALooper> & looper,const sp<AHandler> & handler)38*ec779b8eSAndroid Build Coastguard Worker ALooper::handler_id ALooperRoster::registerHandler(
39*ec779b8eSAndroid Build Coastguard Worker         const sp<ALooper> &looper, const sp<AHandler> &handler) {
40*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
41*ec779b8eSAndroid Build Coastguard Worker 
42*ec779b8eSAndroid Build Coastguard Worker     if (handler->id() != 0) {
43*ec779b8eSAndroid Build Coastguard Worker         CHECK(!"A handler must only be registered once.");
44*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
45*ec779b8eSAndroid Build Coastguard Worker     }
46*ec779b8eSAndroid Build Coastguard Worker 
47*ec779b8eSAndroid Build Coastguard Worker     HandlerInfo info;
48*ec779b8eSAndroid Build Coastguard Worker     info.mLooper = looper;
49*ec779b8eSAndroid Build Coastguard Worker     info.mHandler = handler;
50*ec779b8eSAndroid Build Coastguard Worker     ALooper::handler_id handlerID = mNextHandlerID++;
51*ec779b8eSAndroid Build Coastguard Worker     mHandlers.add(handlerID, info);
52*ec779b8eSAndroid Build Coastguard Worker 
53*ec779b8eSAndroid Build Coastguard Worker     handler->setID(handlerID, looper);
54*ec779b8eSAndroid Build Coastguard Worker 
55*ec779b8eSAndroid Build Coastguard Worker     return handlerID;
56*ec779b8eSAndroid Build Coastguard Worker }
57*ec779b8eSAndroid Build Coastguard Worker 
unregisterHandler(ALooper::handler_id handlerID)58*ec779b8eSAndroid Build Coastguard Worker void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
59*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
60*ec779b8eSAndroid Build Coastguard Worker 
61*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mHandlers.indexOfKey(handlerID);
62*ec779b8eSAndroid Build Coastguard Worker 
63*ec779b8eSAndroid Build Coastguard Worker     if (index < 0) {
64*ec779b8eSAndroid Build Coastguard Worker         return;
65*ec779b8eSAndroid Build Coastguard Worker     }
66*ec779b8eSAndroid Build Coastguard Worker 
67*ec779b8eSAndroid Build Coastguard Worker     const HandlerInfo &info = mHandlers.valueAt(index);
68*ec779b8eSAndroid Build Coastguard Worker 
69*ec779b8eSAndroid Build Coastguard Worker     sp<AHandler> handler = info.mHandler.promote();
70*ec779b8eSAndroid Build Coastguard Worker 
71*ec779b8eSAndroid Build Coastguard Worker     if (handler != NULL) {
72*ec779b8eSAndroid Build Coastguard Worker         handler->setID(0, NULL);
73*ec779b8eSAndroid Build Coastguard Worker     }
74*ec779b8eSAndroid Build Coastguard Worker 
75*ec779b8eSAndroid Build Coastguard Worker     mHandlers.removeItemsAt(index);
76*ec779b8eSAndroid Build Coastguard Worker }
77*ec779b8eSAndroid Build Coastguard Worker 
unregisterStaleHandlers()78*ec779b8eSAndroid Build Coastguard Worker void ALooperRoster::unregisterStaleHandlers() {
79*ec779b8eSAndroid Build Coastguard Worker 
80*ec779b8eSAndroid Build Coastguard Worker     Vector<sp<ALooper> > activeLoopers;
81*ec779b8eSAndroid Build Coastguard Worker     {
82*ec779b8eSAndroid Build Coastguard Worker         Mutex::Autolock autoLock(mLock);
83*ec779b8eSAndroid Build Coastguard Worker 
84*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = mHandlers.size(); i > 0;) {
85*ec779b8eSAndroid Build Coastguard Worker             i--;
86*ec779b8eSAndroid Build Coastguard Worker             const HandlerInfo &info = mHandlers.valueAt(i);
87*ec779b8eSAndroid Build Coastguard Worker 
88*ec779b8eSAndroid Build Coastguard Worker             sp<ALooper> looper = info.mLooper.promote();
89*ec779b8eSAndroid Build Coastguard Worker             if (looper == NULL) {
90*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("Unregistering stale handler %d", mHandlers.keyAt(i));
91*ec779b8eSAndroid Build Coastguard Worker                 mHandlers.removeItemsAt(i);
92*ec779b8eSAndroid Build Coastguard Worker             } else {
93*ec779b8eSAndroid Build Coastguard Worker                 // At this point 'looper' might be the only sp<> keeping
94*ec779b8eSAndroid Build Coastguard Worker                 // the object alive. To prevent it from going out of scope
95*ec779b8eSAndroid Build Coastguard Worker                 // and having ~ALooper call this method again recursively
96*ec779b8eSAndroid Build Coastguard Worker                 // and then deadlocking because of the Autolock above, add
97*ec779b8eSAndroid Build Coastguard Worker                 // it to a Vector which will go out of scope after the lock
98*ec779b8eSAndroid Build Coastguard Worker                 // has been released.
99*ec779b8eSAndroid Build Coastguard Worker                 activeLoopers.add(looper);
100*ec779b8eSAndroid Build Coastguard Worker             }
101*ec779b8eSAndroid Build Coastguard Worker         }
102*ec779b8eSAndroid Build Coastguard Worker     }
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker 
makeFourCC(uint32_t fourcc,char * s,size_t bufsz)105*ec779b8eSAndroid Build Coastguard Worker static void makeFourCC(uint32_t fourcc, char *s, size_t bufsz) {
106*ec779b8eSAndroid Build Coastguard Worker     s[0] = (fourcc >> 24) & 0xff;
107*ec779b8eSAndroid Build Coastguard Worker     if (s[0]) {
108*ec779b8eSAndroid Build Coastguard Worker         s[1] = (fourcc >> 16) & 0xff;
109*ec779b8eSAndroid Build Coastguard Worker         s[2] = (fourcc >> 8) & 0xff;
110*ec779b8eSAndroid Build Coastguard Worker         s[3] = fourcc & 0xff;
111*ec779b8eSAndroid Build Coastguard Worker         s[4] = 0;
112*ec779b8eSAndroid Build Coastguard Worker     } else {
113*ec779b8eSAndroid Build Coastguard Worker         snprintf(s, bufsz, "%u", fourcc);
114*ec779b8eSAndroid Build Coastguard Worker     }
115*ec779b8eSAndroid Build Coastguard Worker }
116*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd,const Vector<String16> & args)117*ec779b8eSAndroid Build Coastguard Worker void ALooperRoster::dump(int fd, const Vector<String16>& args) {
118*ec779b8eSAndroid Build Coastguard Worker     bool clear = false;
119*ec779b8eSAndroid Build Coastguard Worker     bool oldVerbose = verboseStats;
120*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < args.size(); i++) {
121*ec779b8eSAndroid Build Coastguard Worker         if (args[i] == String16("-c")) {
122*ec779b8eSAndroid Build Coastguard Worker             clear = true;
123*ec779b8eSAndroid Build Coastguard Worker         } else if (args[i] == String16("-von")) {
124*ec779b8eSAndroid Build Coastguard Worker             verboseStats = true;
125*ec779b8eSAndroid Build Coastguard Worker         } else if (args[i] == String16("-voff")) {
126*ec779b8eSAndroid Build Coastguard Worker             verboseStats = false;
127*ec779b8eSAndroid Build Coastguard Worker         }
128*ec779b8eSAndroid Build Coastguard Worker     }
129*ec779b8eSAndroid Build Coastguard Worker     String8 s;
130*ec779b8eSAndroid Build Coastguard Worker     if (verboseStats && !oldVerbose) {
131*ec779b8eSAndroid Build Coastguard Worker         s.append("(verbose stats collection enabled, stats will be cleared)\n");
132*ec779b8eSAndroid Build Coastguard Worker     }
133*ec779b8eSAndroid Build Coastguard Worker 
134*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
135*ec779b8eSAndroid Build Coastguard Worker     size_t n = mHandlers.size();
136*ec779b8eSAndroid Build Coastguard Worker     s.appendFormat(" %zu registered handlers:\n", n);
137*ec779b8eSAndroid Build Coastguard Worker 
138*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < n; i++) {
139*ec779b8eSAndroid Build Coastguard Worker         s.appendFormat("  %d: ", mHandlers.keyAt(i));
140*ec779b8eSAndroid Build Coastguard Worker         HandlerInfo &info = mHandlers.editValueAt(i);
141*ec779b8eSAndroid Build Coastguard Worker         sp<ALooper> looper = info.mLooper.promote();
142*ec779b8eSAndroid Build Coastguard Worker         if (looper != NULL) {
143*ec779b8eSAndroid Build Coastguard Worker             s.append(looper->getName());
144*ec779b8eSAndroid Build Coastguard Worker             sp<AHandler> handler = info.mHandler.promote();
145*ec779b8eSAndroid Build Coastguard Worker             if (handler != NULL) {
146*ec779b8eSAndroid Build Coastguard Worker                 bool deliveringMessages;
147*ec779b8eSAndroid Build Coastguard Worker                 uint32_t currentMessageWhat;
148*ec779b8eSAndroid Build Coastguard Worker                 int64_t currentDeliveryDurationUs;
149*ec779b8eSAndroid Build Coastguard Worker                 handler->getDeliveryStatus(deliveringMessages,
150*ec779b8eSAndroid Build Coastguard Worker                                            currentMessageWhat,
151*ec779b8eSAndroid Build Coastguard Worker                                            currentDeliveryDurationUs);
152*ec779b8eSAndroid Build Coastguard Worker                 handler->mVerboseStats = verboseStats;
153*ec779b8eSAndroid Build Coastguard Worker                 s.appendFormat(": %" PRIu64 " messages processed, delivering "
154*ec779b8eSAndroid Build Coastguard Worker                                "%d, current msg %" PRIu32 ", current msg "
155*ec779b8eSAndroid Build Coastguard Worker                                "durationUs %" PRIu64 "",
156*ec779b8eSAndroid Build Coastguard Worker                                handler->mMessageCounter,
157*ec779b8eSAndroid Build Coastguard Worker                                deliveringMessages,
158*ec779b8eSAndroid Build Coastguard Worker                                currentMessageWhat,
159*ec779b8eSAndroid Build Coastguard Worker                                currentDeliveryDurationUs);
160*ec779b8eSAndroid Build Coastguard Worker                 if (verboseStats) {
161*ec779b8eSAndroid Build Coastguard Worker                     for (size_t j = 0; j < handler->mMessages.size(); j++) {
162*ec779b8eSAndroid Build Coastguard Worker                         char fourcc[15];
163*ec779b8eSAndroid Build Coastguard Worker                         makeFourCC(handler->mMessages.keyAt(j), fourcc, sizeof(fourcc));
164*ec779b8eSAndroid Build Coastguard Worker                         s.appendFormat("\n    %s: %u",
165*ec779b8eSAndroid Build Coastguard Worker                                 fourcc,
166*ec779b8eSAndroid Build Coastguard Worker                                 handler->mMessages.valueAt(j));
167*ec779b8eSAndroid Build Coastguard Worker                     }
168*ec779b8eSAndroid Build Coastguard Worker                 } else {
169*ec779b8eSAndroid Build Coastguard Worker                     handler->mMessages.clear();
170*ec779b8eSAndroid Build Coastguard Worker                 }
171*ec779b8eSAndroid Build Coastguard Worker                 if (clear || (verboseStats && !oldVerbose)) {
172*ec779b8eSAndroid Build Coastguard Worker                     handler->mMessageCounter = 0;
173*ec779b8eSAndroid Build Coastguard Worker                     handler->mMessages.clear();
174*ec779b8eSAndroid Build Coastguard Worker                 }
175*ec779b8eSAndroid Build Coastguard Worker             } else {
176*ec779b8eSAndroid Build Coastguard Worker                 s.append(": <stale handler>");
177*ec779b8eSAndroid Build Coastguard Worker             }
178*ec779b8eSAndroid Build Coastguard Worker         } else {
179*ec779b8eSAndroid Build Coastguard Worker             s.append("<stale>");
180*ec779b8eSAndroid Build Coastguard Worker         }
181*ec779b8eSAndroid Build Coastguard Worker         s.append("\n");
182*ec779b8eSAndroid Build Coastguard Worker     }
183*ec779b8eSAndroid Build Coastguard Worker     (void)write(fd, s.c_str(), s.size());
184*ec779b8eSAndroid Build Coastguard Worker }
185*ec779b8eSAndroid Build Coastguard Worker 
186*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
187