xref: /aosp_15_r20/frameworks/av/services/mediaresourcemanager/ResourceObserverService.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /**
2*ec779b8eSAndroid Build Coastguard Worker  *
3*ec779b8eSAndroid Build Coastguard Worker  * Copyright 2020, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker  *
5*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker  *
9*ec779b8eSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker  *
11*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker  */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ResourceObserverService"
20*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <android/binder_manager.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <android/binder_process.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/String16.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/media/MediaResourceParcel.h>
27*ec779b8eSAndroid Build Coastguard Worker 
28*ec779b8eSAndroid Build Coastguard Worker #include "ResourceObserverService.h"
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker namespace android {
31*ec779b8eSAndroid Build Coastguard Worker 
32*ec779b8eSAndroid Build Coastguard Worker using ::aidl::android::media::MediaResourceParcel;
33*ec779b8eSAndroid Build Coastguard Worker using ::aidl::android::media::MediaObservableEvent;
34*ec779b8eSAndroid Build Coastguard Worker 
35*ec779b8eSAndroid Build Coastguard Worker // MediaObservableEvent will be used as uint64_t flags.
36*ec779b8eSAndroid Build Coastguard Worker static_assert(sizeof(MediaObservableEvent) == sizeof(uint64_t));
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker static std::vector<MediaObservableEvent> sEvents = {
39*ec779b8eSAndroid Build Coastguard Worker         MediaObservableEvent::kBusy,
40*ec779b8eSAndroid Build Coastguard Worker         MediaObservableEvent::kIdle,
41*ec779b8eSAndroid Build Coastguard Worker };
42*ec779b8eSAndroid Build Coastguard Worker 
getObservableType(const MediaResourceParcel & res)43*ec779b8eSAndroid Build Coastguard Worker static MediaObservableType getObservableType(const MediaResourceParcel& res) {
44*ec779b8eSAndroid Build Coastguard Worker     if (res.subType == MediaResourceSubType::kHwVideoCodec ||
45*ec779b8eSAndroid Build Coastguard Worker         res.subType == MediaResourceSubType::kSwVideoCodec) {
46*ec779b8eSAndroid Build Coastguard Worker         if (res.type == MediaResourceType::kNonSecureCodec) {
47*ec779b8eSAndroid Build Coastguard Worker             return MediaObservableType::kVideoNonSecureCodec;
48*ec779b8eSAndroid Build Coastguard Worker         }
49*ec779b8eSAndroid Build Coastguard Worker         if (res.type == MediaResourceType::kSecureCodec) {
50*ec779b8eSAndroid Build Coastguard Worker             return MediaObservableType::kVideoSecureCodec;
51*ec779b8eSAndroid Build Coastguard Worker         }
52*ec779b8eSAndroid Build Coastguard Worker     }
53*ec779b8eSAndroid Build Coastguard Worker     return MediaObservableType::kInvalid;
54*ec779b8eSAndroid Build Coastguard Worker }
55*ec779b8eSAndroid Build Coastguard Worker 
56*ec779b8eSAndroid Build Coastguard Worker //static
57*ec779b8eSAndroid Build Coastguard Worker std::mutex ResourceObserverService::sDeathRecipientLock;
58*ec779b8eSAndroid Build Coastguard Worker //static
59*ec779b8eSAndroid Build Coastguard Worker std::map<uintptr_t, std::shared_ptr<ResourceObserverService::DeathRecipient> >
60*ec779b8eSAndroid Build Coastguard Worker ResourceObserverService::sDeathRecipientMap;
61*ec779b8eSAndroid Build Coastguard Worker 
62*ec779b8eSAndroid Build Coastguard Worker struct ResourceObserverService::DeathRecipient {
DeathRecipientandroid::ResourceObserverService::DeathRecipient63*ec779b8eSAndroid Build Coastguard Worker     DeathRecipient(ResourceObserverService* _service,
64*ec779b8eSAndroid Build Coastguard Worker             const std::shared_ptr<IResourceObserver>& _observer)
65*ec779b8eSAndroid Build Coastguard Worker         : service(_service), observer(_observer) {}
~DeathRecipientandroid::ResourceObserverService::DeathRecipient66*ec779b8eSAndroid Build Coastguard Worker     ~DeathRecipient() {}
67*ec779b8eSAndroid Build Coastguard Worker 
binderDiedandroid::ResourceObserverService::DeathRecipient68*ec779b8eSAndroid Build Coastguard Worker     void binderDied() {
69*ec779b8eSAndroid Build Coastguard Worker         if (service != nullptr) {
70*ec779b8eSAndroid Build Coastguard Worker             service->unregisterObserver(observer);
71*ec779b8eSAndroid Build Coastguard Worker         }
72*ec779b8eSAndroid Build Coastguard Worker     }
73*ec779b8eSAndroid Build Coastguard Worker 
74*ec779b8eSAndroid Build Coastguard Worker     ResourceObserverService* service;
75*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<IResourceObserver> observer;
76*ec779b8eSAndroid Build Coastguard Worker };
77*ec779b8eSAndroid Build Coastguard Worker 
78*ec779b8eSAndroid Build Coastguard Worker // static
BinderDiedCallback(void * cookie)79*ec779b8eSAndroid Build Coastguard Worker void ResourceObserverService::BinderDiedCallback(void* cookie) {
80*ec779b8eSAndroid Build Coastguard Worker     uintptr_t id = reinterpret_cast<uintptr_t>(cookie);
81*ec779b8eSAndroid Build Coastguard Worker 
82*ec779b8eSAndroid Build Coastguard Worker     ALOGW("Observer %lld is dead", (long long)id);
83*ec779b8eSAndroid Build Coastguard Worker 
84*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<DeathRecipient> recipient;
85*ec779b8eSAndroid Build Coastguard Worker 
86*ec779b8eSAndroid Build Coastguard Worker     {
87*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{sDeathRecipientLock};
88*ec779b8eSAndroid Build Coastguard Worker 
89*ec779b8eSAndroid Build Coastguard Worker         auto it = sDeathRecipientMap.find(id);
90*ec779b8eSAndroid Build Coastguard Worker         if (it != sDeathRecipientMap.end()) {
91*ec779b8eSAndroid Build Coastguard Worker             recipient = it->second;
92*ec779b8eSAndroid Build Coastguard Worker         }
93*ec779b8eSAndroid Build Coastguard Worker     }
94*ec779b8eSAndroid Build Coastguard Worker 
95*ec779b8eSAndroid Build Coastguard Worker     if (recipient != nullptr) {
96*ec779b8eSAndroid Build Coastguard Worker         recipient->binderDied();
97*ec779b8eSAndroid Build Coastguard Worker     }
98*ec779b8eSAndroid Build Coastguard Worker }
99*ec779b8eSAndroid Build Coastguard Worker 
100*ec779b8eSAndroid Build Coastguard Worker //static
instantiate()101*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<ResourceObserverService> ResourceObserverService::instantiate() {
102*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<ResourceObserverService> observerService =
103*ec779b8eSAndroid Build Coastguard Worker             ::ndk::SharedRefBase::make<ResourceObserverService>();
104*ec779b8eSAndroid Build Coastguard Worker     binder_status_t status = AServiceManager_addServiceWithFlags(
105*ec779b8eSAndroid Build Coastguard Worker       observerService->asBinder().get(),ResourceObserverService::getServiceName(),
106*ec779b8eSAndroid Build Coastguard Worker       AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED);
107*ec779b8eSAndroid Build Coastguard Worker 
108*ec779b8eSAndroid Build Coastguard Worker     if (status != STATUS_OK) {
109*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
110*ec779b8eSAndroid Build Coastguard Worker     }
111*ec779b8eSAndroid Build Coastguard Worker     return observerService;
112*ec779b8eSAndroid Build Coastguard Worker }
113*ec779b8eSAndroid Build Coastguard Worker 
ResourceObserverService()114*ec779b8eSAndroid Build Coastguard Worker ResourceObserverService::ResourceObserverService()
115*ec779b8eSAndroid Build Coastguard Worker     : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {}
116*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd,const char **,uint32_t)117*ec779b8eSAndroid Build Coastguard Worker binder_status_t ResourceObserverService::dump(
118*ec779b8eSAndroid Build Coastguard Worker         int fd, const char** /*args*/, uint32_t /*numArgs*/) {
119*ec779b8eSAndroid Build Coastguard Worker     String8 result;
120*ec779b8eSAndroid Build Coastguard Worker 
121*ec779b8eSAndroid Build Coastguard Worker     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
122*ec779b8eSAndroid Build Coastguard Worker         result.format("Permission Denial: "
123*ec779b8eSAndroid Build Coastguard Worker                 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
124*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingPid(),
125*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingUid());
126*ec779b8eSAndroid Build Coastguard Worker         write(fd, result.c_str(), result.size());
127*ec779b8eSAndroid Build Coastguard Worker         return PERMISSION_DENIED;
128*ec779b8eSAndroid Build Coastguard Worker     }
129*ec779b8eSAndroid Build Coastguard Worker 
130*ec779b8eSAndroid Build Coastguard Worker     result.appendFormat("ResourceObserverService: %p\n", this);
131*ec779b8eSAndroid Build Coastguard Worker     result.appendFormat("  Registered Observers: %zu\n", mObserverInfoMap.size());
132*ec779b8eSAndroid Build Coastguard Worker 
133*ec779b8eSAndroid Build Coastguard Worker     {
134*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{mObserverLock};
135*ec779b8eSAndroid Build Coastguard Worker 
136*ec779b8eSAndroid Build Coastguard Worker         for (auto &observer : mObserverInfoMap) {
137*ec779b8eSAndroid Build Coastguard Worker             result.appendFormat("    Observer %p:\n", observer.second.binder.get());
138*ec779b8eSAndroid Build Coastguard Worker             for (auto &observable : observer.second.filters) {
139*ec779b8eSAndroid Build Coastguard Worker                 String8 enabledEventsStr;
140*ec779b8eSAndroid Build Coastguard Worker                 for (auto &event : sEvents) {
141*ec779b8eSAndroid Build Coastguard Worker                     if (((uint64_t)observable.eventFilter & (uint64_t)event) != 0) {
142*ec779b8eSAndroid Build Coastguard Worker                         if (!enabledEventsStr.empty()) {
143*ec779b8eSAndroid Build Coastguard Worker                             enabledEventsStr.append("|");
144*ec779b8eSAndroid Build Coastguard Worker                         }
145*ec779b8eSAndroid Build Coastguard Worker                         enabledEventsStr.append(toString(event).c_str());
146*ec779b8eSAndroid Build Coastguard Worker                     }
147*ec779b8eSAndroid Build Coastguard Worker                 }
148*ec779b8eSAndroid Build Coastguard Worker                 result.appendFormat("      %s: %s\n",
149*ec779b8eSAndroid Build Coastguard Worker                         toString(observable.type).c_str(), enabledEventsStr.c_str());
150*ec779b8eSAndroid Build Coastguard Worker             }
151*ec779b8eSAndroid Build Coastguard Worker         }
152*ec779b8eSAndroid Build Coastguard Worker     }
153*ec779b8eSAndroid Build Coastguard Worker 
154*ec779b8eSAndroid Build Coastguard Worker     write(fd, result.c_str(), result.size());
155*ec779b8eSAndroid Build Coastguard Worker     return OK;
156*ec779b8eSAndroid Build Coastguard Worker }
157*ec779b8eSAndroid Build Coastguard Worker 
registerObserver(const std::shared_ptr<IResourceObserver> & in_observer,const std::vector<MediaObservableFilter> & in_filters)158*ec779b8eSAndroid Build Coastguard Worker Status ResourceObserverService::registerObserver(
159*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<IResourceObserver>& in_observer,
160*ec779b8eSAndroid Build Coastguard Worker         const std::vector<MediaObservableFilter>& in_filters) {
161*ec779b8eSAndroid Build Coastguard Worker     if ((getpid() != AIBinder_getCallingPid()) &&
162*ec779b8eSAndroid Build Coastguard Worker             checkCallingPermission(
163*ec779b8eSAndroid Build Coastguard Worker             String16("android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER")) == false) {
164*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Permission Denial: "
165*ec779b8eSAndroid Build Coastguard Worker                 "can't registerObserver from pid=%d, uid=%d\n",
166*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingPid(),
167*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingUid());
168*ec779b8eSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(PERMISSION_DENIED);
169*ec779b8eSAndroid Build Coastguard Worker     }
170*ec779b8eSAndroid Build Coastguard Worker 
171*ec779b8eSAndroid Build Coastguard Worker     if (in_observer == nullptr) {
172*ec779b8eSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(BAD_VALUE);
173*ec779b8eSAndroid Build Coastguard Worker     }
174*ec779b8eSAndroid Build Coastguard Worker 
175*ec779b8eSAndroid Build Coastguard Worker     ::ndk::SpAIBinder binder = in_observer->asBinder();
176*ec779b8eSAndroid Build Coastguard Worker 
177*ec779b8eSAndroid Build Coastguard Worker     {
178*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{mObserverLock};
179*ec779b8eSAndroid Build Coastguard Worker 
180*ec779b8eSAndroid Build Coastguard Worker         if (mObserverInfoMap.find((uintptr_t)binder.get()) != mObserverInfoMap.end()) {
181*ec779b8eSAndroid Build Coastguard Worker             return Status::fromServiceSpecificError(ALREADY_EXISTS);
182*ec779b8eSAndroid Build Coastguard Worker         }
183*ec779b8eSAndroid Build Coastguard Worker 
184*ec779b8eSAndroid Build Coastguard Worker         if (in_filters.empty()) {
185*ec779b8eSAndroid Build Coastguard Worker             return Status::fromServiceSpecificError(BAD_VALUE);
186*ec779b8eSAndroid Build Coastguard Worker         }
187*ec779b8eSAndroid Build Coastguard Worker 
188*ec779b8eSAndroid Build Coastguard Worker         // Add observer info.
189*ec779b8eSAndroid Build Coastguard Worker         mObserverInfoMap.emplace((uintptr_t)binder.get(),
190*ec779b8eSAndroid Build Coastguard Worker                 ObserverInfo{binder, in_observer, in_filters});
191*ec779b8eSAndroid Build Coastguard Worker 
192*ec779b8eSAndroid Build Coastguard Worker         // Add observer to observable->subscribers map.
193*ec779b8eSAndroid Build Coastguard Worker         for (auto &filter : in_filters) {
194*ec779b8eSAndroid Build Coastguard Worker             for (auto &event : sEvents) {
195*ec779b8eSAndroid Build Coastguard Worker                 if (!((uint64_t)filter.eventFilter & (uint64_t)event)) {
196*ec779b8eSAndroid Build Coastguard Worker                     continue;
197*ec779b8eSAndroid Build Coastguard Worker                 }
198*ec779b8eSAndroid Build Coastguard Worker                 MediaObservableFilter key{filter.type, event};
199*ec779b8eSAndroid Build Coastguard Worker                 mObservableToSubscribersMap[key].emplace((uintptr_t)binder.get(), in_observer);
200*ec779b8eSAndroid Build Coastguard Worker             }
201*ec779b8eSAndroid Build Coastguard Worker         }
202*ec779b8eSAndroid Build Coastguard Worker     }
203*ec779b8eSAndroid Build Coastguard Worker 
204*ec779b8eSAndroid Build Coastguard Worker     // Add death binder and link.
205*ec779b8eSAndroid Build Coastguard Worker     uintptr_t cookie = (uintptr_t)binder.get();
206*ec779b8eSAndroid Build Coastguard Worker     {
207*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{sDeathRecipientLock};
208*ec779b8eSAndroid Build Coastguard Worker         sDeathRecipientMap.emplace(
209*ec779b8eSAndroid Build Coastguard Worker                 cookie, std::make_shared<DeathRecipient>(this, in_observer));
210*ec779b8eSAndroid Build Coastguard Worker     }
211*ec779b8eSAndroid Build Coastguard Worker 
212*ec779b8eSAndroid Build Coastguard Worker     AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(),
213*ec779b8eSAndroid Build Coastguard Worker                          reinterpret_cast<void*>(cookie));
214*ec779b8eSAndroid Build Coastguard Worker 
215*ec779b8eSAndroid Build Coastguard Worker     return Status::ok();
216*ec779b8eSAndroid Build Coastguard Worker }
217*ec779b8eSAndroid Build Coastguard Worker 
unregisterObserver(const std::shared_ptr<IResourceObserver> & in_observer)218*ec779b8eSAndroid Build Coastguard Worker Status ResourceObserverService::unregisterObserver(
219*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<IResourceObserver>& in_observer) {
220*ec779b8eSAndroid Build Coastguard Worker     if ((getpid() != AIBinder_getCallingPid()) &&
221*ec779b8eSAndroid Build Coastguard Worker             checkCallingPermission(
222*ec779b8eSAndroid Build Coastguard Worker             String16("android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER")) == false) {
223*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Permission Denial: "
224*ec779b8eSAndroid Build Coastguard Worker                 "can't unregisterObserver from pid=%d, uid=%d\n",
225*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingPid(),
226*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingUid());
227*ec779b8eSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(PERMISSION_DENIED);
228*ec779b8eSAndroid Build Coastguard Worker     }
229*ec779b8eSAndroid Build Coastguard Worker 
230*ec779b8eSAndroid Build Coastguard Worker     if (in_observer == nullptr) {
231*ec779b8eSAndroid Build Coastguard Worker         return Status::fromServiceSpecificError(BAD_VALUE);
232*ec779b8eSAndroid Build Coastguard Worker     }
233*ec779b8eSAndroid Build Coastguard Worker 
234*ec779b8eSAndroid Build Coastguard Worker     ::ndk::SpAIBinder binder = in_observer->asBinder();
235*ec779b8eSAndroid Build Coastguard Worker 
236*ec779b8eSAndroid Build Coastguard Worker     {
237*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{mObserverLock};
238*ec779b8eSAndroid Build Coastguard Worker 
239*ec779b8eSAndroid Build Coastguard Worker         auto it = mObserverInfoMap.find((uintptr_t)binder.get());
240*ec779b8eSAndroid Build Coastguard Worker         if (it == mObserverInfoMap.end()) {
241*ec779b8eSAndroid Build Coastguard Worker             return Status::fromServiceSpecificError(NAME_NOT_FOUND);
242*ec779b8eSAndroid Build Coastguard Worker         }
243*ec779b8eSAndroid Build Coastguard Worker 
244*ec779b8eSAndroid Build Coastguard Worker         // Remove observer from observable->subscribers map.
245*ec779b8eSAndroid Build Coastguard Worker         for (auto &filter : it->second.filters) {
246*ec779b8eSAndroid Build Coastguard Worker             for (auto &event : sEvents) {
247*ec779b8eSAndroid Build Coastguard Worker                 if (!((uint64_t)filter.eventFilter & (uint64_t)event)) {
248*ec779b8eSAndroid Build Coastguard Worker                     continue;
249*ec779b8eSAndroid Build Coastguard Worker                 }
250*ec779b8eSAndroid Build Coastguard Worker                 MediaObservableFilter key{filter.type, event};
251*ec779b8eSAndroid Build Coastguard Worker                 mObservableToSubscribersMap[key].erase((uintptr_t)binder.get());
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker                 //Remove the entry if there's no more subscribers.
254*ec779b8eSAndroid Build Coastguard Worker                 if (mObservableToSubscribersMap[key].empty()) {
255*ec779b8eSAndroid Build Coastguard Worker                     mObservableToSubscribersMap.erase(key);
256*ec779b8eSAndroid Build Coastguard Worker                 }
257*ec779b8eSAndroid Build Coastguard Worker             }
258*ec779b8eSAndroid Build Coastguard Worker         }
259*ec779b8eSAndroid Build Coastguard Worker 
260*ec779b8eSAndroid Build Coastguard Worker         // Remove observer info.
261*ec779b8eSAndroid Build Coastguard Worker         mObserverInfoMap.erase(it);
262*ec779b8eSAndroid Build Coastguard Worker     }
263*ec779b8eSAndroid Build Coastguard Worker 
264*ec779b8eSAndroid Build Coastguard Worker     // Unlink and remove death binder.
265*ec779b8eSAndroid Build Coastguard Worker     uintptr_t cookie = (uintptr_t)binder.get();
266*ec779b8eSAndroid Build Coastguard Worker     AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(),
267*ec779b8eSAndroid Build Coastguard Worker             reinterpret_cast<void*>(cookie));
268*ec779b8eSAndroid Build Coastguard Worker 
269*ec779b8eSAndroid Build Coastguard Worker     {
270*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{sDeathRecipientLock};
271*ec779b8eSAndroid Build Coastguard Worker         sDeathRecipientMap.erase(cookie);
272*ec779b8eSAndroid Build Coastguard Worker     }
273*ec779b8eSAndroid Build Coastguard Worker 
274*ec779b8eSAndroid Build Coastguard Worker     return Status::ok();
275*ec779b8eSAndroid Build Coastguard Worker }
276*ec779b8eSAndroid Build Coastguard Worker 
notifyObservers(MediaObservableEvent event,int uid,int pid,const ResourceList & resources)277*ec779b8eSAndroid Build Coastguard Worker void ResourceObserverService::notifyObservers(
278*ec779b8eSAndroid Build Coastguard Worker         MediaObservableEvent event, int uid, int pid, const ResourceList &resources) {
279*ec779b8eSAndroid Build Coastguard Worker     struct CalleeInfo {
280*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<IResourceObserver> observer;
281*ec779b8eSAndroid Build Coastguard Worker         std::vector<MediaObservableParcel> monitors;
282*ec779b8eSAndroid Build Coastguard Worker     };
283*ec779b8eSAndroid Build Coastguard Worker     // Build a consolidated list of observers to call with their respective observables.
284*ec779b8eSAndroid Build Coastguard Worker     std::map<uintptr_t, CalleeInfo> calleeList;
285*ec779b8eSAndroid Build Coastguard Worker 
286*ec779b8eSAndroid Build Coastguard Worker     {
287*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{mObserverLock};
288*ec779b8eSAndroid Build Coastguard Worker 
289*ec779b8eSAndroid Build Coastguard Worker         for (const MediaResourceParcel& res : resources.getResources()) {
290*ec779b8eSAndroid Build Coastguard Worker             // Skip if this resource doesn't map to any observable type.
291*ec779b8eSAndroid Build Coastguard Worker             MediaObservableType observableType = getObservableType(res);
292*ec779b8eSAndroid Build Coastguard Worker             if (observableType == MediaObservableType::kInvalid) {
293*ec779b8eSAndroid Build Coastguard Worker                 continue;
294*ec779b8eSAndroid Build Coastguard Worker             }
295*ec779b8eSAndroid Build Coastguard Worker             MediaObservableFilter key{observableType, event};
296*ec779b8eSAndroid Build Coastguard Worker             // Skip if no one subscribed to this observable.
297*ec779b8eSAndroid Build Coastguard Worker             auto observableIt = mObservableToSubscribersMap.find(key);
298*ec779b8eSAndroid Build Coastguard Worker             if (observableIt == mObservableToSubscribersMap.end()) {
299*ec779b8eSAndroid Build Coastguard Worker                 continue;
300*ec779b8eSAndroid Build Coastguard Worker             }
301*ec779b8eSAndroid Build Coastguard Worker             // Loop through all subsribers.
302*ec779b8eSAndroid Build Coastguard Worker             for (auto &subscriber : observableIt->second) {
303*ec779b8eSAndroid Build Coastguard Worker                 auto calleeIt = calleeList.find(subscriber.first);
304*ec779b8eSAndroid Build Coastguard Worker                 if (calleeIt == calleeList.end()) {
305*ec779b8eSAndroid Build Coastguard Worker                     calleeList.emplace(subscriber.first, CalleeInfo{
306*ec779b8eSAndroid Build Coastguard Worker                         subscriber.second, {{observableType, res.value}}});
307*ec779b8eSAndroid Build Coastguard Worker                 } else {
308*ec779b8eSAndroid Build Coastguard Worker                     calleeIt->second.monitors.push_back({observableType, res.value});
309*ec779b8eSAndroid Build Coastguard Worker                 }
310*ec779b8eSAndroid Build Coastguard Worker             }
311*ec779b8eSAndroid Build Coastguard Worker         }
312*ec779b8eSAndroid Build Coastguard Worker     }
313*ec779b8eSAndroid Build Coastguard Worker 
314*ec779b8eSAndroid Build Coastguard Worker     // Finally call the observers about the status change.
315*ec779b8eSAndroid Build Coastguard Worker     for (auto &calleeInfo : calleeList) {
316*ec779b8eSAndroid Build Coastguard Worker         calleeInfo.second.observer->onStatusChanged(
317*ec779b8eSAndroid Build Coastguard Worker                 event, uid, pid, calleeInfo.second.monitors);
318*ec779b8eSAndroid Build Coastguard Worker     }
319*ec779b8eSAndroid Build Coastguard Worker }
320*ec779b8eSAndroid Build Coastguard Worker 
onResourceAdded(int uid,int pid,const ResourceList & resources)321*ec779b8eSAndroid Build Coastguard Worker void ResourceObserverService::onResourceAdded(
322*ec779b8eSAndroid Build Coastguard Worker         int uid, int pid, const ResourceList &resources) {
323*ec779b8eSAndroid Build Coastguard Worker     notifyObservers(MediaObservableEvent::kBusy, uid, pid, resources);
324*ec779b8eSAndroid Build Coastguard Worker }
325*ec779b8eSAndroid Build Coastguard Worker 
onResourceRemoved(int uid,int pid,const ResourceList & resources)326*ec779b8eSAndroid Build Coastguard Worker void ResourceObserverService::onResourceRemoved(
327*ec779b8eSAndroid Build Coastguard Worker         int uid, int pid, const ResourceList &resources) {
328*ec779b8eSAndroid Build Coastguard Worker     notifyObservers(MediaObservableEvent::kIdle, uid, pid, resources);
329*ec779b8eSAndroid Build Coastguard Worker }
330*ec779b8eSAndroid Build Coastguard Worker 
331*ec779b8eSAndroid Build Coastguard Worker } // namespace android
332