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