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