1#define LOG_TAG "hwservicemanager" 2 3#include "ServiceManager.h" 4#include "Vintf.h" 5 6#include <android-base/logging.h> 7#include <hwbinder/IPCThreadState.h> 8#include <hidl/HidlSupport.h> 9#include <regex> 10#include <sstream> 11 12using android::hardware::IPCThreadState; 13 14namespace android { 15namespace hidl { 16namespace manager { 17namespace V1_0 { 18namespace implementation { 19 20static constexpr uint64_t kServiceDiedCookie = 0; 21static constexpr uint64_t kPackageListenerDiedCookie = 1; 22static constexpr uint64_t kServiceListenerDiedCookie = 2; 23 24size_t ServiceManager::countExistingService() const { 25 size_t total = 0; 26 forEachExistingService([&] (const HidlService *) { 27 ++total; 28 }); 29 return total; 30} 31 32void ServiceManager::forEachExistingService(std::function<void(const HidlService *)> f) const { 33 forEachServiceEntry([f] (const HidlService *service) { 34 if (service->getService() == nullptr) { 35 return; 36 } 37 f(service); 38 }); 39} 40 41void ServiceManager::forEachServiceEntry(std::function<void(const HidlService *)> f) const { 42 for (const auto &interfaceMapping : mServiceMap) { 43 const auto &instanceMap = interfaceMapping.second.getInstanceMap(); 44 45 for (const auto &instanceMapping : instanceMap) { 46 f(instanceMapping.second.get()); 47 } 48 } 49} 50 51void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) { 52 switch (cookie) { 53 case kServiceDiedCookie: 54 remove(who); 55 break; 56 case kPackageListenerDiedCookie: 57 removePackageListener(who); 58 break; 59 case kServiceListenerDiedCookie: 60 removeServiceListener(who); 61 break; 62 } 63} 64 65ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() { 66 return mInstanceMap; 67} 68 69const ServiceManager::InstanceMap &ServiceManager::PackageInterfaceMap::getInstanceMap() const { 70 return mInstanceMap; 71} 72 73const HidlService *ServiceManager::PackageInterfaceMap::lookup( 74 const std::string &name) const { 75 auto it = mInstanceMap.find(name); 76 77 if (it == mInstanceMap.end()) { 78 return nullptr; 79 } 80 81 return it->second.get(); 82} 83 84HidlService *ServiceManager::PackageInterfaceMap::lookup( 85 const std::string &name) { 86 87 return const_cast<HidlService*>( 88 const_cast<const PackageInterfaceMap*>(this)->lookup(name)); 89} 90 91void ServiceManager::PackageInterfaceMap::insertService( 92 std::unique_ptr<HidlService> &&service) { 93 mInstanceMap.insert({service->getInstanceName(), std::move(service)}); 94} 95 96void ServiceManager::PackageInterfaceMap::sendPackageRegistrationNotification( 97 const hidl_string &fqName, 98 const hidl_string &instanceName) { 99 100 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) { 101 auto ret = (*it)->onRegistration(fqName, instanceName, false /* preexisting */); 102 if (ret.isOk()) { 103 ++it; 104 } else { 105 LOG(ERROR) << "Dropping registration callback for " << fqName << "/" << instanceName 106 << ": transport error."; 107 it = mPackageListeners.erase(it); 108 } 109 } 110} 111 112void ServiceManager::PackageInterfaceMap::addPackageListener(sp<IServiceNotification> listener) { 113 for (const auto &instanceMapping : mInstanceMap) { 114 const std::unique_ptr<HidlService> &service = instanceMapping.second; 115 116 if (service->getService() == nullptr) { 117 continue; 118 } 119 120 auto ret = listener->onRegistration( 121 service->getInterfaceName(), 122 service->getInstanceName(), 123 true /* preexisting */); 124 if (!ret.isOk()) { 125 LOG(ERROR) << "Not adding package listener for " << service->getInterfaceName() 126 << "/" << service->getInstanceName() << ": transport error " 127 << "when sending notification for already registered instance."; 128 return; 129 } 130 } 131 mPackageListeners.push_back(listener); 132} 133 134bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) { 135 bool found = false; 136 137 for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) { 138 if (*it == who) { 139 it = mPackageListeners.erase(it); 140 found = true; 141 } else { 142 ++it; 143 } 144 } 145 146 return found; 147} 148 149// Methods from ::android::hidl::manager::V1_0::IServiceManager follow. 150Return<sp<IBase>> ServiceManager::get(const hidl_string& fqName, 151 const hidl_string& name) { 152 pid_t pid = IPCThreadState::self()->getCallingPid(); 153 if (!mAcl.canGet(fqName, pid)) { 154 return nullptr; 155 } 156 157 auto ifaceIt = mServiceMap.find(fqName); 158 if (ifaceIt == mServiceMap.end()) { 159 return nullptr; 160 } 161 162 const PackageInterfaceMap &ifaceMap = ifaceIt->second; 163 const HidlService *hidlService = ifaceMap.lookup(name); 164 165 if (hidlService == nullptr) { 166 return nullptr; 167 } 168 169 return hidlService->getService(); 170} 171 172Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) { 173 bool isValidService = false; 174 175 if (service == nullptr) { 176 return false; 177 } 178 179 // TODO(b/34235311): use HIDL way to determine this 180 // also, this assumes that the PID that is registering is the pid that is the service 181 pid_t pid = IPCThreadState::self()->getCallingPid(); 182 183 auto ret = service->interfaceChain([&](const auto &interfaceChain) { 184 if (interfaceChain.size() == 0) { 185 return; 186 } 187 188 // First, verify you're allowed to add() the whole interface hierarchy 189 for(size_t i = 0; i < interfaceChain.size(); i++) { 190 std::string fqName = interfaceChain[i]; 191 192 if (!mAcl.canAdd(fqName, pid)) { 193 return; 194 } 195 } 196 197 for(size_t i = 0; i < interfaceChain.size(); i++) { 198 std::string fqName = interfaceChain[i]; 199 200 PackageInterfaceMap &ifaceMap = mServiceMap[fqName]; 201 HidlService *hidlService = ifaceMap.lookup(name); 202 203 if (hidlService == nullptr) { 204 ifaceMap.insertService( 205 std::make_unique<HidlService>(fqName, name, service, pid)); 206 } else { 207 if (hidlService->getService() != nullptr) { 208 auto ret = hidlService->getService()->unlinkToDeath(this); 209 ret.isOk(); // ignore 210 } 211 hidlService->setService(service, pid); 212 } 213 214 ifaceMap.sendPackageRegistrationNotification(fqName, name); 215 } 216 217 auto linkRet = service->linkToDeath(this, 0 /*cookie*/); 218 linkRet.isOk(); // ignore 219 220 isValidService = true; 221 }); 222 223 if (!ret.isOk()) { 224 LOG(ERROR) << "Failed to retrieve interface chain."; 225 return false; 226 } 227 228 return isValidService; 229} 230 231Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName, 232 const hidl_string& name) { 233 using ::android::hardware::getTransport; 234 235 pid_t pid = IPCThreadState::self()->getCallingPid(); 236 if (!mAcl.canGet(fqName, pid)) { 237 return Transport::EMPTY; 238 } 239 240 switch (getTransport(fqName, name)) { 241 case vintf::Transport::HWBINDER: 242 return Transport::HWBINDER; 243 case vintf::Transport::PASSTHROUGH: 244 return Transport::PASSTHROUGH; 245 case vintf::Transport::EMPTY: 246 default: 247 return Transport::EMPTY; 248 } 249} 250 251Return<void> ServiceManager::list(list_cb _hidl_cb) { 252 pid_t pid = IPCThreadState::self()->getCallingPid(); 253 if (!mAcl.canList(pid)) { 254 _hidl_cb({}); 255 return Void(); 256 } 257 258 hidl_vec<hidl_string> list; 259 260 list.resize(countExistingService()); 261 262 size_t idx = 0; 263 forEachExistingService([&] (const HidlService *service) { 264 list[idx++] = service->string(); 265 }); 266 267 _hidl_cb(list); 268 return Void(); 269} 270 271Return<void> ServiceManager::listByInterface(const hidl_string& fqName, 272 listByInterface_cb _hidl_cb) { 273 pid_t pid = IPCThreadState::self()->getCallingPid(); 274 if (!mAcl.canGet(fqName, pid)) { 275 _hidl_cb({}); 276 return Void(); 277 } 278 279 auto ifaceIt = mServiceMap.find(fqName); 280 if (ifaceIt == mServiceMap.end()) { 281 _hidl_cb(hidl_vec<hidl_string>()); 282 return Void(); 283 } 284 285 const auto &instanceMap = ifaceIt->second.getInstanceMap(); 286 287 hidl_vec<hidl_string> list; 288 289 size_t total = 0; 290 for (const auto &serviceMapping : instanceMap) { 291 const std::unique_ptr<HidlService> &service = serviceMapping.second; 292 if (service->getService() == nullptr) continue; 293 294 ++total; 295 } 296 list.resize(total); 297 298 size_t idx = 0; 299 for (const auto &serviceMapping : instanceMap) { 300 const std::unique_ptr<HidlService> &service = serviceMapping.second; 301 if (service->getService() == nullptr) continue; 302 303 list[idx++] = service->getInstanceName(); 304 } 305 306 _hidl_cb(list); 307 return Void(); 308} 309 310Return<bool> ServiceManager::registerForNotifications(const hidl_string& fqName, 311 const hidl_string& name, 312 const sp<IServiceNotification>& callback) { 313 if (callback == nullptr) { 314 return false; 315 } 316 317 pid_t pid = IPCThreadState::self()->getCallingPid(); 318 if (!mAcl.canGet(fqName, pid)) { 319 return false; 320 } 321 322 PackageInterfaceMap &ifaceMap = mServiceMap[fqName]; 323 324 if (name.empty()) { 325 auto ret = callback->linkToDeath(this, kPackageListenerDiedCookie /*cookie*/); 326 if (!ret.isOk()) { 327 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name; 328 return false; 329 } 330 ifaceMap.addPackageListener(callback); 331 return true; 332 } 333 334 HidlService *service = ifaceMap.lookup(name); 335 336 auto ret = callback->linkToDeath(this, kServiceListenerDiedCookie); 337 if (!ret.isOk()) { 338 LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name; 339 return false; 340 } 341 342 if (service == nullptr) { 343 auto adding = std::make_unique<HidlService>(fqName, name); 344 adding->addListener(callback); 345 ifaceMap.insertService(std::move(adding)); 346 } else { 347 service->addListener(callback); 348 } 349 350 return true; 351} 352 353Return<void> ServiceManager::debugDump(debugDump_cb _cb) { 354 pid_t pid = IPCThreadState::self()->getCallingPid(); 355 if (!mAcl.canList(pid)) { 356 _cb({}); 357 return Void(); 358 } 359 360 std::vector<IServiceManager::InstanceDebugInfo> list; 361 forEachServiceEntry([&] (const HidlService *service) { 362 hidl_vec<int32_t> clientPids; 363 clientPids.resize(service->getPassthroughClients().size()); 364 365 size_t i = 0; 366 for (pid_t p : service->getPassthroughClients()) { 367 clientPids[i++] = p; 368 } 369 370 list.push_back({ 371 .pid = service->getPid(), 372 .interfaceName = service->getInterfaceName(), 373 .instanceName = service->getInstanceName(), 374 .clientPids = clientPids, 375 .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN 376 }); 377 }); 378 379 _cb(list); 380 return Void(); 381} 382 383 384Return<void> ServiceManager::registerPassthroughClient(const hidl_string &fqName, 385 const hidl_string &name) { 386 pid_t pid = IPCThreadState::self()->getCallingPid(); 387 if (!mAcl.canGet(fqName, pid)) { 388 /* We guard this function with "get", because it's typically used in 389 * the getService() path, albeit for a passthrough service in this 390 * case 391 */ 392 return Void(); 393 } 394 395 PackageInterfaceMap &ifaceMap = mServiceMap[fqName]; 396 397 if (name.empty()) { 398 LOG(WARNING) << "registerPassthroughClient encounters empty instance name for " 399 << fqName.c_str(); 400 return Void(); 401 } 402 403 HidlService *service = ifaceMap.lookup(name); 404 405 if (service == nullptr) { 406 auto adding = std::make_unique<HidlService>(fqName, name); 407 adding->registerPassthroughClient(pid); 408 ifaceMap.insertService(std::move(adding)); 409 } else { 410 service->registerPassthroughClient(pid); 411 } 412 return Void(); 413} 414 415bool ServiceManager::remove(const wp<IBase>& who) { 416 bool found = false; 417 for (auto &interfaceMapping : mServiceMap) { 418 auto &instanceMap = interfaceMapping.second.getInstanceMap(); 419 420 for (auto &servicePair : instanceMap) { 421 const std::unique_ptr<HidlService> &service = servicePair.second; 422 if (service->getService() == who) { 423 service->setService(nullptr, static_cast<pid_t>(IServiceManager::PidConstant::NO_PID)); 424 found = true; 425 } 426 } 427 } 428 return found; 429} 430 431bool ServiceManager::removePackageListener(const wp<IBase>& who) { 432 bool found = false; 433 434 for (auto &interfaceMapping : mServiceMap) { 435 found |= interfaceMapping.second.removePackageListener(who); 436 } 437 438 return found; 439} 440 441bool ServiceManager::removeServiceListener(const wp<IBase>& who) { 442 bool found = false; 443 for (auto &interfaceMapping : mServiceMap) { 444 auto &instanceMap = interfaceMapping.second.getInstanceMap(); 445 446 for (auto &servicePair : instanceMap) { 447 const std::unique_ptr<HidlService> &service = servicePair.second; 448 found |= service->removeListener(who); 449 } 450 } 451 return found; 452} 453} // namespace implementation 454} // namespace V1_0 455} // namespace manager 456} // namespace hidl 457} // namespace android 458