• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define LOG_TAG "hwservicemanager"
2 
3 #include "ServiceManager.h"
4 #include "Vintf.h"
5 
6 #include <android-base/logging.h>
7 #include <android-base/properties.h>
8 #include <hwbinder/IPCThreadState.h>
9 #include <hidl/HidlSupport.h>
10 #include <hidl/HidlTransportSupport.h>
11 #include <regex>
12 #include <sstream>
13 #include <thread>
14 
15 using android::hardware::IPCThreadState;
16 
17 namespace android {
18 namespace hidl {
19 namespace manager {
20 namespace implementation {
21 
getBinderCallingContext()22 AccessControl::CallingContext getBinderCallingContext() {
23     const auto& self = IPCThreadState::self();
24 
25     pid_t pid = self->getCallingPid();
26     const char* sid = self->getCallingSid();
27 
28     if (sid == nullptr) {
29         if (pid != getpid()) {
30             android_errorWriteLog(0x534e4554, "121035042");
31         }
32 
33         return AccessControl::getCallingContext(pid);
34     } else {
35         return { true, sid, pid };
36     }
37 }
38 
39 static constexpr uint64_t kServiceDiedCookie = 0;
40 static constexpr uint64_t kPackageListenerDiedCookie = 1;
41 static constexpr uint64_t kServiceListenerDiedCookie = 2;
42 
countExistingService() const43 size_t ServiceManager::countExistingService() const {
44     size_t total = 0;
45     forEachExistingService([&] (const HidlService *) {
46         ++total;
47     });
48     return total;
49 }
50 
forEachExistingService(std::function<void (const HidlService *)> f) const51 void ServiceManager::forEachExistingService(std::function<void(const HidlService *)> f) const {
52     forEachServiceEntry([f] (const HidlService *service) {
53         if (service->getService() == nullptr) {
54             return;
55         }
56         f(service);
57     });
58 }
59 
forEachServiceEntry(std::function<void (const HidlService *)> f) const60 void ServiceManager::forEachServiceEntry(std::function<void(const HidlService *)> f) const {
61     for (const auto &interfaceMapping : mServiceMap) {
62         const auto &instanceMap = interfaceMapping.second.getInstanceMap();
63 
64         for (const auto &instanceMapping : instanceMap) {
65             f(instanceMapping.second.get());
66         }
67     }
68 }
69 
serviceDied(uint64_t cookie,const wp<IBase> & who)70 void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
71     switch (cookie) {
72         case kServiceDiedCookie:
73             removeService(who, nullptr /* restrictToInstanceName */);
74             break;
75         case kPackageListenerDiedCookie:
76             removePackageListener(who);
77             break;
78         case kServiceListenerDiedCookie:
79             removeServiceListener(who);
80             break;
81     }
82 }
83 
getInstanceMap()84 ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() {
85     return mInstanceMap;
86 }
87 
getInstanceMap() const88 const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const {
89     return mInstanceMap;
90 }
91 
lookup(const std::string & name) const92 const HidlService *ServiceManager::PackageInterfaceMap::lookup(
93         const std::string &name) const {
94     auto it = mInstanceMap.find(name);
95 
96     if (it == mInstanceMap.end()) {
97         return nullptr;
98     }
99 
100     return it->second.get();
101 }
102 
lookup(const std::string & name)103 HidlService *ServiceManager::PackageInterfaceMap::lookup(
104         const std::string &name) {
105 
106     return const_cast<HidlService*>(
107         const_cast<const PackageInterfaceMap*>(this)->lookup(name));
108 }
109 
insertService(std::unique_ptr<HidlService> && service)110 void ServiceManager::PackageInterfaceMap::insertService(
111         std::unique_ptr<HidlService> &&service) {
112     mInstanceMap.insert({service->getInstanceName(), std::move(service)});
113 }
114 
sendPackageRegistrationNotification(const hidl_string & fqName,const hidl_string & instanceName)115 void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification(
116         const hidl_string &fqName,
117         const hidl_string &instanceName) {
118 
119     for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
120         auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */);
121         if (ret.isOk()) {
122             ++it;
123         } else {
124             LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName
125                        << ": transport error.";
126             it = mPackageListeners.erase(it);
127         }
128     }
129 }
130 
addPackageListener(sp<IServiceNotification> listener)131 void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) {
132     for (const auto &instanceMapping : mInstanceMap) {
133         const std::unique_ptr<HidlService> &service = instanceMapping.second;
134 
135         if (service->getService() == nullptr) {
136             continue;
137         }
138 
139         auto ret = listener->onRegistration(
140             service->getInterfaceName(),
141             service->getInstanceName(),
142             true /* preexisting */);
143         if (!ret.isOk()) {
144             LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName()
145                        << "/" << service->getInstanceName() << ": transport error "
146                        << "when sending notification for already registered instance.";
147             return;
148         }
149     }
150     mPackageListeners.push_back(listener);
151 }
152 
removePackageListener(const wp<IBase> & who)153 bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
154     using ::android::hardware::interfacesEqual;
155 
156     bool found = false;
157 
158     for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
159         if (interfacesEqual(*it, who.promote())) {
160             it = mPackageListeners.erase(it);
161             found = true;
162         } else {
163             ++it;
164         }
165     }
166 
167     return found;
168 }
169 
removeServiceListener(const wp<IBase> & who)170 bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
171     using ::android::hardware::interfacesEqual;
172 
173     bool found = false;
174 
175     for (auto &servicePair : getInstanceMap()) {
176         const std::unique_ptr<HidlService> &service = servicePair.second;
177         found |= service->removeListener(who);
178     }
179 
180     return found;
181 }
182 
tryStartService(const std::string & fqName,const std::string & name)183 static void tryStartService(const std::string& fqName, const std::string& name) {
184     using ::android::base::SetProperty;
185 
186     std::thread([=] {
187         bool success = SetProperty("ctl.interface_start", fqName + "/" + name);
188 
189         if (!success) {
190             LOG(ERROR) << "Failed to set property for starting " << fqName << "/" << name;
191         }
192     }).detach();
193 }
194 
195 // Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
get(const hidl_string & hidlFqName,const hidl_string & hidlName)196 Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
197                                       const hidl_string& hidlName) {
198     const std::string fqName = hidlFqName;
199     const std::string name = hidlName;
200 
201     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
202         return nullptr;
203     }
204 
205     auto ifaceIt = mServiceMap.find(fqName);
206     if (ifaceIt == mServiceMap.end()) {
207         tryStartService(fqName, hidlName);
208         return nullptr;
209     }
210 
211     const PackageInterfaceMap &ifaceMap = ifaceIt->second;
212     const HidlService *hidlService = ifaceMap.lookup(name);
213 
214     if (hidlService == nullptr) {
215         tryStartService(fqName, hidlName);
216         return nullptr;
217     }
218 
219     sp<IBase> service = hidlService->getService();
220     if (service == nullptr) {
221         tryStartService(fqName, hidlName);
222         return nullptr;
223     }
224 
225     return service;
226 }
227 
add(const hidl_string & name,const sp<IBase> & service)228 Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
229     bool isValidService = false;
230 
231     if (service == nullptr) {
232         return false;
233     }
234 
235     auto callingContext = getBinderCallingContext();
236 
237     auto ret = service->interfaceChain([&](const auto &interfaceChain) {
238         if (interfaceChain.size() == 0) {
239             return;
240         }
241 
242         // First, verify you're allowed to add() the whole interface hierarchy
243         for(size_t i = 0; i < interfaceChain.size(); i++) {
244             const std::string fqName = interfaceChain[i];
245 
246             if (!mAcl.canAdd(fqName, callingContext)) {
247                 return;
248             }
249         }
250 
251         {
252             // For IBar extends IFoo if IFoo/default is being registered, remove
253             // IBar/default. This makes sure the following two things are equivalent
254             // 1). IBar::castFrom(IFoo::getService(X))
255             // 2). IBar::getService(X)
256             // assuming that IBar is declared in the device manifest and there
257             // is also not an IBaz extends IFoo.
258             const std::string childFqName = interfaceChain[0];
259             const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
260             const HidlService *hidlService = ifaceMap.lookup(name);
261             if (hidlService != nullptr) {
262                 const sp<IBase> remove = hidlService->getService();
263 
264                 if (remove != nullptr) {
265                     const std::string instanceName = name;
266                     removeService(remove, &instanceName /* restrictToInstanceName */);
267                 }
268             }
269         }
270 
271         for(size_t i = 0; i < interfaceChain.size(); i++) {
272             const std::string fqName = interfaceChain[i];
273 
274             PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
275             HidlService *hidlService = ifaceMap.lookup(name);
276 
277             if (hidlService == nullptr) {
278                 ifaceMap.insertService(
279                     std::make_unique<HidlService>(fqName, name, service, callingContext.pid));
280             } else {
281                 hidlService->setService(service, callingContext.pid);
282             }
283 
284             ifaceMap.sendPackageRegistrationNotification(fqName, name);
285         }
286 
287         bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
288         if (!linkRet) {
289             LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
290         }
291 
292         isValidService = true;
293     });
294 
295     if (!ret.isOk()) {
296         LOG(ERROR) << "Failed to retrieve interface chain.";
297         return false;
298     }
299 
300     return isValidService;
301 }
302 
getTransport(const hidl_string & fqName,const hidl_string & name)303 Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
304                                                                const hidl_string& name) {
305     using ::android::hardware::getTransport;
306 
307     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
308         return Transport::EMPTY;
309     }
310 
311     switch (getTransport(fqName, name)) {
312         case vintf::Transport::HWBINDER:
313              return Transport::HWBINDER;
314         case vintf::Transport::PASSTHROUGH:
315              return Transport::PASSTHROUGH;
316         case vintf::Transport::EMPTY:
317         default:
318              return Transport::EMPTY;
319     }
320 }
321 
list(list_cb _hidl_cb)322 Return<void> ServiceManager::list(list_cb _hidl_cb) {
323     if (!mAcl.canList(getBinderCallingContext())) {
324         _hidl_cb({});
325         return Void();
326     }
327 
328     hidl_vec<hidl_string> list;
329 
330     list.resize(countExistingService());
331 
332     size_t idx = 0;
333     forEachExistingService([&] (const HidlService *service) {
334         list[idx++] = service->string();
335     });
336 
337     _hidl_cb(list);
338     return Void();
339 }
340 
listByInterface(const hidl_string & fqName,listByInterface_cb _hidl_cb)341 Return<void> ServiceManager::listByInterface(const hidl_string& fqName,
342                                              listByInterface_cb _hidl_cb) {
343     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
344         _hidl_cb({});
345         return Void();
346     }
347 
348     auto ifaceIt = mServiceMap.find(fqName);
349     if (ifaceIt == mServiceMap.end()) {
350         _hidl_cb(hidl_vec<hidl_string>());
351         return Void();
352     }
353 
354     const auto &instanceMap = ifaceIt->second.getInstanceMap();
355 
356     hidl_vec<hidl_string> list;
357 
358     size_t total = 0;
359     for (const auto &serviceMapping : instanceMap) {
360         const std::unique_ptr<HidlService> &service = serviceMapping.second;
361         if (service->getService() == nullptr) continue;
362 
363         ++total;
364     }
365     list.resize(total);
366 
367     size_t idx = 0;
368     for (const auto &serviceMapping : instanceMap) {
369         const std::unique_ptr<HidlService> &service = serviceMapping.second;
370         if (service->getService() == nullptr) continue;
371 
372         list[idx++] = service->getInstanceName();
373     }
374 
375     _hidl_cb(list);
376     return Void();
377 }
378 
registerForNotifications(const hidl_string & fqName,const hidl_string & name,const sp<IServiceNotification> & callback)379 Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName,
380                                                       const hidl_string& name,
381                                                       const sp<IServiceNotification>& callback) {
382     if (callback == nullptr) {
383         return false;
384     }
385 
386     if (!mAcl.canGet(fqName, getBinderCallingContext())) {
387         return false;
388     }
389 
390     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
391 
392     if (name.empty()) {
393         auto ret = callback->linkToDeath(this, kPackageListenerDiedCookie);
394         if (!ret.isOk()) {
395             LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
396             return false;
397         }
398         ifaceMap.addPackageListener(callback);
399         return true;
400     }
401 
402     HidlService *service = ifaceMap.lookup(name);
403 
404     auto ret = callback->linkToDeath(this, kServiceListenerDiedCookie);
405     if (!ret.isOk()) {
406         LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
407         return false;
408     }
409 
410     if (service == nullptr) {
411         auto adding = std::make_unique<HidlService>(fqName, name);
412         adding->addListener(callback);
413         ifaceMap.insertService(std::move(adding));
414     } else {
415         service->addListener(callback);
416     }
417 
418     return true;
419 }
420 
unregisterForNotifications(const hidl_string & fqName,const hidl_string & name,const sp<IServiceNotification> & callback)421 Return<bool> ServiceManager::unregisterForNotifications(const hidl_string& fqName,
422                                                         const hidl_string& name,
423                                                         const sp<IServiceNotification>& callback) {
424     if (callback == nullptr) {
425         LOG(ERROR) << "Cannot unregister null callback for " << fqName << "/" << name;
426         return false;
427     }
428 
429     // NOTE: don't need ACL since callback is binder token, and if someone has gotten it,
430     // then they already have access to it.
431 
432     if (fqName.empty()) {
433         bool success = false;
434         success |= removePackageListener(callback);
435         success |= removeServiceListener(callback);
436         return success;
437     }
438 
439     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
440 
441     if (name.empty()) {
442         bool success = false;
443         success |= ifaceMap.removePackageListener(callback);
444         success |= ifaceMap.removeServiceListener(callback);
445         return success;
446     }
447 
448     HidlService *service = ifaceMap.lookup(name);
449 
450     if (service == nullptr) {
451         return false;
452     }
453 
454     return service->removeListener(callback);
455 }
456 
debugDump(debugDump_cb _cb)457 Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
458     if (!mAcl.canList(getBinderCallingContext())) {
459         _cb({});
460         return Void();
461     }
462 
463     std::vector<IServiceManager::InstanceDebugInfo> list;
464     forEachServiceEntry([&] (const HidlService *service) {
465         hidl_vec<int32_t> clientPids;
466         clientPids.resize(service->getPassthroughClients().size());
467 
468         size_t i = 0;
469         for (pid_t p : service->getPassthroughClients()) {
470             clientPids[i++] = p;
471         }
472 
473         list.push_back({
474             .pid = service->getDebugPid(),
475             .interfaceName = service->getInterfaceName(),
476             .instanceName = service->getInstanceName(),
477             .clientPids = clientPids,
478             .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
479         });
480     });
481 
482     _cb(list);
483     return Void();
484 }
485 
486 
registerPassthroughClient(const hidl_string & fqName,const hidl_string & name)487 Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName,
488         const hidl_string &name) {
489     auto callingContext = getBinderCallingContext();
490 
491     if (!mAcl.canGet(fqName, callingContext)) {
492         /* We guard this function with "get", because it's typically used in
493          * the getService() path, albeit for a passthrough service in this
494          * case
495          */
496         return Void();
497     }
498 
499     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
500 
501     if (name.empty()) {
502         LOG(WARNING) << "registerPassthroughClient encounters empty instance name for "
503                      << fqName.c_str();
504         return Void();
505     }
506 
507     HidlService *service = ifaceMap.lookup(name);
508 
509     if (service == nullptr) {
510         auto adding = std::make_unique<HidlService>(fqName, name);
511         adding->registerPassthroughClient(callingContext.pid);
512         ifaceMap.insertService(std::move(adding));
513     } else {
514         service->registerPassthroughClient(callingContext.pid);
515     }
516     return Void();
517 }
518 
removeService(const wp<IBase> & who,const std::string * restrictToInstanceName)519 bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
520     using ::android::hardware::interfacesEqual;
521 
522     bool keepInstance = false;
523     bool removed = false;
524     for (auto &interfaceMapping : mServiceMap) {
525         auto &instanceMap = interfaceMapping.second.getInstanceMap();
526 
527         for (auto &servicePair : instanceMap) {
528             const std::string &instanceName = servicePair.first;
529             const std::unique_ptr<HidlService> &service = servicePair.second;
530 
531             if (interfacesEqual(service->getService(), who.promote())) {
532                 if (restrictToInstanceName != nullptr && *restrictToInstanceName != instanceName) {
533                     // We cannot remove all instances of this service, so we don't return that it
534                     // has been entirely removed.
535                     keepInstance = true;
536                     continue;
537                 }
538 
539                 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID));
540                 removed = true;
541             }
542         }
543     }
544 
545     return !keepInstance && removed;
546 }
547 
removePackageListener(const wp<IBase> & who)548 bool ServiceManager::removePackageListener(const wp<IBase>& who) {
549     bool found = false;
550 
551     for (auto &interfaceMapping : mServiceMap) {
552         found |= interfaceMapping.second.removePackageListener(who);
553     }
554 
555     return found;
556 }
557 
removeServiceListener(const wp<IBase> & who)558 bool ServiceManager::removeServiceListener(const wp<IBase>& who) {
559     bool found = false;
560     for (auto &interfaceMapping : mServiceMap) {
561         auto &packageInterfaceMap = interfaceMapping.second;
562 
563         found |= packageInterfaceMap.removeServiceListener(who);
564     }
565     return found;
566 }
567 }  // namespace implementation
568 }  // namespace manager
569 }  // namespace hidl
570 }  // namespace android
571