15d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland/* 25d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * Copyright (C) 2016 The Android Open Source Project 35d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * 45d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * Licensed under the Apache License, Version 2.0 (the "License"); 55d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * you may not use this file except in compliance with the License. 65d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * You may obtain a copy of the License at 75d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * 85d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * http://www.apache.org/licenses/LICENSE-2.0 95d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * 105d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * Unless required by applicable law or agreed to in writing, software 115d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * distributed under the License is distributed on an "AS IS" BASIS, 125d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * See the License for the specific language governing permissions and 145d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland * limitations under the License. 155d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland */ 165d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 175d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland#define LOG_TAG "ServiceManagement" 185d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 193ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park#include <android/dlext.h> 209a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#include <condition_variable> 219a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#include <dlfcn.h> 229a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#include <dirent.h> 23405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland#include <fstream> 24405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland#include <pthread.h> 259a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#include <unistd.h> 269a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong 279a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#include <mutex> 289a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#include <regex> 299a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong 3012f04d913dae2fb287089f6db24f144731c79d9cMartijn Coenen#include <hidl/HidlBinderSupport.h> 315d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland#include <hidl/ServiceManagement.h> 325d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland#include <hidl/Status.h> 335d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 34337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland#include <android-base/logging.h> 35c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland#include <android-base/properties.h> 365d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland#include <hwbinder/IPCThreadState.h> 375d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland#include <hwbinder/Parcel.h> 385d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 395d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland#include <android/hidl/manager/1.0/IServiceManager.h> 404e92599704db4a3e29d4ad4a539586b019c99dfbYifan Hong#include <android/hidl/manager/1.0/BpHwServiceManager.h> 414e92599704db4a3e29d4ad4a539586b019c99dfbYifan Hong#include <android/hidl/manager/1.0/BnHwServiceManager.h> 425d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 439a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*" 449a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*" 459a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hongstatic const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so"); 469a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong 473ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Parkextern "C" { 483ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park android_namespace_t* android_get_exported_namespace(const char*); 493ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park} 503ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park 51c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Morelandusing android::base::WaitForProperty; 52c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland 535d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Morelandusing android::hidl::manager::V1_0::IServiceManager; 54337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Morelandusing android::hidl::manager::V1_0::IServiceNotification; 554e92599704db4a3e29d4ad4a539586b019c99dfbYifan Hongusing android::hidl::manager::V1_0::BpHwServiceManager; 564e92599704db4a3e29d4ad4a539586b019c99dfbYifan Hongusing android::hidl::manager::V1_0::BnHwServiceManager; 575d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 585d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Morelandnamespace android { 595d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Morelandnamespace hardware { 605d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 61953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hongnamespace details { 62953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hongextern Mutex gDefaultServiceManagerLock; 63953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hongextern sp<android::hidl::manager::V1_0::IServiceManager> gDefaultServiceManager; 64953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong} // namespace details 65953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong 66c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Morelandstatic const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready"; 67c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland 68c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Morelandvoid waitForHwServiceManager() { 69c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland using std::literals::chrono_literals::operator""s; 70c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland 71c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) { 72c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another..."; 73c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland } 74c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland} 75c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland 76405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandbool endsWith(const std::string &in, const std::string &suffix) { 77405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland return in.size() >= suffix.size() && 78405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland in.substr(in.size() - suffix.size()) == suffix; 79405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland} 80405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 81405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandbool startsWith(const std::string &in, const std::string &prefix) { 82405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland return in.size() >= prefix.size() && 83405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland in.substr(0, prefix.size()) == prefix; 84405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland} 85405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 86405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandstd::string binaryName() { 87405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland std::ifstream ifs("/proc/self/cmdline"); 88405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland std::string cmdline; 89405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland if (!ifs.is_open()) { 90405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland return ""; 91405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland } 92405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland ifs >> cmdline; 93405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 94405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland size_t idx = cmdline.rfind("/"); 95405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland if (idx != std::string::npos) { 96405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland cmdline = cmdline.substr(idx + 1); 97405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland } 98405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 99405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland return cmdline; 100405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland} 101405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 102405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandvoid tryShortenProcessName(const std::string &packageName) { 103405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland std::string processName = binaryName(); 104405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 105405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland if (!startsWith(processName, packageName)) { 106405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland return; 107405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland } 108405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 109405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland // e.x. android.hardware.module.foo@1.0 -> foo@1.0 110405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland size_t lastDot = packageName.rfind('.'); 111405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland size_t secondDot = packageName.rfind('.', lastDot - 1); 112405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 113405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland if (secondDot == std::string::npos) { 114405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland return; 115405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland } 116405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 117405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland std::string newName = processName.substr(secondDot + 1, 118405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 16 /* TASK_COMM_LEN */ - 1); 119405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland ALOGI("Removing namespace from process name %s to %s.", 120405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland processName.c_str(), newName.c_str()); 121405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 122405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland int rc = pthread_setname_np(pthread_self(), newName.c_str()); 123405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland ALOGI_IF(rc != 0, "Removing namespace from process name %s failed.", 124405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland processName.c_str()); 125405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland} 126405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 127405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandnamespace details { 1285d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 129405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandvoid onRegistration(const std::string &packageName, 130405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland const std::string& /* interfaceName */, 131405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland const std::string& /* instanceName */) { 132405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland tryShortenProcessName(packageName); 133405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland} 134405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 135405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland} // details 136405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 137405d76134f5ec033817a21fbbcc13083fe0349feSteven Morelandsp<IServiceManager> defaultServiceManager() { 1385d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland { 139953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong AutoMutex _l(details::gDefaultServiceManagerLock); 140953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong if (details::gDefaultServiceManager != NULL) { 141953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong return details::gDefaultServiceManager; 1428fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong } 143405d76134f5ec033817a21fbbcc13083fe0349feSteven Moreland 1448fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) { 1458fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong // HwBinder not available on this device or not accessible to 1468fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong // this process. 1478fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong return nullptr; 1488fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong } 149c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland 150c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland waitForHwServiceManager(); 151c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland 152953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong while (details::gDefaultServiceManager == NULL) { 153953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong details::gDefaultServiceManager = 1548fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>( 1558fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong ProcessState::self()->getContextObject(NULL)); 156953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong if (details::gDefaultServiceManager == NULL) { 157c1cee2ca2b50b13281dedc3e3a9079a3b9b59ff6Steven Moreland LOG(ERROR) << "Waited for hwservicemanager, but got nullptr."; 1585d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland sleep(1); 1598fb656b8ad63536bb8a16548fc33c6a2f3e0435bYifan Hong } 1605d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland } 1615d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland } 1625d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 163953e6b0f57b5003390b3e70904bfa47f535492e4Yifan Hong return details::gDefaultServiceManager; 1645d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland} 1655d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland 1660091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Morelandstd::vector<std::string> search(const std::string &path, 1670091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland const std::string &prefix, 1680091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland const std::string &suffix) { 1690091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir); 1700091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland if (!dir) return {}; 1710091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 1720091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland std::vector<std::string> results{}; 1730091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 1740091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland dirent* dp; 1750091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland while ((dp = readdir(dir.get())) != nullptr) { 1760091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland std::string name = dp->d_name; 1770091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 178819c05d28de72983177620902990dff360e80e73Steven Moreland if (startsWith(name, prefix) && 179819c05d28de72983177620902990dff360e80e73Steven Moreland endsWith(name, suffix)) { 1800091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland results.push_back(name); 1810091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland } 1820091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland } 1830091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 1840091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland return results; 1850091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland} 1860091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 1879a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hongbool matchPackageName(const std::string &lib, std::string *matchedName) { 1889a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong std::smatch match; 1899a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong if (std::regex_match(lib, match, gLibraryFileNamePattern)) { 1909a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong *matchedName = match.str(1) + "::I*"; 1919a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong return true; 1929a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong } 1939a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong return false; 1949a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong} 1959a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong 1967f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hongstatic void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) { 1977f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong sp<IServiceManager> binderizedManager = defaultServiceManager(); 1987f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong if (binderizedManager == nullptr) { 1997f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong LOG(WARNING) << "Could not registerReference for " 2007f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong << interfaceName << "/" << instanceName 2017f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong << ": null binderized manager."; 2027f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong return; 2037f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong } 204af4aba557ba4a7f9fe22a23ad6e26476737f824aMartijn Coenen auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName); 2057f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong if (!ret.isOk()) { 2067f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong LOG(WARNING) << "Could not registerReference for " 2077f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong << interfaceName << "/" << instanceName 2087f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong << ": " << ret.description(); 2090aeaa7847ee32aea9773aab4c39361b3802821fcSteven Moreland return; 2107f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong } 211e681aa5d655fcf5e2970b7fdc91f3b307ba50331Steven Moreland LOG(VERBOSE) << "Successfully registerReference for " 212e681aa5d655fcf5e2970b7fdc91f3b307ba50331Steven Moreland << interfaceName << "/" << instanceName; 2137f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong} 2147f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong 215337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Morelandstruct PassthroughServiceManager : IServiceManager { 216337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland Return<sp<IBase>> get(const hidl_string& fqName, 217819c05d28de72983177620902990dff360e80e73Steven Moreland const hidl_string& name) override { 218819c05d28de72983177620902990dff360e80e73Steven Moreland std::string stdFqName(fqName.c_str()); 219819c05d28de72983177620902990dff360e80e73Steven Moreland 220819c05d28de72983177620902990dff360e80e73Steven Moreland //fqName looks like android.hardware.foo@1.0::IFoo 221819c05d28de72983177620902990dff360e80e73Steven Moreland size_t idx = stdFqName.find("::"); 222337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 223819c05d28de72983177620902990dff360e80e73Steven Moreland if (idx == std::string::npos || 224819c05d28de72983177620902990dff360e80e73Steven Moreland idx + strlen("::") + 1 >= stdFqName.size()) { 225337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName; 226337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland return nullptr; 227337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland } 228337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 229819c05d28de72983177620902990dff360e80e73Steven Moreland std::string packageAndVersion = stdFqName.substr(0, idx); 230819c05d28de72983177620902990dff360e80e73Steven Moreland std::string ifaceName = stdFqName.substr(idx + strlen("::")); 231819c05d28de72983177620902990dff360e80e73Steven Moreland 232819c05d28de72983177620902990dff360e80e73Steven Moreland const std::string prefix = packageAndVersion + "-impl"; 233819c05d28de72983177620902990dff360e80e73Steven Moreland const std::string sym = "HIDL_FETCH_" + ifaceName; 234348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland 2353ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park const android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal"); 236337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland const int dlMode = RTLD_LAZY; 237337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland void *handle = nullptr; 238337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 2390091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland // TODO: lookup in VINTF instead 2400091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland // TODO(b/34135607): Remove HAL_LIBRARY_PATH_SYSTEM 2410091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 242a29905cc9dcb5a1c4368b25940aafd5081d95d54Steven Moreland dlerror(); // clear 243a29905cc9dcb5a1c4368b25940aafd5081d95d54Steven Moreland 244337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland for (const std::string &path : { 245337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM 246337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland }) { 2470091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland std::vector<std::string> libs = search(path, prefix, ".so"); 2480091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland 2490091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland for (const std::string &lib : libs) { 250348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland const std::string fullPath = path + lib; 251348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland 2523ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park // If sphal namespace is available, try to load from the 2533ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park // namespace first. If it fails, fall back to the original 2543ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park // dlopen, which loads from the current namespace. 2553ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park if (sphal_namespace != nullptr && path != HAL_LIBRARY_PATH_SYSTEM) { 2563ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park const android_dlextinfo dlextinfo = { 2573ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park .flags = ANDROID_DLEXT_USE_NAMESPACE, 2583ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park // const_cast is dirty but required because 2593ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park // library_namespace field is non-const. 2603ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park .library_namespace = const_cast<android_namespace_t*>(sphal_namespace), 2613ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park }; 2623ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park handle = android_dlopen_ext(fullPath.c_str(), dlMode, &dlextinfo); 2633ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park if (handle == nullptr) { 2643ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park const char* error = dlerror(); 2653ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park LOG(WARNING) << "Failed to dlopen " << lib << " from sphal namespace:" 2663ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park << (error == nullptr ? "unknown error" : error); 2673ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park } else { 2683ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park LOG(DEBUG) << lib << " loaded from sphal namespace."; 2693ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park } 2703ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park } 2713ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park if (handle == nullptr) { 2723ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park handle = dlopen(fullPath.c_str(), dlMode); 2733ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park } 2743ab546c2d2bd2abb72d128c6b331e8889a6a2825Jiyong Park 275348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland if (handle == nullptr) { 276348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland const char* error = dlerror(); 277348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland LOG(ERROR) << "Failed to dlopen " << lib << ": " 278348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland << (error == nullptr ? "unknown error" : error); 279348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland continue; 2800091c09e423b0bc2ccdc6075d74f60a4ce83450dSteven Moreland } 281337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 282348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland IBase* (*generator)(const char* name); 283348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland *(void **)(&generator) = dlsym(handle, sym.c_str()); 284348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland if(!generator) { 285348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland const char* error = dlerror(); 286348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland LOG(ERROR) << "Passthrough lookup opened " << lib 287348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland << " but could not find symbol " << sym << ": " 288348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland << (error == nullptr ? "unknown error" : error); 289348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland dlclose(handle); 290348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland continue; 291348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland } 292337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 2930c84ab4192f9b0b03b9840b85fc430afa17f55f1Scott Randolph IBase *interface = (*generator)(name.c_str()); 294337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 295348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland if (interface == nullptr) { 296348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland dlclose(handle); 297348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland continue; // this module doesn't provide this instance name 298348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland } 2997f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong 300348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland registerReference(fqName, name); 3017f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong 302348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland return interface; 303348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland } 304f6f1b40df805f845035ba992e8d44f24ade87b9fSteven Moreland } 305f6f1b40df805f845035ba992e8d44f24ade87b9fSteven Moreland 306348802db245e7b4d30283dd69f2bbd32e0ca8a3dSteven Moreland return nullptr; 307337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland } 308337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 30967a024919015598efa7e24f0ab3d0d9154f12523Martijn Coenen Return<bool> add(const hidl_string& /* name */, 310337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland const sp<IBase>& /* service */) override { 311337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland LOG(FATAL) << "Cannot register services with passthrough service manager."; 312337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland return false; 313337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland } 314337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 315c601c5f21808844e614015eabc03e9c71f5aae42Steven Moreland Return<Transport> getTransport(const hidl_string& /* fqName */, 316c601c5f21808844e614015eabc03e9c71f5aae42Steven Moreland const hidl_string& /* name */) { 317c601c5f21808844e614015eabc03e9c71f5aae42Steven Moreland LOG(FATAL) << "Cannot getTransport with passthrough service manager."; 318c601c5f21808844e614015eabc03e9c71f5aae42Steven Moreland return Transport::EMPTY; 319c601c5f21808844e614015eabc03e9c71f5aae42Steven Moreland } 320c601c5f21808844e614015eabc03e9c71f5aae42Steven Moreland 321705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong Return<void> list(list_cb /* _hidl_cb */) override { 322705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong LOG(FATAL) << "Cannot list services with passthrough service manager."; 323337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland return Void(); 324337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland } 325337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland Return<void> listByInterface(const hidl_string& /* fqInstanceName */, 326337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland listByInterface_cb /* _hidl_cb */) override { 327337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland // TODO: add this functionality 328337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland LOG(FATAL) << "Cannot list services with passthrough service manager."; 329337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland return Void(); 330337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland } 331337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 332337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland Return<bool> registerForNotifications(const hidl_string& /* fqName */, 333337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland const hidl_string& /* name */, 334337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland const sp<IServiceNotification>& /* callback */) override { 335337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland // This makes no sense. 336337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland LOG(FATAL) << "Cannot register for notifications with passthrough service manager."; 337337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland return false; 338337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland } 339337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 340705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong Return<void> debugDump(debugDump_cb _hidl_cb) override { 341705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong using Arch = ::android::hidl::base::V1_0::DebugInfo::Architecture; 342705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong static std::vector<std::pair<Arch, std::vector<const char *>>> sAllPaths{ 343705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong {Arch::IS_64BIT, {HAL_LIBRARY_PATH_ODM_64BIT, 344705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong HAL_LIBRARY_PATH_VENDOR_64BIT, 345705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong HAL_LIBRARY_PATH_SYSTEM_64BIT}}, 346705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong {Arch::IS_32BIT, {HAL_LIBRARY_PATH_ODM_32BIT, 347705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong HAL_LIBRARY_PATH_VENDOR_32BIT, 348705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong HAL_LIBRARY_PATH_SYSTEM_32BIT}} 349705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong }; 350705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong std::vector<InstanceDebugInfo> vec; 351705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong for (const auto &pair : sAllPaths) { 352705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong Arch arch = pair.first; 353705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong for (const auto &path : pair.second) { 354705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong std::vector<std::string> libs = search(path, "", ".so"); 355705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong for (const std::string &lib : libs) { 356705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong std::string matchedName; 357705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong if (matchPackageName(lib, &matchedName)) { 358705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong vec.push_back({ 359705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong .interfaceName = matchedName, 360705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong .instanceName = "*", 361705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong .clientPids = {}, 362705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong .arch = arch 363705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong }); 364705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong } 365705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong } 366705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong } 367705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong } 368705e5da46d6f6fa5a2177afe460304668bd9102cYifan Hong _hidl_cb(vec); 3697f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong return Void(); 3707f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong } 3717f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong 372af4aba557ba4a7f9fe22a23ad6e26476737f824aMartijn Coenen Return<void> registerPassthroughClient(const hidl_string &, const hidl_string &) override { 3737f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong // This makes no sense. 3747f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong LOG(FATAL) << "Cannot call registerPassthroughClient on passthrough service manager. " 3757f49f59f349b9d097c6ab533b4a20090d0bc5740Yifan Hong << "Call it on defaultServiceManager() instead."; 3769a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong return Void(); 3779a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong } 3789a22d1db4dca94f205e25105a3d822dd179d3b53Yifan Hong 379337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland}; 380337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 381337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Morelandsp<IServiceManager> getPassthroughServiceManager() { 382337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland static sp<PassthroughServiceManager> manager(new PassthroughServiceManager()); 383337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland return manager; 384337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland} 385337e6b61c4fc3a7ba76862662117c17496a1f8a2Steven Moreland 386cbefd35d5c607fa245855ce897ae08369e667222Steven Morelandnamespace details { 387cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 388cbefd35d5c607fa245855ce897ae08369e667222Steven Morelandstruct Waiter : IServiceNotification { 389cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland Return<void> onRegistration(const hidl_string& /* fqName */, 390cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland const hidl_string& /* name */, 391cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland bool /* preexisting */) override { 392cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland std::unique_lock<std::mutex> lock(mMutex); 393cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland if (mRegistered) { 394cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland return Void(); 395cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland } 396cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland mRegistered = true; 397cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland lock.unlock(); 398cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 399cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland mCondition.notify_one(); 400cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland return Void(); 401cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland } 402cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 403496051047ce92b23c1027fe77242f386fae940c4Steven Moreland void wait(const std::string &interface, const std::string &instanceName) { 404496051047ce92b23c1027fe77242f386fae940c4Steven Moreland using std::literals::chrono_literals::operator""s; 405496051047ce92b23c1027fe77242f386fae940c4Steven Moreland 406cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland std::unique_lock<std::mutex> lock(mMutex); 407496051047ce92b23c1027fe77242f386fae940c4Steven Moreland while(true) { 408496051047ce92b23c1027fe77242f386fae940c4Steven Moreland mCondition.wait_for(lock, 1s, [this]{ 409496051047ce92b23c1027fe77242f386fae940c4Steven Moreland return mRegistered; 410496051047ce92b23c1027fe77242f386fae940c4Steven Moreland }); 411496051047ce92b23c1027fe77242f386fae940c4Steven Moreland 412496051047ce92b23c1027fe77242f386fae940c4Steven Moreland if (mRegistered) { 413496051047ce92b23c1027fe77242f386fae940c4Steven Moreland break; 414496051047ce92b23c1027fe77242f386fae940c4Steven Moreland } 415496051047ce92b23c1027fe77242f386fae940c4Steven Moreland 416496051047ce92b23c1027fe77242f386fae940c4Steven Moreland LOG(WARNING) << "Waited one second for " 417496051047ce92b23c1027fe77242f386fae940c4Steven Moreland << interface << "/" << instanceName 418496051047ce92b23c1027fe77242f386fae940c4Steven Moreland << ". Waiting another..."; 419496051047ce92b23c1027fe77242f386fae940c4Steven Moreland } 420cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland } 421cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 422cbefd35d5c607fa245855ce897ae08369e667222Steven Morelandprivate: 423cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland std::mutex mMutex; 424cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland std::condition_variable mCondition; 425cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland bool mRegistered = false; 426cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland}; 427cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 428cbefd35d5c607fa245855ce897ae08369e667222Steven Morelandvoid waitForHwService( 429cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland const std::string &interface, const std::string &instanceName) { 430cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland const sp<IServiceManager> manager = defaultServiceManager(); 431cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 432cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland if (manager == nullptr) { 433cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland LOG(ERROR) << "Could not get default service manager."; 434cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland return; 435cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland } 436cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 437cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland sp<Waiter> waiter = new Waiter(); 438cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland Return<bool> ret = manager->registerForNotifications(interface, instanceName, waiter); 439cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 440cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland if (!ret.isOk()) { 441cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland LOG(ERROR) << "Transport error, " << ret.description() 442cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland << ", during notification registration for " 443cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland << interface << "/" << instanceName << "."; 444cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland return; 445cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland } 446cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 447cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland if (!ret) { 448cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland LOG(ERROR) << "Could not register for notifications for " 449cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland << interface << "/" << instanceName << "."; 450cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland return; 451cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland } 452cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 453496051047ce92b23c1027fe77242f386fae940c4Steven Moreland waiter->wait(interface, instanceName); 454cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland} 455cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 456cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland}; // namespace details 457cbefd35d5c607fa245855ce897ae08369e667222Steven Moreland 4585d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland}; // namespace hardware 4595d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland}; // namespace android 460