xref: /aosp_15_r20/system/hwservicemanager/ServiceManager.cpp (revision ee3b7b6295061e544d3520b965ea91a90424af41)
1*ee3b7b62SAndroid Build Coastguard Worker /*
2*ee3b7b62SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*ee3b7b62SAndroid Build Coastguard Worker  *
4*ee3b7b62SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ee3b7b62SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ee3b7b62SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ee3b7b62SAndroid Build Coastguard Worker  *
8*ee3b7b62SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ee3b7b62SAndroid Build Coastguard Worker  *
10*ee3b7b62SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ee3b7b62SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ee3b7b62SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ee3b7b62SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ee3b7b62SAndroid Build Coastguard Worker  * limitations under the License.
15*ee3b7b62SAndroid Build Coastguard Worker  */
16*ee3b7b62SAndroid Build Coastguard Worker 
17*ee3b7b62SAndroid Build Coastguard Worker #define LOG_TAG "hwservicemanager"
18*ee3b7b62SAndroid Build Coastguard Worker 
19*ee3b7b62SAndroid Build Coastguard Worker #include "ServiceManager.h"
20*ee3b7b62SAndroid Build Coastguard Worker #include "Vintf.h"
21*ee3b7b62SAndroid Build Coastguard Worker 
22*ee3b7b62SAndroid Build Coastguard Worker #include <android-base/logging.h>
23*ee3b7b62SAndroid Build Coastguard Worker #include <android-base/properties.h>
24*ee3b7b62SAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
25*ee3b7b62SAndroid Build Coastguard Worker #include <hidl/HidlSupport.h>
26*ee3b7b62SAndroid Build Coastguard Worker #include <hidl/HidlTransportSupport.h>
27*ee3b7b62SAndroid Build Coastguard Worker #include <regex>
28*ee3b7b62SAndroid Build Coastguard Worker #include <sstream>
29*ee3b7b62SAndroid Build Coastguard Worker #include <thread>
30*ee3b7b62SAndroid Build Coastguard Worker 
31*ee3b7b62SAndroid Build Coastguard Worker using android::hardware::IPCThreadState;
32*ee3b7b62SAndroid Build Coastguard Worker using ::android::hardware::interfacesEqual;
33*ee3b7b62SAndroid Build Coastguard Worker 
34*ee3b7b62SAndroid Build Coastguard Worker namespace android {
35*ee3b7b62SAndroid Build Coastguard Worker namespace hidl {
36*ee3b7b62SAndroid Build Coastguard Worker namespace manager {
37*ee3b7b62SAndroid Build Coastguard Worker namespace implementation {
38*ee3b7b62SAndroid Build Coastguard Worker 
getBinderCallingContext()39*ee3b7b62SAndroid Build Coastguard Worker AccessControl::CallingContext getBinderCallingContext() {
40*ee3b7b62SAndroid Build Coastguard Worker     const auto& self = IPCThreadState::self();
41*ee3b7b62SAndroid Build Coastguard Worker 
42*ee3b7b62SAndroid Build Coastguard Worker     pid_t pid = self->getCallingPid();
43*ee3b7b62SAndroid Build Coastguard Worker     const char* sid = self->getCallingSid();
44*ee3b7b62SAndroid Build Coastguard Worker 
45*ee3b7b62SAndroid Build Coastguard Worker     if (sid == nullptr) {
46*ee3b7b62SAndroid Build Coastguard Worker         if (pid != getpid()) {
47*ee3b7b62SAndroid Build Coastguard Worker             android_errorWriteLog(0x534e4554, "121035042");
48*ee3b7b62SAndroid Build Coastguard Worker         }
49*ee3b7b62SAndroid Build Coastguard Worker 
50*ee3b7b62SAndroid Build Coastguard Worker         return AccessControl::getCallingContext(pid);
51*ee3b7b62SAndroid Build Coastguard Worker     } else {
52*ee3b7b62SAndroid Build Coastguard Worker         return { true, sid, pid };
53*ee3b7b62SAndroid Build Coastguard Worker     }
54*ee3b7b62SAndroid Build Coastguard Worker }
55*ee3b7b62SAndroid Build Coastguard Worker 
56*ee3b7b62SAndroid Build Coastguard Worker static constexpr uint64_t kServiceDiedCookie = 0;
57*ee3b7b62SAndroid Build Coastguard Worker static constexpr uint64_t kPackageListenerDiedCookie = 1;
58*ee3b7b62SAndroid Build Coastguard Worker static constexpr uint64_t kServiceListenerDiedCookie = 2;
59*ee3b7b62SAndroid Build Coastguard Worker static constexpr uint64_t kClientCallbackDiedCookie = 3;
60*ee3b7b62SAndroid Build Coastguard Worker 
countExistingService() const61*ee3b7b62SAndroid Build Coastguard Worker size_t ServiceManager::countExistingService() const {
62*ee3b7b62SAndroid Build Coastguard Worker     size_t total = 0;
63*ee3b7b62SAndroid Build Coastguard Worker     forEachExistingService([&] (const HidlService *) {
64*ee3b7b62SAndroid Build Coastguard Worker         ++total;
65*ee3b7b62SAndroid Build Coastguard Worker         return true;  // continue
66*ee3b7b62SAndroid Build Coastguard Worker     });
67*ee3b7b62SAndroid Build Coastguard Worker     return total;
68*ee3b7b62SAndroid Build Coastguard Worker }
69*ee3b7b62SAndroid Build Coastguard Worker 
forEachExistingService(std::function<bool (const HidlService *)> f) const70*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::forEachExistingService(std::function<bool(const HidlService *)> f) const {
71*ee3b7b62SAndroid Build Coastguard Worker     forEachServiceEntry([&] (const HidlService *service) {
72*ee3b7b62SAndroid Build Coastguard Worker         if (service->getService() == nullptr) {
73*ee3b7b62SAndroid Build Coastguard Worker             return true;  // continue
74*ee3b7b62SAndroid Build Coastguard Worker         }
75*ee3b7b62SAndroid Build Coastguard Worker         return f(service);
76*ee3b7b62SAndroid Build Coastguard Worker     });
77*ee3b7b62SAndroid Build Coastguard Worker }
78*ee3b7b62SAndroid Build Coastguard Worker 
forEachExistingService(std::function<bool (HidlService *)> f)79*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::forEachExistingService(std::function<bool(HidlService *)> f) {
80*ee3b7b62SAndroid Build Coastguard Worker     forEachServiceEntry([&] (HidlService *service) {
81*ee3b7b62SAndroid Build Coastguard Worker         if (service->getService() == nullptr) {
82*ee3b7b62SAndroid Build Coastguard Worker             return true;  // continue
83*ee3b7b62SAndroid Build Coastguard Worker         }
84*ee3b7b62SAndroid Build Coastguard Worker         return f(service);
85*ee3b7b62SAndroid Build Coastguard Worker     });
86*ee3b7b62SAndroid Build Coastguard Worker }
87*ee3b7b62SAndroid Build Coastguard Worker 
forEachServiceEntry(std::function<bool (const HidlService *)> f) const88*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::forEachServiceEntry(std::function<bool(const HidlService *)> f) const {
89*ee3b7b62SAndroid Build Coastguard Worker     for (const auto& interfaceMapping : mServiceMap) {
90*ee3b7b62SAndroid Build Coastguard Worker         const auto& instanceMap = interfaceMapping.second.getInstanceMap();
91*ee3b7b62SAndroid Build Coastguard Worker 
92*ee3b7b62SAndroid Build Coastguard Worker         for (const auto& instanceMapping : instanceMap) {
93*ee3b7b62SAndroid Build Coastguard Worker             if (!f(instanceMapping.second.get())) {
94*ee3b7b62SAndroid Build Coastguard Worker                 return;
95*ee3b7b62SAndroid Build Coastguard Worker             }
96*ee3b7b62SAndroid Build Coastguard Worker         }
97*ee3b7b62SAndroid Build Coastguard Worker     }
98*ee3b7b62SAndroid Build Coastguard Worker }
99*ee3b7b62SAndroid Build Coastguard Worker 
forEachServiceEntry(std::function<bool (HidlService *)> f)100*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::forEachServiceEntry(std::function<bool(HidlService *)> f) {
101*ee3b7b62SAndroid Build Coastguard Worker     for (auto& interfaceMapping : mServiceMap) {
102*ee3b7b62SAndroid Build Coastguard Worker         auto& instanceMap = interfaceMapping.second.getInstanceMap();
103*ee3b7b62SAndroid Build Coastguard Worker 
104*ee3b7b62SAndroid Build Coastguard Worker         for (auto& instanceMapping : instanceMap) {
105*ee3b7b62SAndroid Build Coastguard Worker             if (!f(instanceMapping.second.get())) {
106*ee3b7b62SAndroid Build Coastguard Worker                 return;
107*ee3b7b62SAndroid Build Coastguard Worker             }
108*ee3b7b62SAndroid Build Coastguard Worker         }
109*ee3b7b62SAndroid Build Coastguard Worker     }
110*ee3b7b62SAndroid Build Coastguard Worker }
111*ee3b7b62SAndroid Build Coastguard Worker 
lookup(const std::string & fqName,const std::string & name)112*ee3b7b62SAndroid Build Coastguard Worker HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) {
113*ee3b7b62SAndroid Build Coastguard Worker     auto ifaceIt = mServiceMap.find(fqName);
114*ee3b7b62SAndroid Build Coastguard Worker     if (ifaceIt == mServiceMap.end()) {
115*ee3b7b62SAndroid Build Coastguard Worker         return nullptr;
116*ee3b7b62SAndroid Build Coastguard Worker     }
117*ee3b7b62SAndroid Build Coastguard Worker 
118*ee3b7b62SAndroid Build Coastguard Worker     PackageInterfaceMap &ifaceMap = ifaceIt->second;
119*ee3b7b62SAndroid Build Coastguard Worker 
120*ee3b7b62SAndroid Build Coastguard Worker     HidlService *hidlService = ifaceMap.lookup(name);
121*ee3b7b62SAndroid Build Coastguard Worker 
122*ee3b7b62SAndroid Build Coastguard Worker     return hidlService;
123*ee3b7b62SAndroid Build Coastguard Worker }
124*ee3b7b62SAndroid Build Coastguard Worker 
serviceDied(uint64_t cookie,const wp<IBase> & who)125*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
126*ee3b7b62SAndroid Build Coastguard Worker     bool serviceRemoved = false;
127*ee3b7b62SAndroid Build Coastguard Worker     switch (cookie) {
128*ee3b7b62SAndroid Build Coastguard Worker         case kServiceDiedCookie:
129*ee3b7b62SAndroid Build Coastguard Worker             serviceRemoved = removeService(who, nullptr /* restrictToInstanceName */);
130*ee3b7b62SAndroid Build Coastguard Worker             break;
131*ee3b7b62SAndroid Build Coastguard Worker         case kPackageListenerDiedCookie:
132*ee3b7b62SAndroid Build Coastguard Worker             serviceRemoved = removePackageListener(who);
133*ee3b7b62SAndroid Build Coastguard Worker             break;
134*ee3b7b62SAndroid Build Coastguard Worker         case kServiceListenerDiedCookie:
135*ee3b7b62SAndroid Build Coastguard Worker             serviceRemoved = removeServiceListener(who);
136*ee3b7b62SAndroid Build Coastguard Worker             break;
137*ee3b7b62SAndroid Build Coastguard Worker         case kClientCallbackDiedCookie: {
138*ee3b7b62SAndroid Build Coastguard Worker             sp<IBase> base = who.promote();
139*ee3b7b62SAndroid Build Coastguard Worker             IClientCallback* callback = static_cast<IClientCallback*>(base.get());
140*ee3b7b62SAndroid Build Coastguard Worker             serviceRemoved = unregisterClientCallback(nullptr /*service*/,
141*ee3b7b62SAndroid Build Coastguard Worker                                                       sp<IClientCallback>(callback));
142*ee3b7b62SAndroid Build Coastguard Worker         } break;
143*ee3b7b62SAndroid Build Coastguard Worker     }
144*ee3b7b62SAndroid Build Coastguard Worker 
145*ee3b7b62SAndroid Build Coastguard Worker     if (!serviceRemoved) {
146*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Received death notification but interface instance not removed. Cookie: "
147*ee3b7b62SAndroid Build Coastguard Worker                    << cookie << " Service pointer: " << who.promote().get();
148*ee3b7b62SAndroid Build Coastguard Worker     }
149*ee3b7b62SAndroid Build Coastguard Worker }
150*ee3b7b62SAndroid Build Coastguard Worker 
getInstanceMap()151*ee3b7b62SAndroid Build Coastguard Worker ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
152*ee3b7b62SAndroid Build Coastguard Worker     return mInstanceMap;
153*ee3b7b62SAndroid Build Coastguard Worker }
154*ee3b7b62SAndroid Build Coastguard Worker 
getInstanceMap() const155*ee3b7b62SAndroid Build Coastguard Worker const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
156*ee3b7b62SAndroid Build Coastguard Worker     return mInstanceMap;
157*ee3b7b62SAndroid Build Coastguard Worker }
158*ee3b7b62SAndroid Build Coastguard Worker 
lookup(const std::string & name) const159*ee3b7b62SAndroid Build Coastguard Worker const HidlService *ServiceManager::PackageInterfaceMap::lookup(
160*ee3b7b62SAndroid Build Coastguard Worker         const std::string &name) const {
161*ee3b7b62SAndroid Build Coastguard Worker     auto it = mInstanceMap.find(name);
162*ee3b7b62SAndroid Build Coastguard Worker 
163*ee3b7b62SAndroid Build Coastguard Worker     if (it == mInstanceMap.end()) {
164*ee3b7b62SAndroid Build Coastguard Worker         return nullptr;
165*ee3b7b62SAndroid Build Coastguard Worker     }
166*ee3b7b62SAndroid Build Coastguard Worker 
167*ee3b7b62SAndroid Build Coastguard Worker     return it->second.get();
168*ee3b7b62SAndroid Build Coastguard Worker }
169*ee3b7b62SAndroid Build Coastguard Worker 
lookup(const std::string & name)170*ee3b7b62SAndroid Build Coastguard Worker HidlService *ServiceManager::PackageInterfaceMap::lookup(
171*ee3b7b62SAndroid Build Coastguard Worker         const std::string &name) {
172*ee3b7b62SAndroid Build Coastguard Worker 
173*ee3b7b62SAndroid Build Coastguard Worker     return const_cast<HidlService*>(
174*ee3b7b62SAndroid Build Coastguard Worker         const_cast<const PackageInterfaceMap*>(this)->lookup(name));
175*ee3b7b62SAndroid Build Coastguard Worker }
176*ee3b7b62SAndroid Build Coastguard Worker 
insertService(std::unique_ptr<HidlService> && service)177*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::PackageInterfaceMap::insertService(
178*ee3b7b62SAndroid Build Coastguard Worker         std::unique_ptr<HidlService> &&service) {
179*ee3b7b62SAndroid Build Coastguard Worker     mInstanceMap.insert({service->getInstanceName(), std::move(service)});
180*ee3b7b62SAndroid Build Coastguard Worker }
181*ee3b7b62SAndroid Build Coastguard Worker 
sendPackageRegistrationNotification(const hidl_string & fqName,const hidl_string & instanceName)182*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification(
183*ee3b7b62SAndroid Build Coastguard Worker         const hidl_string &fqName,
184*ee3b7b62SAndroid Build Coastguard Worker         const hidl_string &instanceName) {
185*ee3b7b62SAndroid Build Coastguard Worker 
186*ee3b7b62SAndroid Build Coastguard Worker     for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
187*ee3b7b62SAndroid Build Coastguard Worker         auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */);
188*ee3b7b62SAndroid Build Coastguard Worker         if (ret.isOk()) {
189*ee3b7b62SAndroid Build Coastguard Worker             ++it;
190*ee3b7b62SAndroid Build Coastguard Worker         } else {
191*ee3b7b62SAndroid Build Coastguard Worker             LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName
192*ee3b7b62SAndroid Build Coastguard Worker                        << ": transport error.";
193*ee3b7b62SAndroid Build Coastguard Worker             it = mPackageListeners.erase(it);
194*ee3b7b62SAndroid Build Coastguard Worker         }
195*ee3b7b62SAndroid Build Coastguard Worker     }
196*ee3b7b62SAndroid Build Coastguard Worker }
197*ee3b7b62SAndroid Build Coastguard Worker 
addPackageListener(sp<IServiceNotification> listener)198*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) {
199*ee3b7b62SAndroid Build Coastguard Worker     for (const auto &instanceMapping : mInstanceMap) {
200*ee3b7b62SAndroid Build Coastguard Worker         const std::unique_ptr<HidlService> &service = instanceMapping.second;
201*ee3b7b62SAndroid Build Coastguard Worker 
202*ee3b7b62SAndroid Build Coastguard Worker         if (service->getService() == nullptr) {
203*ee3b7b62SAndroid Build Coastguard Worker             continue;
204*ee3b7b62SAndroid Build Coastguard Worker         }
205*ee3b7b62SAndroid Build Coastguard Worker 
206*ee3b7b62SAndroid Build Coastguard Worker         auto ret = listener->onRegistration(
207*ee3b7b62SAndroid Build Coastguard Worker             service->getInterfaceName(),
208*ee3b7b62SAndroid Build Coastguard Worker             service->getInstanceName(),
209*ee3b7b62SAndroid Build Coastguard Worker             true /* preexisting */);
210*ee3b7b62SAndroid Build Coastguard Worker         if (!ret.isOk()) {
211*ee3b7b62SAndroid Build Coastguard Worker             LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName()
212*ee3b7b62SAndroid Build Coastguard Worker                        << "/" << service->getInstanceName() << ": transport error "
213*ee3b7b62SAndroid Build Coastguard Worker                        << "when sending notification for already registered instance.";
214*ee3b7b62SAndroid Build Coastguard Worker             return;
215*ee3b7b62SAndroid Build Coastguard Worker         }
216*ee3b7b62SAndroid Build Coastguard Worker     }
217*ee3b7b62SAndroid Build Coastguard Worker     mPackageListeners.push_back(listener);
218*ee3b7b62SAndroid Build Coastguard Worker }
219*ee3b7b62SAndroid Build Coastguard Worker 
removePackageListener(const wp<IBase> & who)220*ee3b7b62SAndroid Build Coastguard Worker bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
221*ee3b7b62SAndroid Build Coastguard Worker     bool found = false;
222*ee3b7b62SAndroid Build Coastguard Worker 
223*ee3b7b62SAndroid Build Coastguard Worker     for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
224*ee3b7b62SAndroid Build Coastguard Worker         if (interfacesEqual(*it, who.promote())) {
225*ee3b7b62SAndroid Build Coastguard Worker             it = mPackageListeners.erase(it);
226*ee3b7b62SAndroid Build Coastguard Worker             found = true;
227*ee3b7b62SAndroid Build Coastguard Worker         } else {
228*ee3b7b62SAndroid Build Coastguard Worker             ++it;
229*ee3b7b62SAndroid Build Coastguard Worker         }
230*ee3b7b62SAndroid Build Coastguard Worker     }
231*ee3b7b62SAndroid Build Coastguard Worker 
232*ee3b7b62SAndroid Build Coastguard Worker     return found;
233*ee3b7b62SAndroid Build Coastguard Worker }
234*ee3b7b62SAndroid Build Coastguard Worker 
removeServiceListener(const wp<IBase> & who)235*ee3b7b62SAndroid Build Coastguard Worker bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
236*ee3b7b62SAndroid Build Coastguard Worker     bool found = false;
237*ee3b7b62SAndroid Build Coastguard Worker 
238*ee3b7b62SAndroid Build Coastguard Worker     for (auto &servicePair : getInstanceMap()) {
239*ee3b7b62SAndroid Build Coastguard Worker         const std::unique_ptr<HidlService> &service = servicePair.second;
240*ee3b7b62SAndroid Build Coastguard Worker         found |= service->removeListener(who);
241*ee3b7b62SAndroid Build Coastguard Worker     }
242*ee3b7b62SAndroid Build Coastguard Worker 
243*ee3b7b62SAndroid Build Coastguard Worker     return found;
244*ee3b7b62SAndroid Build Coastguard Worker }
245*ee3b7b62SAndroid Build Coastguard Worker 
tryStartService(const std::string & fqName,const std::string & name)246*ee3b7b62SAndroid Build Coastguard Worker static void tryStartService(const std::string& fqName, const std::string& name) {
247*ee3b7b62SAndroid Build Coastguard Worker     using ::android::base::SetProperty;
248*ee3b7b62SAndroid Build Coastguard Worker 
249*ee3b7b62SAndroid Build Coastguard Worker     // The "happy path" here is starting up a service that is configured as a
250*ee3b7b62SAndroid Build Coastguard Worker     // lazy HAL, but we aren't sure that is the case. If the service doesn't
251*ee3b7b62SAndroid Build Coastguard Worker     // have an 'interface' entry in its .rc file OR if the service is already
252*ee3b7b62SAndroid Build Coastguard Worker     // running, then this will be a no-op. So, for instance, if a service is
253*ee3b7b62SAndroid Build Coastguard Worker     // deadlocked during startup, you will see this message repeatedly.
254*ee3b7b62SAndroid Build Coastguard Worker     LOG(INFO) << "Since " << fqName << "/" << name
255*ee3b7b62SAndroid Build Coastguard Worker               << " is not registered, trying to start it as a lazy HAL (if it's not configured to "
256*ee3b7b62SAndroid Build Coastguard Worker                  "be a lazy HAL, it may be stuck starting or still starting).";
257*ee3b7b62SAndroid Build Coastguard Worker 
258*ee3b7b62SAndroid Build Coastguard Worker     std::thread([=] {
259*ee3b7b62SAndroid Build Coastguard Worker         if (!SetProperty("ctl.interface_start", fqName + "/" + name)) {
260*ee3b7b62SAndroid Build Coastguard Worker             LOG(INFO) << "Tried to start " << fqName << "/" << name
261*ee3b7b62SAndroid Build Coastguard Worker                       << " as a lazy service, but was unable to. Usually this happens when a "
262*ee3b7b62SAndroid Build Coastguard Worker                          "service is not installed, but if the service is intended to be used as a "
263*ee3b7b62SAndroid Build Coastguard Worker                          "lazy service, then it may be configured incorrectly.";
264*ee3b7b62SAndroid Build Coastguard Worker         }
265*ee3b7b62SAndroid Build Coastguard Worker     }).detach();
266*ee3b7b62SAndroid Build Coastguard Worker }
267*ee3b7b62SAndroid Build Coastguard Worker 
268*ee3b7b62SAndroid Build Coastguard Worker // Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
get(const hidl_string & hidlFqName,const hidl_string & hidlName)269*ee3b7b62SAndroid Build Coastguard Worker Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
270*ee3b7b62SAndroid Build Coastguard Worker                                       const hidl_string& hidlName) {
271*ee3b7b62SAndroid Build Coastguard Worker     const std::string fqName = hidlFqName;
272*ee3b7b62SAndroid Build Coastguard Worker     const std::string name = hidlName;
273*ee3b7b62SAndroid Build Coastguard Worker 
274*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
275*ee3b7b62SAndroid Build Coastguard Worker         return nullptr;
276*ee3b7b62SAndroid Build Coastguard Worker     }
277*ee3b7b62SAndroid Build Coastguard Worker 
278*ee3b7b62SAndroid Build Coastguard Worker     HidlService* hidlService = lookup(fqName, name);
279*ee3b7b62SAndroid Build Coastguard Worker     if (hidlService == nullptr) {
280*ee3b7b62SAndroid Build Coastguard Worker         tryStartService(fqName, name);
281*ee3b7b62SAndroid Build Coastguard Worker         return nullptr;
282*ee3b7b62SAndroid Build Coastguard Worker     }
283*ee3b7b62SAndroid Build Coastguard Worker 
284*ee3b7b62SAndroid Build Coastguard Worker     sp<IBase> service = hidlService->getService();
285*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
286*ee3b7b62SAndroid Build Coastguard Worker         tryStartService(fqName, name);
287*ee3b7b62SAndroid Build Coastguard Worker         return nullptr;
288*ee3b7b62SAndroid Build Coastguard Worker     }
289*ee3b7b62SAndroid Build Coastguard Worker 
290*ee3b7b62SAndroid Build Coastguard Worker     // Let HidlService know that we handed out a client. If the client drops the service before the
291*ee3b7b62SAndroid Build Coastguard Worker     // next time handleClientCallbacks is called, it will still know that the service had been handed out.
292*ee3b7b62SAndroid Build Coastguard Worker     hidlService->guaranteeClient();
293*ee3b7b62SAndroid Build Coastguard Worker     forEachExistingService([&] (HidlService *otherService) {
294*ee3b7b62SAndroid Build Coastguard Worker         if (otherService != hidlService && interfacesEqual(service, otherService->getService())) {
295*ee3b7b62SAndroid Build Coastguard Worker             otherService->guaranteeClient();
296*ee3b7b62SAndroid Build Coastguard Worker         }
297*ee3b7b62SAndroid Build Coastguard Worker         return true;
298*ee3b7b62SAndroid Build Coastguard Worker     });
299*ee3b7b62SAndroid Build Coastguard Worker 
300*ee3b7b62SAndroid Build Coastguard Worker     // This is executed immediately after the binder driver confirms the transaction. The driver
301*ee3b7b62SAndroid Build Coastguard Worker     // will update the appropriate data structures to reflect the fact that the client now has the
302*ee3b7b62SAndroid Build Coastguard Worker     // service this function is returning. Nothing else can update the HidlService at the same
303*ee3b7b62SAndroid Build Coastguard Worker     // time. This will run before anything else can modify the HidlService which is owned by this
304*ee3b7b62SAndroid Build Coastguard Worker     // object, so it will be in the same state that it was when this function returns.
305*ee3b7b62SAndroid Build Coastguard Worker     hardware::addPostCommandTask([hidlService] {
306*ee3b7b62SAndroid Build Coastguard Worker         hidlService->handleClientCallbacks(false /* isCalledOnInterval */, 1 /*knownClientCount*/);
307*ee3b7b62SAndroid Build Coastguard Worker     });
308*ee3b7b62SAndroid Build Coastguard Worker 
309*ee3b7b62SAndroid Build Coastguard Worker     return service;
310*ee3b7b62SAndroid Build Coastguard Worker }
311*ee3b7b62SAndroid Build Coastguard Worker 
add(const hidl_string & name,const sp<IBase> & service)312*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
313*ee3b7b62SAndroid Build Coastguard Worker     bool addSuccess = false;
314*ee3b7b62SAndroid Build Coastguard Worker 
315*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
316*ee3b7b62SAndroid Build Coastguard Worker         return false;
317*ee3b7b62SAndroid Build Coastguard Worker     }
318*ee3b7b62SAndroid Build Coastguard Worker 
319*ee3b7b62SAndroid Build Coastguard Worker     auto pidcon = getBinderCallingContext();
320*ee3b7b62SAndroid Build Coastguard Worker 
321*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canAdd(IBase::descriptor, pidcon)) {
322*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Missing permissions to add IBase";
323*ee3b7b62SAndroid Build Coastguard Worker         return false;
324*ee3b7b62SAndroid Build Coastguard Worker     }
325*ee3b7b62SAndroid Build Coastguard Worker 
326*ee3b7b62SAndroid Build Coastguard Worker     auto ret = service->interfaceChain([&](const auto &interfaceChain) {
327*ee3b7b62SAndroid Build Coastguard Worker         addSuccess = addImpl(name, service, interfaceChain, pidcon);
328*ee3b7b62SAndroid Build Coastguard Worker     });
329*ee3b7b62SAndroid Build Coastguard Worker 
330*ee3b7b62SAndroid Build Coastguard Worker     if (!ret.isOk()) {
331*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Failed to retrieve interface chain: " << ret.description();
332*ee3b7b62SAndroid Build Coastguard Worker         return false;
333*ee3b7b62SAndroid Build Coastguard Worker     }
334*ee3b7b62SAndroid Build Coastguard Worker 
335*ee3b7b62SAndroid Build Coastguard Worker     return addSuccess;
336*ee3b7b62SAndroid Build Coastguard Worker }
337*ee3b7b62SAndroid Build Coastguard Worker 
addImpl(const std::string & name,const sp<IBase> & service,const hidl_vec<hidl_string> & interfaceChain,const AccessControl::CallingContext & callingContext)338*ee3b7b62SAndroid Build Coastguard Worker bool ServiceManager::addImpl(const std::string& name,
339*ee3b7b62SAndroid Build Coastguard Worker                              const sp<IBase>& service,
340*ee3b7b62SAndroid Build Coastguard Worker                              const hidl_vec<hidl_string>& interfaceChain,
341*ee3b7b62SAndroid Build Coastguard Worker                              const AccessControl::CallingContext& callingContext) {
342*ee3b7b62SAndroid Build Coastguard Worker     if (interfaceChain.size() == 0) {
343*ee3b7b62SAndroid Build Coastguard Worker         LOG(WARNING) << "Empty interface chain for " << name;
344*ee3b7b62SAndroid Build Coastguard Worker         return false;
345*ee3b7b62SAndroid Build Coastguard Worker     }
346*ee3b7b62SAndroid Build Coastguard Worker 
347*ee3b7b62SAndroid Build Coastguard Worker     // First, verify you're allowed to add() the whole interface hierarchy
348*ee3b7b62SAndroid Build Coastguard Worker     for(size_t i = 0; i < interfaceChain.size(); i++) {
349*ee3b7b62SAndroid Build Coastguard Worker         const std::string fqName = interfaceChain[i];
350*ee3b7b62SAndroid Build Coastguard Worker 
351*ee3b7b62SAndroid Build Coastguard Worker         if (!mAcl.canAdd(fqName, callingContext)) {
352*ee3b7b62SAndroid Build Coastguard Worker             return false;
353*ee3b7b62SAndroid Build Coastguard Worker         }
354*ee3b7b62SAndroid Build Coastguard Worker     }
355*ee3b7b62SAndroid Build Coastguard Worker 
356*ee3b7b62SAndroid Build Coastguard Worker     const std::string childFqName = interfaceChain[0];
357*ee3b7b62SAndroid Build Coastguard Worker 
358*ee3b7b62SAndroid Build Coastguard Worker     // Detect duplicate registration
359*ee3b7b62SAndroid Build Coastguard Worker     if (interfaceChain.size() > 1) {
360*ee3b7b62SAndroid Build Coastguard Worker         // second to last entry should be the highest base class other than IBase.
361*ee3b7b62SAndroid Build Coastguard Worker         const std::string baseFqName = interfaceChain[interfaceChain.size() - 2];
362*ee3b7b62SAndroid Build Coastguard Worker         const HidlService *hidlService = lookup(baseFqName, name);
363*ee3b7b62SAndroid Build Coastguard Worker         if (hidlService != nullptr && hidlService->getService() != nullptr) {
364*ee3b7b62SAndroid Build Coastguard Worker             // This shouldn't occur during normal operation. Here are some cases where
365*ee3b7b62SAndroid Build Coastguard Worker             // it might get hit:
366*ee3b7b62SAndroid Build Coastguard Worker             // - bad configuration (service installed on device multiple times)
367*ee3b7b62SAndroid Build Coastguard Worker             // - race between death notification and a new service being registered
368*ee3b7b62SAndroid Build Coastguard Worker             //     (previous logs should indicate a separate problem)
369*ee3b7b62SAndroid Build Coastguard Worker             pid_t newServicePid = IPCThreadState::self()->getCallingPid();
370*ee3b7b62SAndroid Build Coastguard Worker             pid_t oldServicePid = hidlService->getDebugPid();
371*ee3b7b62SAndroid Build Coastguard Worker             LOG(WARNING) << "Detected instance of " << childFqName << " (pid: " << newServicePid
372*ee3b7b62SAndroid Build Coastguard Worker                     << ") registering over instance of or with base of " << baseFqName << " (pid: "
373*ee3b7b62SAndroid Build Coastguard Worker                     << oldServicePid << ").";
374*ee3b7b62SAndroid Build Coastguard Worker         }
375*ee3b7b62SAndroid Build Coastguard Worker     }
376*ee3b7b62SAndroid Build Coastguard Worker 
377*ee3b7b62SAndroid Build Coastguard Worker     // Unregister superclass if subclass is registered over it
378*ee3b7b62SAndroid Build Coastguard Worker     {
379*ee3b7b62SAndroid Build Coastguard Worker         // For IBar extends IFoo if IFoo/default is being registered, remove
380*ee3b7b62SAndroid Build Coastguard Worker         // IBar/default. This makes sure the following two things are equivalent
381*ee3b7b62SAndroid Build Coastguard Worker         // 1). IBar::castFrom(IFoo::getService(X))
382*ee3b7b62SAndroid Build Coastguard Worker         // 2). IBar::getService(X)
383*ee3b7b62SAndroid Build Coastguard Worker         // assuming that IBar is declared in the device manifest and there
384*ee3b7b62SAndroid Build Coastguard Worker         // is also not an IBaz extends IFoo and there is no race.
385*ee3b7b62SAndroid Build Coastguard Worker         const HidlService *hidlService = lookup(childFqName, name);
386*ee3b7b62SAndroid Build Coastguard Worker         if (hidlService != nullptr) {
387*ee3b7b62SAndroid Build Coastguard Worker             const sp<IBase> remove = hidlService->getService();
388*ee3b7b62SAndroid Build Coastguard Worker 
389*ee3b7b62SAndroid Build Coastguard Worker             if (remove != nullptr) {
390*ee3b7b62SAndroid Build Coastguard Worker                 const std::string instanceName = name;
391*ee3b7b62SAndroid Build Coastguard Worker                 removeService(remove, &instanceName /* restrictToInstanceName */);
392*ee3b7b62SAndroid Build Coastguard Worker             }
393*ee3b7b62SAndroid Build Coastguard Worker         }
394*ee3b7b62SAndroid Build Coastguard Worker     }
395*ee3b7b62SAndroid Build Coastguard Worker 
396*ee3b7b62SAndroid Build Coastguard Worker     // Detect missing manifest entries of superclass, when subclass in manifest.
397*ee3b7b62SAndroid Build Coastguard Worker     {
398*ee3b7b62SAndroid Build Coastguard Worker         // Ideally we could require all HALs registered with hwservicemanager to
399*ee3b7b62SAndroid Build Coastguard Worker         // be in the VINTF manifest. However, this would prevent tests from
400*ee3b7b62SAndroid Build Coastguard Worker         // running, and we would need another method of registering them (AIDL
401*ee3b7b62SAndroid Build Coastguard Worker         // servicemanager gets around this because only certain objects are
402*ee3b7b62SAndroid Build Coastguard Worker         // VINTF objects). So, for HIDL, we rely on VTS.
403*ee3b7b62SAndroid Build Coastguard Worker         //
404*ee3b7b62SAndroid Build Coastguard Worker         // When registering a HAL, in the client process, it checks to make sure
405*ee3b7b62SAndroid Build Coastguard Worker         // that the last (leaf) class in the chain is in the VINTF manifest and
406*ee3b7b62SAndroid Build Coastguard Worker         // fails. However, this fails to take into account parent classes. If
407*ee3b7b62SAndroid Build Coastguard Worker         // parent classes are associated with certain VTS tests, then those VTS
408*ee3b7b62SAndroid Build Coastguard Worker         // tests will not run until vts_treble_vintf_vendor_test fails and the
409*ee3b7b62SAndroid Build Coastguard Worker         // failures are fixed (namely adding this into a manifest).
410*ee3b7b62SAndroid Build Coastguard Worker         //
411*ee3b7b62SAndroid Build Coastguard Worker         // So, here we make sure that if something is in the manifest, all of
412*ee3b7b62SAndroid Build Coastguard Worker         // its parent classes are.
413*ee3b7b62SAndroid Build Coastguard Worker         using ::android::hardware::getTransport;
414*ee3b7b62SAndroid Build Coastguard Worker         if (vintf::Transport::EMPTY != getTransport(childFqName, name)) {
415*ee3b7b62SAndroid Build Coastguard Worker             bool parentsInManifest = true;
416*ee3b7b62SAndroid Build Coastguard Worker 
417*ee3b7b62SAndroid Build Coastguard Worker             // skip over latest, and check over all interfaces except the base
418*ee3b7b62SAndroid Build Coastguard Worker             // interface (android.hidl.base is never in the manifest)
419*ee3b7b62SAndroid Build Coastguard Worker             for (size_t i = 1; i + 1 < interfaceChain.size(); i++) {
420*ee3b7b62SAndroid Build Coastguard Worker                 if (vintf::Transport::EMPTY == getTransport(interfaceChain[i], name)) {
421*ee3b7b62SAndroid Build Coastguard Worker                     LOG(ERROR) << childFqName << "/" << name
422*ee3b7b62SAndroid Build Coastguard Worker                                << " is in the VINTF manifest, but its superclass "
423*ee3b7b62SAndroid Build Coastguard Worker                                << interfaceChain[i] << " is not. Refusing to register.";
424*ee3b7b62SAndroid Build Coastguard Worker                     parentsInManifest = false;
425*ee3b7b62SAndroid Build Coastguard Worker                 }
426*ee3b7b62SAndroid Build Coastguard Worker             }
427*ee3b7b62SAndroid Build Coastguard Worker             if (!parentsInManifest) {
428*ee3b7b62SAndroid Build Coastguard Worker                 return false;
429*ee3b7b62SAndroid Build Coastguard Worker             }
430*ee3b7b62SAndroid Build Coastguard Worker         }
431*ee3b7b62SAndroid Build Coastguard Worker     }
432*ee3b7b62SAndroid Build Coastguard Worker 
433*ee3b7b62SAndroid Build Coastguard Worker     for(size_t i = 0; i < interfaceChain.size(); i++) {
434*ee3b7b62SAndroid Build Coastguard Worker         const std::string fqName = interfaceChain[i];
435*ee3b7b62SAndroid Build Coastguard Worker 
436*ee3b7b62SAndroid Build Coastguard Worker         PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
437*ee3b7b62SAndroid Build Coastguard Worker         HidlService *hidlService = ifaceMap.lookup(name);
438*ee3b7b62SAndroid Build Coastguard Worker 
439*ee3b7b62SAndroid Build Coastguard Worker         if (hidlService == nullptr) {
440*ee3b7b62SAndroid Build Coastguard Worker             ifaceMap.insertService(
441*ee3b7b62SAndroid Build Coastguard Worker                 std::make_unique<HidlService>(fqName, name, service, callingContext.pid));
442*ee3b7b62SAndroid Build Coastguard Worker         } else {
443*ee3b7b62SAndroid Build Coastguard Worker             hidlService->setService(service, callingContext.pid);
444*ee3b7b62SAndroid Build Coastguard Worker         }
445*ee3b7b62SAndroid Build Coastguard Worker 
446*ee3b7b62SAndroid Build Coastguard Worker         ifaceMap.sendPackageRegistrationNotification(fqName, name);
447*ee3b7b62SAndroid Build Coastguard Worker     }
448*ee3b7b62SAndroid Build Coastguard Worker 
449*ee3b7b62SAndroid Build Coastguard Worker     bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
450*ee3b7b62SAndroid Build Coastguard Worker     if (!linkRet) {
451*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
452*ee3b7b62SAndroid Build Coastguard Worker     }
453*ee3b7b62SAndroid Build Coastguard Worker 
454*ee3b7b62SAndroid Build Coastguard Worker     return true;
455*ee3b7b62SAndroid Build Coastguard Worker }
456*ee3b7b62SAndroid Build Coastguard Worker 
getTransport(const hidl_string & fqName,const hidl_string & name)457*ee3b7b62SAndroid Build Coastguard Worker Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
458*ee3b7b62SAndroid Build Coastguard Worker                                                                const hidl_string& name) {
459*ee3b7b62SAndroid Build Coastguard Worker     using ::android::hardware::getTransport;
460*ee3b7b62SAndroid Build Coastguard Worker 
461*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
462*ee3b7b62SAndroid Build Coastguard Worker         return Transport::EMPTY;
463*ee3b7b62SAndroid Build Coastguard Worker     }
464*ee3b7b62SAndroid Build Coastguard Worker 
465*ee3b7b62SAndroid Build Coastguard Worker     switch (getTransport(fqName, name)) {
466*ee3b7b62SAndroid Build Coastguard Worker         case vintf::Transport::HWBINDER:
467*ee3b7b62SAndroid Build Coastguard Worker              return Transport::HWBINDER;
468*ee3b7b62SAndroid Build Coastguard Worker         case vintf::Transport::PASSTHROUGH:
469*ee3b7b62SAndroid Build Coastguard Worker              return Transport::PASSTHROUGH;
470*ee3b7b62SAndroid Build Coastguard Worker         case vintf::Transport::EMPTY:
471*ee3b7b62SAndroid Build Coastguard Worker         default:
472*ee3b7b62SAndroid Build Coastguard Worker              return Transport::EMPTY;
473*ee3b7b62SAndroid Build Coastguard Worker     }
474*ee3b7b62SAndroid Build Coastguard Worker }
475*ee3b7b62SAndroid Build Coastguard Worker 
list(list_cb _hidl_cb)476*ee3b7b62SAndroid Build Coastguard Worker Return<void> ServiceManager::list(list_cb _hidl_cb) {
477*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canList(getBinderCallingContext())) {
478*ee3b7b62SAndroid Build Coastguard Worker         _hidl_cb({});
479*ee3b7b62SAndroid Build Coastguard Worker         return Void();
480*ee3b7b62SAndroid Build Coastguard Worker     }
481*ee3b7b62SAndroid Build Coastguard Worker 
482*ee3b7b62SAndroid Build Coastguard Worker     hidl_vec<hidl_string> list;
483*ee3b7b62SAndroid Build Coastguard Worker 
484*ee3b7b62SAndroid Build Coastguard Worker     list.resize(countExistingService());
485*ee3b7b62SAndroid Build Coastguard Worker 
486*ee3b7b62SAndroid Build Coastguard Worker     size_t idx = 0;
487*ee3b7b62SAndroid Build Coastguard Worker     forEachExistingService([&] (const HidlService *service) {
488*ee3b7b62SAndroid Build Coastguard Worker         list[idx++] = service->string();
489*ee3b7b62SAndroid Build Coastguard Worker         return true;  // continue
490*ee3b7b62SAndroid Build Coastguard Worker     });
491*ee3b7b62SAndroid Build Coastguard Worker 
492*ee3b7b62SAndroid Build Coastguard Worker     _hidl_cb(list);
493*ee3b7b62SAndroid Build Coastguard Worker     return Void();
494*ee3b7b62SAndroid Build Coastguard Worker }
495*ee3b7b62SAndroid Build Coastguard Worker 
listByInterface(const hidl_string & fqName,listByInterface_cb _hidl_cb)496*ee3b7b62SAndroid Build Coastguard Worker Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
497*ee3b7b62SAndroid Build Coastguard Worker                                              listByInterface_cb _hidl_cb) {
498*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
499*ee3b7b62SAndroid Build Coastguard Worker         _hidl_cb({});
500*ee3b7b62SAndroid Build Coastguard Worker         return Void();
501*ee3b7b62SAndroid Build Coastguard Worker     }
502*ee3b7b62SAndroid Build Coastguard Worker 
503*ee3b7b62SAndroid Build Coastguard Worker     auto ifaceIt = mServiceMap.find(fqName);
504*ee3b7b62SAndroid Build Coastguard Worker     if (ifaceIt == mServiceMap.end()) {
505*ee3b7b62SAndroid Build Coastguard Worker         _hidl_cb(hidl_vec<hidl_string>());
506*ee3b7b62SAndroid Build Coastguard Worker         return Void();
507*ee3b7b62SAndroid Build Coastguard Worker     }
508*ee3b7b62SAndroid Build Coastguard Worker 
509*ee3b7b62SAndroid Build Coastguard Worker     const auto &instanceMap = ifaceIt->second.getInstanceMap();
510*ee3b7b62SAndroid Build Coastguard Worker 
511*ee3b7b62SAndroid Build Coastguard Worker     hidl_vec<hidl_string> list;
512*ee3b7b62SAndroid Build Coastguard Worker 
513*ee3b7b62SAndroid Build Coastguard Worker     size_t total = 0;
514*ee3b7b62SAndroid Build Coastguard Worker     for (const auto &serviceMapping : instanceMap) {
515*ee3b7b62SAndroid Build Coastguard Worker         const std::unique_ptr<HidlService> &service = serviceMapping.second;
516*ee3b7b62SAndroid Build Coastguard Worker         if (service->getService() == nullptr) continue;
517*ee3b7b62SAndroid Build Coastguard Worker 
518*ee3b7b62SAndroid Build Coastguard Worker         ++total;
519*ee3b7b62SAndroid Build Coastguard Worker     }
520*ee3b7b62SAndroid Build Coastguard Worker     list.resize(total);
521*ee3b7b62SAndroid Build Coastguard Worker 
522*ee3b7b62SAndroid Build Coastguard Worker     size_t idx = 0;
523*ee3b7b62SAndroid Build Coastguard Worker     for (const auto &serviceMapping : instanceMap) {
524*ee3b7b62SAndroid Build Coastguard Worker         const std::unique_ptr<HidlService> &service = serviceMapping.second;
525*ee3b7b62SAndroid Build Coastguard Worker         if (service->getService() == nullptr) continue;
526*ee3b7b62SAndroid Build Coastguard Worker 
527*ee3b7b62SAndroid Build Coastguard Worker         list[idx++] = service->getInstanceName();
528*ee3b7b62SAndroid Build Coastguard Worker     }
529*ee3b7b62SAndroid Build Coastguard Worker 
530*ee3b7b62SAndroid Build Coastguard Worker     _hidl_cb(list);
531*ee3b7b62SAndroid Build Coastguard Worker     return Void();
532*ee3b7b62SAndroid Build Coastguard Worker }
533*ee3b7b62SAndroid Build Coastguard Worker 
registerForNotifications(const hidl_string & fqName,const hidl_string & name,const sp<IServiceNotification> & callback)534*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
535*ee3b7b62SAndroid Build Coastguard Worker                                                       const hidl_string& name,
536*ee3b7b62SAndroid Build Coastguard Worker                                                       const sp<IServiceNotification>& callback) {
537*ee3b7b62SAndroid Build Coastguard Worker     if (callback == nullptr) {
538*ee3b7b62SAndroid Build Coastguard Worker         return false;
539*ee3b7b62SAndroid Build Coastguard Worker     }
540*ee3b7b62SAndroid Build Coastguard Worker 
541*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
542*ee3b7b62SAndroid Build Coastguard Worker         return false;
543*ee3b7b62SAndroid Build Coastguard Worker     }
544*ee3b7b62SAndroid Build Coastguard Worker 
545*ee3b7b62SAndroid Build Coastguard Worker     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
546*ee3b7b62SAndroid Build Coastguard Worker 
547*ee3b7b62SAndroid Build Coastguard Worker     if (name.empty()) {
548*ee3b7b62SAndroid Build Coastguard Worker         bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
549*ee3b7b62SAndroid Build Coastguard Worker         if (!ret) {
550*ee3b7b62SAndroid Build Coastguard Worker             LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
551*ee3b7b62SAndroid Build Coastguard Worker             return false;
552*ee3b7b62SAndroid Build Coastguard Worker         }
553*ee3b7b62SAndroid Build Coastguard Worker         ifaceMap.addPackageListener(callback);
554*ee3b7b62SAndroid Build Coastguard Worker         return true;
555*ee3b7b62SAndroid Build Coastguard Worker     }
556*ee3b7b62SAndroid Build Coastguard Worker 
557*ee3b7b62SAndroid Build Coastguard Worker     HidlService *service = ifaceMap.lookup(name);
558*ee3b7b62SAndroid Build Coastguard Worker 
559*ee3b7b62SAndroid Build Coastguard Worker     bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
560*ee3b7b62SAndroid Build Coastguard Worker     if (!ret) {
561*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
562*ee3b7b62SAndroid Build Coastguard Worker         return false;
563*ee3b7b62SAndroid Build Coastguard Worker     }
564*ee3b7b62SAndroid Build Coastguard Worker 
565*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
566*ee3b7b62SAndroid Build Coastguard Worker         auto adding = std::make_unique<HidlService>(fqName, name);
567*ee3b7b62SAndroid Build Coastguard Worker         adding->addListener(callback);
568*ee3b7b62SAndroid Build Coastguard Worker         ifaceMap.insertService(std::move(adding));
569*ee3b7b62SAndroid Build Coastguard Worker     } else {
570*ee3b7b62SAndroid Build Coastguard Worker         service->addListener(callback);
571*ee3b7b62SAndroid Build Coastguard Worker     }
572*ee3b7b62SAndroid Build Coastguard Worker 
573*ee3b7b62SAndroid Build Coastguard Worker     return true;
574*ee3b7b62SAndroid Build Coastguard Worker }
575*ee3b7b62SAndroid Build Coastguard Worker 
unregisterForNotifications(const hidl_string & fqName,const hidl_string & name,const sp<IServiceNotification> & callback)576*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
577*ee3b7b62SAndroid Build Coastguard Worker                                                         const hidl_string& name,
578*ee3b7b62SAndroid Build Coastguard Worker                                                         const sp<IServiceNotification>& callback) {
579*ee3b7b62SAndroid Build Coastguard Worker     if (callback == nullptr) {
580*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
581*ee3b7b62SAndroid Build Coastguard Worker         return false;
582*ee3b7b62SAndroid Build Coastguard Worker     }
583*ee3b7b62SAndroid Build Coastguard Worker 
584*ee3b7b62SAndroid Build Coastguard Worker     // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
585*ee3b7b62SAndroid Build Coastguard Worker     // then they already have access to it.
586*ee3b7b62SAndroid Build Coastguard Worker 
587*ee3b7b62SAndroid Build Coastguard Worker     if (fqName.empty()) {
588*ee3b7b62SAndroid Build Coastguard Worker         bool success = false;
589*ee3b7b62SAndroid Build Coastguard Worker         success |= removePackageListener(callback);
590*ee3b7b62SAndroid Build Coastguard Worker         success |= removeServiceListener(callback);
591*ee3b7b62SAndroid Build Coastguard Worker         return success;
592*ee3b7b62SAndroid Build Coastguard Worker     }
593*ee3b7b62SAndroid Build Coastguard Worker 
594*ee3b7b62SAndroid Build Coastguard Worker     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
595*ee3b7b62SAndroid Build Coastguard Worker 
596*ee3b7b62SAndroid Build Coastguard Worker     if (name.empty()) {
597*ee3b7b62SAndroid Build Coastguard Worker         bool success = false;
598*ee3b7b62SAndroid Build Coastguard Worker         success |= ifaceMap.removePackageListener(callback);
599*ee3b7b62SAndroid Build Coastguard Worker         success |= ifaceMap.removeServiceListener(callback);
600*ee3b7b62SAndroid Build Coastguard Worker         return success;
601*ee3b7b62SAndroid Build Coastguard Worker     }
602*ee3b7b62SAndroid Build Coastguard Worker 
603*ee3b7b62SAndroid Build Coastguard Worker     HidlService *service = ifaceMap.lookup(name);
604*ee3b7b62SAndroid Build Coastguard Worker 
605*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
606*ee3b7b62SAndroid Build Coastguard Worker         return false;
607*ee3b7b62SAndroid Build Coastguard Worker     }
608*ee3b7b62SAndroid Build Coastguard Worker 
609*ee3b7b62SAndroid Build Coastguard Worker     return service->removeListener(callback);
610*ee3b7b62SAndroid Build Coastguard Worker }
611*ee3b7b62SAndroid Build Coastguard Worker 
registerClientCallback(const hidl_string & hidlFqName,const hidl_string & hidlName,const sp<IBase> & server,const sp<IClientCallback> & cb)612*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::registerClientCallback(const hidl_string& hidlFqName,
613*ee3b7b62SAndroid Build Coastguard Worker                                                     const hidl_string& hidlName,
614*ee3b7b62SAndroid Build Coastguard Worker                                                     const sp<IBase>& server,
615*ee3b7b62SAndroid Build Coastguard Worker                                                     const sp<IClientCallback>& cb) {
616*ee3b7b62SAndroid Build Coastguard Worker     if (server == nullptr || cb == nullptr) return false;
617*ee3b7b62SAndroid Build Coastguard Worker 
618*ee3b7b62SAndroid Build Coastguard Worker     const std::string fqName = hidlFqName;
619*ee3b7b62SAndroid Build Coastguard Worker     const std::string name = hidlName;
620*ee3b7b62SAndroid Build Coastguard Worker 
621*ee3b7b62SAndroid Build Coastguard Worker     // only the server of the interface can register a client callback
622*ee3b7b62SAndroid Build Coastguard Worker     pid_t pid = IPCThreadState::self()->getCallingPid();
623*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canAdd(fqName, getBinderCallingContext())) {
624*ee3b7b62SAndroid Build Coastguard Worker         return false;
625*ee3b7b62SAndroid Build Coastguard Worker     }
626*ee3b7b62SAndroid Build Coastguard Worker 
627*ee3b7b62SAndroid Build Coastguard Worker     HidlService* registered = lookup(fqName, name);
628*ee3b7b62SAndroid Build Coastguard Worker 
629*ee3b7b62SAndroid Build Coastguard Worker     if (registered == nullptr) {
630*ee3b7b62SAndroid Build Coastguard Worker         return false;
631*ee3b7b62SAndroid Build Coastguard Worker     }
632*ee3b7b62SAndroid Build Coastguard Worker 
633*ee3b7b62SAndroid Build Coastguard Worker     // sanity
634*ee3b7b62SAndroid Build Coastguard Worker     if (registered->getDebugPid() != pid) {
635*ee3b7b62SAndroid Build Coastguard Worker         LOG(WARNING) << "Only a server can register for client callbacks (for " << fqName
636*ee3b7b62SAndroid Build Coastguard Worker             << "/" << name << ")";
637*ee3b7b62SAndroid Build Coastguard Worker         return false;
638*ee3b7b62SAndroid Build Coastguard Worker     }
639*ee3b7b62SAndroid Build Coastguard Worker 
640*ee3b7b62SAndroid Build Coastguard Worker     sp<IBase> service = registered->getService();
641*ee3b7b62SAndroid Build Coastguard Worker 
642*ee3b7b62SAndroid Build Coastguard Worker     if (!interfacesEqual(service, server)) {
643*ee3b7b62SAndroid Build Coastguard Worker         LOG(WARNING) << "Tried to register client callback for " << fqName << "/" << name
644*ee3b7b62SAndroid Build Coastguard Worker             << " but a different service is registered under this name.";
645*ee3b7b62SAndroid Build Coastguard Worker         return false;
646*ee3b7b62SAndroid Build Coastguard Worker     }
647*ee3b7b62SAndroid Build Coastguard Worker 
648*ee3b7b62SAndroid Build Coastguard Worker     bool linkRet = cb->linkToDeath(this, kClientCallbackDiedCookie).withDefault(false);
649*ee3b7b62SAndroid Build Coastguard Worker     if (!linkRet) {
650*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Could not link to death for registerClientCallback";
651*ee3b7b62SAndroid Build Coastguard Worker         return false;
652*ee3b7b62SAndroid Build Coastguard Worker     }
653*ee3b7b62SAndroid Build Coastguard Worker 
654*ee3b7b62SAndroid Build Coastguard Worker     // knownClientCount
655*ee3b7b62SAndroid Build Coastguard Worker     // - one from binder transaction (base here)
656*ee3b7b62SAndroid Build Coastguard Worker     // - one from hwservicemanager
657*ee3b7b62SAndroid Build Coastguard Worker     registered->addClientCallback(cb, 2 /*knownClientCount*/);
658*ee3b7b62SAndroid Build Coastguard Worker 
659*ee3b7b62SAndroid Build Coastguard Worker     return true;
660*ee3b7b62SAndroid Build Coastguard Worker }
661*ee3b7b62SAndroid Build Coastguard Worker 
unregisterClientCallback(const sp<IBase> & server,const sp<IClientCallback> & cb)662*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::unregisterClientCallback(const sp<IBase>& server,
663*ee3b7b62SAndroid Build Coastguard Worker                                                       const sp<IClientCallback>& cb) {
664*ee3b7b62SAndroid Build Coastguard Worker     if (cb == nullptr) return false;
665*ee3b7b62SAndroid Build Coastguard Worker 
666*ee3b7b62SAndroid Build Coastguard Worker     bool removed = false;
667*ee3b7b62SAndroid Build Coastguard Worker 
668*ee3b7b62SAndroid Build Coastguard Worker     forEachExistingService([&] (HidlService *service) {
669*ee3b7b62SAndroid Build Coastguard Worker         if (server == nullptr || interfacesEqual(service->getService(), server)) {
670*ee3b7b62SAndroid Build Coastguard Worker             removed |= service->removeClientCallback(cb);
671*ee3b7b62SAndroid Build Coastguard Worker         }
672*ee3b7b62SAndroid Build Coastguard Worker         return true;  // continue
673*ee3b7b62SAndroid Build Coastguard Worker     });
674*ee3b7b62SAndroid Build Coastguard Worker 
675*ee3b7b62SAndroid Build Coastguard Worker     return removed;
676*ee3b7b62SAndroid Build Coastguard Worker }
677*ee3b7b62SAndroid Build Coastguard Worker 
handleClientCallbacks()678*ee3b7b62SAndroid Build Coastguard Worker void ServiceManager::handleClientCallbacks() {
679*ee3b7b62SAndroid Build Coastguard Worker     forEachServiceEntry([&] (HidlService *service) {
680*ee3b7b62SAndroid Build Coastguard Worker         // hwservicemanager will hold one reference, so knownClientCount is 1.
681*ee3b7b62SAndroid Build Coastguard Worker         service->handleClientCallbacks(true /* isCalledOnInterval */, 1 /*knownClientCount*/);
682*ee3b7b62SAndroid Build Coastguard Worker         return true;  // continue
683*ee3b7b62SAndroid Build Coastguard Worker     });
684*ee3b7b62SAndroid Build Coastguard Worker }
685*ee3b7b62SAndroid Build Coastguard Worker 
addWithChain(const hidl_string & name,const sp<IBase> & service,const hidl_vec<hidl_string> & chain)686*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::addWithChain(const hidl_string& name,
687*ee3b7b62SAndroid Build Coastguard Worker                                           const sp<IBase>& service,
688*ee3b7b62SAndroid Build Coastguard Worker                                           const hidl_vec<hidl_string>& chain) {
689*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
690*ee3b7b62SAndroid Build Coastguard Worker         return false;
691*ee3b7b62SAndroid Build Coastguard Worker     }
692*ee3b7b62SAndroid Build Coastguard Worker 
693*ee3b7b62SAndroid Build Coastguard Worker     auto callingContext = getBinderCallingContext();
694*ee3b7b62SAndroid Build Coastguard Worker 
695*ee3b7b62SAndroid Build Coastguard Worker     return addImpl(name, service, chain, callingContext);
696*ee3b7b62SAndroid Build Coastguard Worker }
697*ee3b7b62SAndroid Build Coastguard Worker 
listManifestByInterface(const hidl_string & fqName,listManifestByInterface_cb _hidl_cb)698*ee3b7b62SAndroid Build Coastguard Worker Return<void> ServiceManager::listManifestByInterface(const hidl_string& fqName,
699*ee3b7b62SAndroid Build Coastguard Worker                                                      listManifestByInterface_cb _hidl_cb) {
700*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
701*ee3b7b62SAndroid Build Coastguard Worker         _hidl_cb({});
702*ee3b7b62SAndroid Build Coastguard Worker         return Void();
703*ee3b7b62SAndroid Build Coastguard Worker     }
704*ee3b7b62SAndroid Build Coastguard Worker 
705*ee3b7b62SAndroid Build Coastguard Worker     std::set<std::string> instances = getInstances(fqName);
706*ee3b7b62SAndroid Build Coastguard Worker     hidl_vec<hidl_string> ret(instances.begin(), instances.end());
707*ee3b7b62SAndroid Build Coastguard Worker 
708*ee3b7b62SAndroid Build Coastguard Worker     _hidl_cb(ret);
709*ee3b7b62SAndroid Build Coastguard Worker     return Void();
710*ee3b7b62SAndroid Build Coastguard Worker }
711*ee3b7b62SAndroid Build Coastguard Worker 
tryUnregister(const hidl_string & hidlFqName,const hidl_string & hidlName,const sp<IBase> & service)712*ee3b7b62SAndroid Build Coastguard Worker Return<bool> ServiceManager::tryUnregister(const hidl_string& hidlFqName,
713*ee3b7b62SAndroid Build Coastguard Worker                                            const hidl_string& hidlName,
714*ee3b7b62SAndroid Build Coastguard Worker                                            const sp<IBase>& service) {
715*ee3b7b62SAndroid Build Coastguard Worker     const std::string fqName = hidlFqName;
716*ee3b7b62SAndroid Build Coastguard Worker     const std::string name = hidlName;
717*ee3b7b62SAndroid Build Coastguard Worker 
718*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
719*ee3b7b62SAndroid Build Coastguard Worker         return false;
720*ee3b7b62SAndroid Build Coastguard Worker     }
721*ee3b7b62SAndroid Build Coastguard Worker 
722*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canAdd(fqName, getBinderCallingContext())) {
723*ee3b7b62SAndroid Build Coastguard Worker         return false;
724*ee3b7b62SAndroid Build Coastguard Worker     }
725*ee3b7b62SAndroid Build Coastguard Worker 
726*ee3b7b62SAndroid Build Coastguard Worker     HidlService* registered = lookup(fqName, name);
727*ee3b7b62SAndroid Build Coastguard Worker 
728*ee3b7b62SAndroid Build Coastguard Worker     // sanity
729*ee3b7b62SAndroid Build Coastguard Worker     pid_t pid = IPCThreadState::self()->getCallingPid();
730*ee3b7b62SAndroid Build Coastguard Worker     if (registered->getDebugPid() != pid) {
731*ee3b7b62SAndroid Build Coastguard Worker         LOG(WARNING) << "Only a server can unregister itself (for " << fqName
732*ee3b7b62SAndroid Build Coastguard Worker             << "/" << name << ")";
733*ee3b7b62SAndroid Build Coastguard Worker         return false;
734*ee3b7b62SAndroid Build Coastguard Worker     }
735*ee3b7b62SAndroid Build Coastguard Worker 
736*ee3b7b62SAndroid Build Coastguard Worker     sp<IBase> server = registered->getService();
737*ee3b7b62SAndroid Build Coastguard Worker 
738*ee3b7b62SAndroid Build Coastguard Worker     if (!interfacesEqual(service, server)) {
739*ee3b7b62SAndroid Build Coastguard Worker         LOG(WARNING) << "Tried to unregister for " << fqName << "/" << name
740*ee3b7b62SAndroid Build Coastguard Worker             << " but a different service is registered under this name.";
741*ee3b7b62SAndroid Build Coastguard Worker         return false;
742*ee3b7b62SAndroid Build Coastguard Worker     }
743*ee3b7b62SAndroid Build Coastguard Worker 
744*ee3b7b62SAndroid Build Coastguard Worker     // knownClientCount
745*ee3b7b62SAndroid Build Coastguard Worker     // - one from binder transaction (base here)
746*ee3b7b62SAndroid Build Coastguard Worker     // - one from hwservicemanager
747*ee3b7b62SAndroid Build Coastguard Worker     bool clients = registered->forceHandleClientCallbacks(false /*isCalledOnInterval*/, 2 /*knownClientCount*/);
748*ee3b7b62SAndroid Build Coastguard Worker 
749*ee3b7b62SAndroid Build Coastguard Worker     if (clients) {
750*ee3b7b62SAndroid Build Coastguard Worker         // client callbacks are either disabled or there are other clients
751*ee3b7b62SAndroid Build Coastguard Worker         LOG(INFO) << "Tried to unregister for " << fqName << "/" << name
752*ee3b7b62SAndroid Build Coastguard Worker             << " but there are clients: " << clients;
753*ee3b7b62SAndroid Build Coastguard Worker         return false;
754*ee3b7b62SAndroid Build Coastguard Worker     }
755*ee3b7b62SAndroid Build Coastguard Worker 
756*ee3b7b62SAndroid Build Coastguard Worker     // will remove entire parent hierarchy
757*ee3b7b62SAndroid Build Coastguard Worker     bool success = removeService(service, &name /*restrictToInstanceName*/);
758*ee3b7b62SAndroid Build Coastguard Worker 
759*ee3b7b62SAndroid Build Coastguard Worker     if (registered->getService() != nullptr) {
760*ee3b7b62SAndroid Build Coastguard Worker         LOG(ERROR) << "Bad state. Unregistration failed for " << fqName << "/" << name << ".";
761*ee3b7b62SAndroid Build Coastguard Worker         return false;
762*ee3b7b62SAndroid Build Coastguard Worker     }
763*ee3b7b62SAndroid Build Coastguard Worker 
764*ee3b7b62SAndroid Build Coastguard Worker     return success;
765*ee3b7b62SAndroid Build Coastguard Worker }
766*ee3b7b62SAndroid Build Coastguard Worker 
debugDump(debugDump_cb _cb)767*ee3b7b62SAndroid Build Coastguard Worker Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
768*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canList(getBinderCallingContext())) {
769*ee3b7b62SAndroid Build Coastguard Worker         _cb({});
770*ee3b7b62SAndroid Build Coastguard Worker         return Void();
771*ee3b7b62SAndroid Build Coastguard Worker     }
772*ee3b7b62SAndroid Build Coastguard Worker 
773*ee3b7b62SAndroid Build Coastguard Worker     std::vector<IServiceManager::InstanceDebugInfo> list;
774*ee3b7b62SAndroid Build Coastguard Worker     forEachServiceEntry([&] (const HidlService *service) {
775*ee3b7b62SAndroid Build Coastguard Worker         hidl_vec<int32_t> clientPids;
776*ee3b7b62SAndroid Build Coastguard Worker         clientPids.resize(service->getPassthroughClients().size());
777*ee3b7b62SAndroid Build Coastguard Worker 
778*ee3b7b62SAndroid Build Coastguard Worker         size_t i = 0;
779*ee3b7b62SAndroid Build Coastguard Worker         for (pid_t p : service->getPassthroughClients()) {
780*ee3b7b62SAndroid Build Coastguard Worker             clientPids[i++] = p;
781*ee3b7b62SAndroid Build Coastguard Worker         }
782*ee3b7b62SAndroid Build Coastguard Worker 
783*ee3b7b62SAndroid Build Coastguard Worker         list.push_back({
784*ee3b7b62SAndroid Build Coastguard Worker             .interfaceName = service->getInterfaceName(),
785*ee3b7b62SAndroid Build Coastguard Worker             .instanceName = service->getInstanceName(),
786*ee3b7b62SAndroid Build Coastguard Worker             .pid = service->getDebugPid(),
787*ee3b7b62SAndroid Build Coastguard Worker             .clientPids = clientPids,
788*ee3b7b62SAndroid Build Coastguard Worker             .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
789*ee3b7b62SAndroid Build Coastguard Worker         });
790*ee3b7b62SAndroid Build Coastguard Worker 
791*ee3b7b62SAndroid Build Coastguard Worker         return true;  // continue
792*ee3b7b62SAndroid Build Coastguard Worker     });
793*ee3b7b62SAndroid Build Coastguard Worker 
794*ee3b7b62SAndroid Build Coastguard Worker     _cb(list);
795*ee3b7b62SAndroid Build Coastguard Worker     return Void();
796*ee3b7b62SAndroid Build Coastguard Worker }
797*ee3b7b62SAndroid Build Coastguard Worker 
798*ee3b7b62SAndroid Build Coastguard Worker 
registerPassthroughClient(const hidl_string & fqName,const hidl_string & name)799*ee3b7b62SAndroid Build Coastguard Worker Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
800*ee3b7b62SAndroid Build Coastguard Worker         const hidl_string &name) {
801*ee3b7b62SAndroid Build Coastguard Worker     auto callingContext = getBinderCallingContext();
802*ee3b7b62SAndroid Build Coastguard Worker 
803*ee3b7b62SAndroid Build Coastguard Worker     if (!mAcl.canGet(fqName, callingContext)) {
804*ee3b7b62SAndroid Build Coastguard Worker         /* We guard this function with "get", because it's typically used in
805*ee3b7b62SAndroid Build Coastguard Worker          * the getService() path, albeit for a passthrough service in this
806*ee3b7b62SAndroid Build Coastguard Worker          * case
807*ee3b7b62SAndroid Build Coastguard Worker          */
808*ee3b7b62SAndroid Build Coastguard Worker         return Void();
809*ee3b7b62SAndroid Build Coastguard Worker     }
810*ee3b7b62SAndroid Build Coastguard Worker 
811*ee3b7b62SAndroid Build Coastguard Worker     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
812*ee3b7b62SAndroid Build Coastguard Worker 
813*ee3b7b62SAndroid Build Coastguard Worker     if (name.empty()) {
814*ee3b7b62SAndroid Build Coastguard Worker         LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
815*ee3b7b62SAndroid Build Coastguard Worker                      << fqName.c_str();
816*ee3b7b62SAndroid Build Coastguard Worker         return Void();
817*ee3b7b62SAndroid Build Coastguard Worker     }
818*ee3b7b62SAndroid Build Coastguard Worker 
819*ee3b7b62SAndroid Build Coastguard Worker     HidlService *service = ifaceMap.lookup(name);
820*ee3b7b62SAndroid Build Coastguard Worker 
821*ee3b7b62SAndroid Build Coastguard Worker     if (service == nullptr) {
822*ee3b7b62SAndroid Build Coastguard Worker         auto adding = std::make_unique<HidlService>(fqName, name);
823*ee3b7b62SAndroid Build Coastguard Worker         adding->registerPassthroughClient(callingContext.pid);
824*ee3b7b62SAndroid Build Coastguard Worker         ifaceMap.insertService(std::move(adding));
825*ee3b7b62SAndroid Build Coastguard Worker     } else {
826*ee3b7b62SAndroid Build Coastguard Worker         service->registerPassthroughClient(callingContext.pid);
827*ee3b7b62SAndroid Build Coastguard Worker     }
828*ee3b7b62SAndroid Build Coastguard Worker     return Void();
829*ee3b7b62SAndroid Build Coastguard Worker }
830*ee3b7b62SAndroid Build Coastguard Worker 
removeService(const wp<IBase> & who,const std::string * restrictToInstanceName)831*ee3b7b62SAndroid Build Coastguard Worker bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
832*ee3b7b62SAndroid Build Coastguard Worker     bool keepInstance = false;
833*ee3b7b62SAndroid Build Coastguard Worker     bool removed = false;
834*ee3b7b62SAndroid Build Coastguard Worker     for (auto &interfaceMapping : mServiceMap) {
835*ee3b7b62SAndroid Build Coastguard Worker         auto &instanceMap = interfaceMapping.second.getInstanceMap();
836*ee3b7b62SAndroid Build Coastguard Worker 
837*ee3b7b62SAndroid Build Coastguard Worker         for (auto &servicePair : instanceMap) {
838*ee3b7b62SAndroid Build Coastguard Worker             const std::string &instanceName = servicePair.first;
839*ee3b7b62SAndroid Build Coastguard Worker             const std::unique_ptr<HidlService> &service = servicePair.second;
840*ee3b7b62SAndroid Build Coastguard Worker 
841*ee3b7b62SAndroid Build Coastguard Worker             if (interfacesEqual(service->getService(), who.promote())) {
842*ee3b7b62SAndroid Build Coastguard Worker                 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
843*ee3b7b62SAndroid Build Coastguard Worker                     // We cannot remove all instances of this service, so we don't return that it
844*ee3b7b62SAndroid Build Coastguard Worker                     // has been entirely removed.
845*ee3b7b62SAndroid Build Coastguard Worker                     keepInstance = true;
846*ee3b7b62SAndroid Build Coastguard Worker                     continue;
847*ee3b7b62SAndroid Build Coastguard Worker                 }
848*ee3b7b62SAndroid Build Coastguard Worker 
849*ee3b7b62SAndroid Build Coastguard Worker                 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
850*ee3b7b62SAndroid Build Coastguard Worker                 removed = true;
851*ee3b7b62SAndroid Build Coastguard Worker             }
852*ee3b7b62SAndroid Build Coastguard Worker         }
853*ee3b7b62SAndroid Build Coastguard Worker     }
854*ee3b7b62SAndroid Build Coastguard Worker 
855*ee3b7b62SAndroid Build Coastguard Worker     return !keepInstance && removed;
856*ee3b7b62SAndroid Build Coastguard Worker }
857*ee3b7b62SAndroid Build Coastguard Worker 
removePackageListener(const wp<IBase> & who)858*ee3b7b62SAndroid Build Coastguard Worker bool ServiceManager::removePackageListener(const wp<IBase>& who) {
859*ee3b7b62SAndroid Build Coastguard Worker     bool found = false;
860*ee3b7b62SAndroid Build Coastguard Worker 
861*ee3b7b62SAndroid Build Coastguard Worker     for (auto &interfaceMapping : mServiceMap) {
862*ee3b7b62SAndroid Build Coastguard Worker         found |= interfaceMapping.second.removePackageListener(who);
863*ee3b7b62SAndroid Build Coastguard Worker     }
864*ee3b7b62SAndroid Build Coastguard Worker 
865*ee3b7b62SAndroid Build Coastguard Worker     return found;
866*ee3b7b62SAndroid Build Coastguard Worker }
867*ee3b7b62SAndroid Build Coastguard Worker 
removeServiceListener(const wp<IBase> & who)868*ee3b7b62SAndroid Build Coastguard Worker bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
869*ee3b7b62SAndroid Build Coastguard Worker     bool found = false;
870*ee3b7b62SAndroid Build Coastguard Worker     for (auto &interfaceMapping : mServiceMap) {
871*ee3b7b62SAndroid Build Coastguard Worker         auto &packageInterfaceMap = interfaceMapping.second;
872*ee3b7b62SAndroid Build Coastguard Worker 
873*ee3b7b62SAndroid Build Coastguard Worker         found |= packageInterfaceMap.removeServiceListener(who);
874*ee3b7b62SAndroid Build Coastguard Worker     }
875*ee3b7b62SAndroid Build Coastguard Worker     return found;
876*ee3b7b62SAndroid Build Coastguard Worker }
877*ee3b7b62SAndroid Build Coastguard Worker }  // namespace implementation
878*ee3b7b62SAndroid Build Coastguard Worker }  // namespace manager
879*ee3b7b62SAndroid Build Coastguard Worker }  // namespace hidl
880*ee3b7b62SAndroid Build Coastguard Worker }  // namespace android
881