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