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