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