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