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