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 
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 
61 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 
70 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 
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 
88 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 
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 
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 
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 
151 ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
152     return mInstanceMap;
153 }
154 
155 const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
156     return mInstanceMap;
157 }
158 
159 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 
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 
177 void ServiceManager::PackageInterfaceMap::insertService(
178         std::unique_ptr<HidlService> &&service) {
179     mInstanceMap.insert({service->getInstanceName(), std::move(service)});
180 }
181 
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 
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 
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 
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 
246 static void tryStartService(const std::string& fqName, const std::string& name) {
247     using ::android::base::SetProperty;
248 
249     // The "happy path" here is starting up a service that is configured as a
250     // lazy HAL, but we aren't sure that is the case. If the service doesn't
251     // have an 'interface' entry in its .rc file OR if the service is already
252     // running, then this will be a no-op. So, for instance, if a service is
253     // deadlocked during startup, you will see this message repeatedly.
254     LOG(INFO) << "Since " << fqName << "/" << name
255               << " is not registered, trying to start it as a lazy HAL.";
256 
257     std::thread([=] {
258         (void)SetProperty("ctl.interface_start", fqName + "/" + name);
259     }).detach();
260 }
261 
262 // Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
263 Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
264                                       const hidl_string& hidlName) {
265     const std::string fqName = hidlFqName;
266     const std::string name = hidlName;
267 
268     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
269         return nullptr;
270     }
271 
272     HidlService* hidlService = lookup(fqName, name);
273     if (hidlService == nullptr) {
274         tryStartService(fqName, name);
275         return nullptr;
276     }
277 
278     sp<IBase> service = hidlService->getService();
279     if (service == nullptr) {
280         tryStartService(fqName, name);
281         return nullptr;
282     }
283 
284     // Let HidlService know that we handed out a client. If the client drops the service before the
285     // next time handleClientCallbacks is called, it will still know that the service had been handed out.
286     hidlService->guaranteeClient();
287     forEachExistingService([&] (HidlService *otherService) {
288         if (otherService != hidlService && interfacesEqual(service, otherService->getService())) {
289             otherService->guaranteeClient();
290         }
291         return true;
292     });
293 
294     // This is executed immediately after the binder driver confirms the transaction. The driver
295     // will update the appropriate data structures to reflect the fact that the client now has the
296     // service this function is returning. Nothing else can update the HidlService at the same
297     // time. This will run before anything else can modify the HidlService which is owned by this
298     // object, so it will be in the same state that it was when this function returns.
299     hardware::addPostCommandTask([hidlService] {
300         hidlService->handleClientCallbacks(false /* isCalledOnInterval */, 1 /*knownClientCount*/);
301     });
302 
303     return service;
304 }
305 
306 Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
307     bool addSuccess = false;
308 
309     if (service == nullptr) {
310         return false;
311     }
312 
313     auto pidcon = getBinderCallingContext();
314 
315     if (!mAcl.canAdd(IBase::descriptor, pidcon)) {
316         LOG(ERROR) << "Missing permissions to add IBase";
317         return false;
318     }
319 
320     auto ret = service->interfaceChain([&](const auto &interfaceChain) {
321         addSuccess = addImpl(name, service, interfaceChain, pidcon);
322     });
323 
324     if (!ret.isOk()) {
325         LOG(ERROR) << "Failed to retrieve interface chain: " << ret.description();
326         return false;
327     }
328 
329     return addSuccess;
330 }
331 
332 bool ServiceManager::addImpl(const std::string& name,
333                              const sp<IBase>& service,
334                              const hidl_vec<hidl_string>& interfaceChain,
335                              const AccessControl::CallingContext& callingContext) {
336     if (interfaceChain.size() == 0) {
337         LOG(WARNING) << "Empty interface chain for " << name;
338         return false;
339     }
340 
341     // First, verify you're allowed to add() the whole interface hierarchy
342     for(size_t i = 0; i < interfaceChain.size(); i++) {
343         const std::string fqName = interfaceChain[i];
344 
345         if (!mAcl.canAdd(fqName, callingContext)) {
346             return false;
347         }
348     }
349 
350     // Detect duplicate registration
351     if (interfaceChain.size() > 1) {
352         // second to last entry should be the highest base class other than IBase.
353         const std::string baseFqName = interfaceChain[interfaceChain.size() - 2];
354         const HidlService *hidlService = lookup(baseFqName, name);
355         if (hidlService != nullptr && hidlService->getService() != nullptr) {
356             // This shouldn't occur during normal operation. Here are some cases where
357             // it might get hit:
358             // - bad configuration (service installed on device multiple times)
359             // - race between death notification and a new service being registered
360             //     (previous logs should indicate a separate problem)
361             const std::string childFqName = interfaceChain[0];
362             pid_t newServicePid = IPCThreadState::self()->getCallingPid();
363             pid_t oldServicePid = hidlService->getDebugPid();
364             LOG(WARNING) << "Detected instance of " << childFqName << " (pid: " << newServicePid
365                     << ") registering over instance of or with base of " << baseFqName << " (pid: "
366                     << oldServicePid << ").";
367         }
368     }
369 
370     // Unregister superclass if subclass is registered over it
371     {
372         // For IBar extends IFoo if IFoo/default is being registered, remove
373         // IBar/default. This makes sure the following two things are equivalent
374         // 1). IBar::castFrom(IFoo::getService(X))
375         // 2). IBar::getService(X)
376         // assuming that IBar is declared in the device manifest and there
377         // is also not an IBaz extends IFoo and there is no race.
378         const std::string childFqName = interfaceChain[0];
379         const HidlService *hidlService = lookup(childFqName, name);
380         if (hidlService != nullptr) {
381             const sp<IBase> remove = hidlService->getService();
382 
383             if (remove != nullptr) {
384                 const std::string instanceName = name;
385                 removeService(remove, &instanceName /* restrictToInstanceName */);
386             }
387         }
388     }
389 
390     for(size_t i = 0; i < interfaceChain.size(); i++) {
391         const std::string fqName = interfaceChain[i];
392 
393         PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
394         HidlService *hidlService = ifaceMap.lookup(name);
395 
396         if (hidlService == nullptr) {
397             ifaceMap.insertService(
398                 std::make_unique<HidlService>(fqName, name, service, callingContext.pid));
399         } else {
400             hidlService->setService(service, callingContext.pid);
401         }
402 
403         ifaceMap.sendPackageRegistrationNotification(fqName, name);
404     }
405 
406     bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
407     if (!linkRet) {
408         LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
409     }
410 
411     return true;
412 }
413 
414 Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
415                                                                const hidl_string& name) {
416     using ::android::hardware::getTransport;
417 
418     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
419         return Transport::EMPTY;
420     }
421 
422     switch (getTransport(fqName, name)) {
423         case vintf::Transport::HWBINDER:
424              return Transport::HWBINDER;
425         case vintf::Transport::PASSTHROUGH:
426              return Transport::PASSTHROUGH;
427         case vintf::Transport::EMPTY:
428         default:
429              return Transport::EMPTY;
430     }
431 }
432 
433 Return<void> ServiceManager::list(list_cb _hidl_cb) {
434     if (!mAcl.canList(getBinderCallingContext())) {
435         _hidl_cb({});
436         return Void();
437     }
438 
439     hidl_vec<hidl_string> list;
440 
441     list.resize(countExistingService());
442 
443     size_t idx = 0;
444     forEachExistingService([&] (const HidlService *service) {
445         list[idx++] = service->string();
446         return true;  // continue
447     });
448 
449     _hidl_cb(list);
450     return Void();
451 }
452 
453 Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
454                                              listByInterface_cb _hidl_cb) {
455     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
456         _hidl_cb({});
457         return Void();
458     }
459 
460     auto ifaceIt = mServiceMap.find(fqName);
461     if (ifaceIt == mServiceMap.end()) {
462         _hidl_cb(hidl_vec<hidl_string>());
463         return Void();
464     }
465 
466     const auto &instanceMap = ifaceIt->second.getInstanceMap();
467 
468     hidl_vec<hidl_string> list;
469 
470     size_t total = 0;
471     for (const auto &serviceMapping : instanceMap) {
472         const std::unique_ptr<HidlService> &service = serviceMapping.second;
473         if (service->getService() == nullptr) continue;
474 
475         ++total;
476     }
477     list.resize(total);
478 
479     size_t idx = 0;
480     for (const auto &serviceMapping : instanceMap) {
481         const std::unique_ptr<HidlService> &service = serviceMapping.second;
482         if (service->getService() == nullptr) continue;
483 
484         list[idx++] = service->getInstanceName();
485     }
486 
487     _hidl_cb(list);
488     return Void();
489 }
490 
491 Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
492                                                       const hidl_string& name,
493                                                       const sp<IServiceNotification>& callback) {
494     if (callback == nullptr) {
495         return false;
496     }
497 
498     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
499         return false;
500     }
501 
502     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
503 
504     if (name.empty()) {
505         bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
506         if (!ret) {
507             LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
508             return false;
509         }
510         ifaceMap.addPackageListener(callback);
511         return true;
512     }
513 
514     HidlService *service = ifaceMap.lookup(name);
515 
516     bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
517     if (!ret) {
518         LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
519         return false;
520     }
521 
522     if (service == nullptr) {
523         auto adding = std::make_unique<HidlService>(fqName, name);
524         adding->addListener(callback);
525         ifaceMap.insertService(std::move(adding));
526     } else {
527         service->addListener(callback);
528     }
529 
530     return true;
531 }
532 
533 Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
534                                                         const hidl_string& name,
535                                                         const sp<IServiceNotification>& callback) {
536     if (callback == nullptr) {
537         LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
538         return false;
539     }
540 
541     // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
542     // then they already have access to it.
543 
544     if (fqName.empty()) {
545         bool success = false;
546         success |= removePackageListener(callback);
547         success |= removeServiceListener(callback);
548         return success;
549     }
550 
551     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
552 
553     if (name.empty()) {
554         bool success = false;
555         success |= ifaceMap.removePackageListener(callback);
556         success |= ifaceMap.removeServiceListener(callback);
557         return success;
558     }
559 
560     HidlService *service = ifaceMap.lookup(name);
561 
562     if (service == nullptr) {
563         return false;
564     }
565 
566     return service->removeListener(callback);
567 }
568 
569 Return<bool> ServiceManager::registerClientCallback(const hidl_string& hidlFqName,
570                                                     const hidl_string& hidlName,
571                                                     const sp<IBase>& server,
572                                                     const sp<IClientCallback>& cb) {
573     if (server == nullptr || cb == nullptr) return false;
574 
575     const std::string fqName = hidlFqName;
576     const std::string name = hidlName;
577 
578     // only the server of the interface can register a client callback
579     pid_t pid = IPCThreadState::self()->getCallingPid();
580     if (!mAcl.canAdd(fqName, getBinderCallingContext())) {
581         return false;
582     }
583 
584     HidlService* registered = lookup(fqName, name);
585 
586     if (registered == nullptr) {
587         return false;
588     }
589 
590     // sanity
591     if (registered->getDebugPid() != pid) {
592         LOG(WARNING) << "Only a server can register for client callbacks (for " << fqName
593             << "/" << name << ")";
594         return false;
595     }
596 
597     sp<IBase> service = registered->getService();
598 
599     if (!interfacesEqual(service, server)) {
600         LOG(WARNING) << "Tried to register client callback for " << fqName << "/" << name
601             << " but a different service is registered under this name.";
602         return false;
603     }
604 
605     bool linkRet = cb->linkToDeath(this, kClientCallbackDiedCookie).withDefault(false);
606     if (!linkRet) {
607         LOG(ERROR) << "Could not link to death for registerClientCallback";
608         return false;
609     }
610 
611     // knownClientCount
612     // - one from binder transaction (base here)
613     // - one from hwservicemanager
614     registered->addClientCallback(cb, 2 /*knownClientCount*/);
615 
616     return true;
617 }
618 
619 Return<bool> ServiceManager::unregisterClientCallback(const sp<IBase>& server,
620                                                       const sp<IClientCallback>& cb) {
621     if (cb == nullptr) return false;
622 
623     bool removed = false;
624 
625     forEachExistingService([&] (HidlService *service) {
626         if (server == nullptr || interfacesEqual(service->getService(), server)) {
627             removed |= service->removeClientCallback(cb);
628         }
629         return true;  // continue
630     });
631 
632     return removed;
633 }
634 
635 void ServiceManager::handleClientCallbacks() {
636     forEachServiceEntry([&] (HidlService *service) {
637         // hwservicemanager will hold one reference, so knownClientCount is 1.
638         service->handleClientCallbacks(true /* isCalledOnInterval */, 1 /*knownClientCount*/);
639         return true;  // continue
640     });
641 }
642 
643 Return<bool> ServiceManager::addWithChain(const hidl_string& name,
644                                           const sp<IBase>& service,
645                                           const hidl_vec<hidl_string>& chain) {
646     if (service == nullptr) {
647         return false;
648     }
649 
650     auto callingContext = getBinderCallingContext();
651 
652     return addImpl(name, service, chain, callingContext);
653 }
654 
655 Return<void> ServiceManager::listManifestByInterface(const hidl_string& fqName,
656                                                      listManifestByInterface_cb _hidl_cb) {
657     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
658         _hidl_cb({});
659         return Void();
660     }
661 
662     std::set<std::string> instances = getInstances(fqName);
663     hidl_vec<hidl_string> ret(instances.begin(), instances.end());
664 
665     _hidl_cb(ret);
666     return Void();
667 }
668 
669 Return<bool> ServiceManager::tryUnregister(const hidl_string& hidlFqName,
670                                            const hidl_string& hidlName,
671                                            const sp<IBase>& service) {
672     const std::string fqName = hidlFqName;
673     const std::string name = hidlName;
674 
675     if (service == nullptr) {
676         return false;
677     }
678 
679     if (!mAcl.canAdd(fqName, getBinderCallingContext())) {
680         return false;
681     }
682 
683     HidlService* registered = lookup(fqName, name);
684 
685     // sanity
686     pid_t pid = IPCThreadState::self()->getCallingPid();
687     if (registered->getDebugPid() != pid) {
688         LOG(WARNING) << "Only a server can unregister itself (for " << fqName
689             << "/" << name << ")";
690         return false;
691     }
692 
693     sp<IBase> server = registered->getService();
694 
695     if (!interfacesEqual(service, server)) {
696         LOG(WARNING) << "Tried to unregister for " << fqName << "/" << name
697             << " but a different service is registered under this name.";
698         return false;
699     }
700 
701     // knownClientCount
702     // - one from binder transaction (base here)
703     // - one from hwservicemanager
704     bool clients = registered->forceHandleClientCallbacks(false /*isCalledOnInterval*/, 2 /*knownClientCount*/);
705 
706     if (clients) {
707         // client callbacks are either disabled or there are other clients
708         LOG(INFO) << "Tried to unregister for " << fqName << "/" << name
709             << " but there are clients: " << clients;
710         return false;
711     }
712 
713     // will remove entire parent hierarchy
714     bool success = removeService(service, &name /*restrictToInstanceName*/);
715 
716     if (registered->getService() != nullptr) {
717         LOG(ERROR) << "Bad state. Unregistration failed for " << fqName << "/" << name << ".";
718         return false;
719     }
720 
721     return success;
722 }
723 
724 Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
725     if (!mAcl.canList(getBinderCallingContext())) {
726         _cb({});
727         return Void();
728     }
729 
730     std::vector<IServiceManager::InstanceDebugInfo> list;
731     forEachServiceEntry([&] (const HidlService *service) {
732         hidl_vec<int32_t> clientPids;
733         clientPids.resize(service->getPassthroughClients().size());
734 
735         size_t i = 0;
736         for (pid_t p : service->getPassthroughClients()) {
737             clientPids[i++] = p;
738         }
739 
740         list.push_back({
741             .interfaceName = service->getInterfaceName(),
742             .instanceName = service->getInstanceName(),
743             .pid = service->getDebugPid(),
744             .clientPids = clientPids,
745             .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
746         });
747 
748         return true;  // continue
749     });
750 
751     _cb(list);
752     return Void();
753 }
754 
755 
756 Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
757         const hidl_string &name) {
758     auto callingContext = getBinderCallingContext();
759 
760     if (!mAcl.canGet(fqName, callingContext)) {
761         /* We guard this function with "get", because it's typically used in
762          * the getService() path, albeit for a passthrough service in this
763          * case
764          */
765         return Void();
766     }
767 
768     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
769 
770     if (name.empty()) {
771         LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
772                      << fqName.c_str();
773         return Void();
774     }
775 
776     HidlService *service = ifaceMap.lookup(name);
777 
778     if (service == nullptr) {
779         auto adding = std::make_unique<HidlService>(fqName, name);
780         adding->registerPassthroughClient(callingContext.pid);
781         ifaceMap.insertService(std::move(adding));
782     } else {
783         service->registerPassthroughClient(callingContext.pid);
784     }
785     return Void();
786 }
787 
788 bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
789     bool keepInstance = false;
790     bool removed = false;
791     for (auto &interfaceMapping : mServiceMap) {
792         auto &instanceMap = interfaceMapping.second.getInstanceMap();
793 
794         for (auto &servicePair : instanceMap) {
795             const std::string &instanceName = servicePair.first;
796             const std::unique_ptr<HidlService> &service = servicePair.second;
797 
798             if (interfacesEqual(service->getService(), who.promote())) {
799                 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
800                     // We cannot remove all instances of this service, so we don't return that it
801                     // has been entirely removed.
802                     keepInstance = true;
803                     continue;
804                 }
805 
806                 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
807                 removed = true;
808             }
809         }
810     }
811 
812     return !keepInstance && removed;
813 }
814 
815 bool ServiceManager::removePackageListener(const wp<IBase>& who) {
816     bool found = false;
817 
818     for (auto &interfaceMapping : mServiceMap) {
819         found |= interfaceMapping.second.removePackageListener(who);
820     }
821 
822     return found;
823 }
824 
825 bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
826     bool found = false;
827     for (auto &interfaceMapping : mServiceMap) {
828         auto &packageInterfaceMap = interfaceMapping.second;
829 
830         found |= packageInterfaceMap.removeServiceListener(who);
831     }
832     return found;
833 }
834 }  // namespace implementation
835 }  // namespace manager
836 }  // namespace hidl
837 }  // namespace android
838