1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "ServiceManagement"
18
19 #include <android/dlext.h>
20 #include <condition_variable>
21 #include <dlfcn.h>
22 #include <dirent.h>
23 #include <fstream>
24 #include <pthread.h>
25 #include <unistd.h>
26
27 #include <mutex>
28 #include <regex>
29 #include <set>
30
31 #include <hidl/HidlBinderSupport.h>
32 #include <hidl/HidlInternal.h>
33 #include <hidl/HidlTransportUtils.h>
34 #include <hidl/ServiceManagement.h>
35 #include <hidl/Status.h>
36
37 #include <android-base/logging.h>
38 #include <android-base/properties.h>
39 #include <android-base/stringprintf.h>
40 #include <hwbinder/IPCThreadState.h>
41 #include <hwbinder/Parcel.h>
42 #include <vndksupport/linker.h>
43
44 #include <android/hidl/manager/1.1/IServiceManager.h>
45 #include <android/hidl/manager/1.1/BpHwServiceManager.h>
46 #include <android/hidl/manager/1.1/BnHwServiceManager.h>
47
48 #define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*"
49 #define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
50 static const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so");
51
52 using android::base::WaitForProperty;
53
54 using IServiceManager1_0 = android::hidl::manager::V1_0::IServiceManager;
55 using IServiceManager1_1 = android::hidl::manager::V1_1::IServiceManager;
56 using android::hidl::manager::V1_0::IServiceNotification;
57 using android::hidl::manager::V1_1::BpHwServiceManager;
58 using android::hidl::manager::V1_1::BnHwServiceManager;
59
60 namespace android {
61 namespace hardware {
62
63 namespace details {
64 extern Mutex gDefaultServiceManagerLock;
65 extern sp<android::hidl::manager::V1_1::IServiceManager> gDefaultServiceManager;
66 } // namespace details
67
68 static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready";
69
waitForHwServiceManager()70 void waitForHwServiceManager() {
71 using std::literals::chrono_literals::operator""s;
72
73 while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) {
74 LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another...";
75 }
76 }
77
endsWith(const std::string & in,const std::string & suffix)78 bool endsWith(const std::string &in, const std::string &suffix) {
79 return in.size() >= suffix.size() &&
80 in.substr(in.size() - suffix.size()) == suffix;
81 }
82
startsWith(const std::string & in,const std::string & prefix)83 bool startsWith(const std::string &in, const std::string &prefix) {
84 return in.size() >= prefix.size() &&
85 in.substr(0, prefix.size()) == prefix;
86 }
87
binaryName()88 std::string binaryName() {
89 std::ifstream ifs("/proc/self/cmdline");
90 std::string cmdline;
91 if (!ifs.is_open()) {
92 return "";
93 }
94 ifs >> cmdline;
95
96 size_t idx = cmdline.rfind('/');
97 if (idx != std::string::npos) {
98 cmdline = cmdline.substr(idx + 1);
99 }
100
101 return cmdline;
102 }
103
packageWithoutVersion(const std::string & packageAndVersion)104 std::string packageWithoutVersion(const std::string& packageAndVersion) {
105 size_t at = packageAndVersion.find('@');
106 if (at == std::string::npos) return packageAndVersion;
107 return packageAndVersion.substr(0, at);
108 }
109
tryShortenProcessName(const std::string & packageAndVersion)110 void tryShortenProcessName(const std::string& packageAndVersion) {
111 const static std::string kTasks = "/proc/self/task/";
112
113 // make sure that this binary name is in the same package
114 std::string processName = binaryName();
115
116 // e.x. android.hardware.foo is this package
117 if (!startsWith(packageWithoutVersion(processName), packageWithoutVersion(packageAndVersion))) {
118 return;
119 }
120
121 // e.x. android.hardware.module.foo@1.2 -> foo@1.2
122 size_t lastDot = packageAndVersion.rfind('.');
123 if (lastDot == std::string::npos) return;
124 size_t secondDot = packageAndVersion.rfind('.', lastDot - 1);
125 if (secondDot == std::string::npos) return;
126
127 std::string newName = processName.substr(secondDot + 1, std::string::npos);
128 ALOGI("Removing namespace from process name %s to %s.", processName.c_str(), newName.c_str());
129
130 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(kTasks.c_str()), closedir);
131 if (dir == nullptr) return;
132
133 dirent* dp;
134 while ((dp = readdir(dir.get())) != nullptr) {
135 if (dp->d_type != DT_DIR) continue;
136 if (dp->d_name[0] == '.') continue;
137
138 std::fstream fs(kTasks + dp->d_name + "/comm");
139 if (!fs.is_open()) {
140 ALOGI("Could not rename process, failed read comm for %s.", dp->d_name);
141 continue;
142 }
143
144 std::string oldComm;
145 fs >> oldComm;
146
147 // don't rename if it already has an explicit name
148 if (startsWith(packageAndVersion, oldComm)) {
149 fs.seekg(0, fs.beg);
150 fs << newName;
151 }
152 }
153 }
154
155 namespace details {
156
onRegistration(const std::string & packageName,const std::string &,const std::string &)157 void onRegistration(const std::string &packageName,
158 const std::string& /* interfaceName */,
159 const std::string& /* instanceName */) {
160 tryShortenProcessName(packageName);
161 }
162
163 } // details
164
defaultServiceManager()165 sp<IServiceManager1_0> defaultServiceManager() {
166 return defaultServiceManager1_1();
167 }
defaultServiceManager1_1()168 sp<IServiceManager1_1> defaultServiceManager1_1() {
169 {
170 AutoMutex _l(details::gDefaultServiceManagerLock);
171 if (details::gDefaultServiceManager != nullptr) {
172 return details::gDefaultServiceManager;
173 }
174
175 if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
176 // HwBinder not available on this device or not accessible to
177 // this process.
178 return nullptr;
179 }
180
181 waitForHwServiceManager();
182
183 while (details::gDefaultServiceManager == nullptr) {
184 details::gDefaultServiceManager =
185 fromBinder<IServiceManager1_1, BpHwServiceManager, BnHwServiceManager>(
186 ProcessState::self()->getContextObject(nullptr));
187 if (details::gDefaultServiceManager == nullptr) {
188 LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
189 sleep(1);
190 }
191 }
192 }
193
194 return details::gDefaultServiceManager;
195 }
196
search(const std::string & path,const std::string & prefix,const std::string & suffix)197 std::vector<std::string> search(const std::string &path,
198 const std::string &prefix,
199 const std::string &suffix) {
200 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
201 if (!dir) return {};
202
203 std::vector<std::string> results{};
204
205 dirent* dp;
206 while ((dp = readdir(dir.get())) != nullptr) {
207 std::string name = dp->d_name;
208
209 if (startsWith(name, prefix) &&
210 endsWith(name, suffix)) {
211 results.push_back(name);
212 }
213 }
214
215 return results;
216 }
217
matchPackageName(const std::string & lib,std::string * matchedName,std::string * implName)218 bool matchPackageName(const std::string& lib, std::string* matchedName, std::string* implName) {
219 std::smatch match;
220 if (std::regex_match(lib, match, gLibraryFileNamePattern)) {
221 *matchedName = match.str(1) + "::I*";
222 *implName = match.str(2);
223 return true;
224 }
225 return false;
226 }
227
registerReference(const hidl_string & interfaceName,const hidl_string & instanceName)228 static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) {
229 sp<IServiceManager1_0> binderizedManager = defaultServiceManager();
230 if (binderizedManager == nullptr) {
231 LOG(WARNING) << "Could not registerReference for "
232 << interfaceName << "/" << instanceName
233 << ": null binderized manager.";
234 return;
235 }
236 auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName);
237 if (!ret.isOk()) {
238 LOG(WARNING) << "Could not registerReference for "
239 << interfaceName << "/" << instanceName
240 << ": " << ret.description();
241 return;
242 }
243 LOG(VERBOSE) << "Successfully registerReference for "
244 << interfaceName << "/" << instanceName;
245 }
246
247 using InstanceDebugInfo = hidl::manager::V1_0::IServiceManager::InstanceDebugInfo;
fetchPidsForPassthroughLibraries(std::map<std::string,InstanceDebugInfo> * infos)248 static inline void fetchPidsForPassthroughLibraries(
249 std::map<std::string, InstanceDebugInfo>* infos) {
250 static const std::string proc = "/proc/";
251
252 std::map<std::string, std::set<pid_t>> pids;
253 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(proc.c_str()), closedir);
254 if (!dir) return;
255 dirent* dp;
256 while ((dp = readdir(dir.get())) != nullptr) {
257 pid_t pid = strtoll(dp->d_name, nullptr, 0);
258 if (pid == 0) continue;
259 std::string mapsPath = proc + dp->d_name + "/maps";
260 std::ifstream ifs{mapsPath};
261 if (!ifs.is_open()) continue;
262
263 for (std::string line; std::getline(ifs, line);) {
264 // The last token of line should look like
265 // vendor/lib64/hw/android.hardware.foo@1.0-impl-extra.so
266 // Use some simple filters to ignore bad lines before extracting libFileName
267 // and checking the key in info to make parsing faster.
268 if (line.back() != 'o') continue;
269 if (line.rfind('@') == std::string::npos) continue;
270
271 auto spacePos = line.rfind(' ');
272 if (spacePos == std::string::npos) continue;
273 auto libFileName = line.substr(spacePos + 1);
274 auto it = infos->find(libFileName);
275 if (it == infos->end()) continue;
276 pids[libFileName].insert(pid);
277 }
278 }
279 for (auto& pair : *infos) {
280 pair.second.clientPids =
281 std::vector<pid_t>{pids[pair.first].begin(), pids[pair.first].end()};
282 }
283 }
284
285 struct PassthroughServiceManager : IServiceManager1_1 {
openLibsandroid::hardware::PassthroughServiceManager286 static void openLibs(
287 const std::string& fqName,
288 const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
289 const std::string& /* sym */)>& eachLib) {
290 //fqName looks like android.hardware.foo@1.0::IFoo
291 size_t idx = fqName.find("::");
292
293 if (idx == std::string::npos ||
294 idx + strlen("::") + 1 >= fqName.size()) {
295 LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
296 return;
297 }
298
299 std::string packageAndVersion = fqName.substr(0, idx);
300 std::string ifaceName = fqName.substr(idx + strlen("::"));
301
302 const std::string prefix = packageAndVersion + "-impl";
303 const std::string sym = "HIDL_FETCH_" + ifaceName;
304
305 constexpr int dlMode = RTLD_LAZY;
306 void* handle = nullptr;
307
308 dlerror(); // clear
309
310 static std::string halLibPathVndkSp = android::base::StringPrintf(
311 HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
312 std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
313 halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};
314
315 #ifdef LIBHIDL_TARGET_DEBUGGABLE
316 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
317 const bool trebleTestingOverride = env && !strcmp(env, "true");
318 if (trebleTestingOverride) {
319 // Load HAL implementations that are statically linked
320 handle = dlopen(nullptr, dlMode);
321 if (handle == nullptr) {
322 const char* error = dlerror();
323 LOG(ERROR) << "Failed to dlopen self: "
324 << (error == nullptr ? "unknown error" : error);
325 } else if (!eachLib(handle, "SELF", sym)) {
326 return;
327 }
328
329 const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
330 if (vtsRootPath && strlen(vtsRootPath) > 0) {
331 const std::string halLibraryPathVtsOverride =
332 std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
333 paths.insert(paths.begin(), halLibraryPathVtsOverride);
334 }
335 }
336 #endif
337
338 for (const std::string& path : paths) {
339 std::vector<std::string> libs = search(path, prefix, ".so");
340
341 for (const std::string &lib : libs) {
342 const std::string fullPath = path + lib;
343
344 if (path == HAL_LIBRARY_PATH_SYSTEM) {
345 handle = dlopen(fullPath.c_str(), dlMode);
346 } else {
347 handle = android_load_sphal_library(fullPath.c_str(), dlMode);
348 }
349
350 if (handle == nullptr) {
351 const char* error = dlerror();
352 LOG(ERROR) << "Failed to dlopen " << lib << ": "
353 << (error == nullptr ? "unknown error" : error);
354 continue;
355 }
356
357 if (!eachLib(handle, lib, sym)) {
358 return;
359 }
360 }
361 }
362 }
363
getandroid::hardware::PassthroughServiceManager364 Return<sp<IBase>> get(const hidl_string& fqName,
365 const hidl_string& name) override {
366 sp<IBase> ret = nullptr;
367
368 openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
369 IBase* (*generator)(const char* name);
370 *(void **)(&generator) = dlsym(handle, sym.c_str());
371 if(!generator) {
372 const char* error = dlerror();
373 LOG(ERROR) << "Passthrough lookup opened " << lib
374 << " but could not find symbol " << sym << ": "
375 << (error == nullptr ? "unknown error" : error);
376 dlclose(handle);
377 return true;
378 }
379
380 ret = (*generator)(name.c_str());
381
382 if (ret == nullptr) {
383 dlclose(handle);
384 return true; // this module doesn't provide this instance name
385 }
386
387 // Actual fqname might be a subclass.
388 // This assumption is tested in vts_treble_vintf_test
389 using ::android::hardware::details::getDescriptor;
390 std::string actualFqName = getDescriptor(ret.get());
391 CHECK(actualFqName.size() > 0);
392 registerReference(actualFqName, name);
393 return false;
394 });
395
396 return ret;
397 }
398
addandroid::hardware::PassthroughServiceManager399 Return<bool> add(const hidl_string& /* name */,
400 const sp<IBase>& /* service */) override {
401 LOG(FATAL) << "Cannot register services with passthrough service manager.";
402 return false;
403 }
404
getTransportandroid::hardware::PassthroughServiceManager405 Return<Transport> getTransport(const hidl_string& /* fqName */,
406 const hidl_string& /* name */) {
407 LOG(FATAL) << "Cannot getTransport with passthrough service manager.";
408 return Transport::EMPTY;
409 }
410
listandroid::hardware::PassthroughServiceManager411 Return<void> list(list_cb /* _hidl_cb */) override {
412 LOG(FATAL) << "Cannot list services with passthrough service manager.";
413 return Void();
414 }
listByInterfaceandroid::hardware::PassthroughServiceManager415 Return<void> listByInterface(const hidl_string& /* fqInstanceName */,
416 listByInterface_cb /* _hidl_cb */) override {
417 // TODO: add this functionality
418 LOG(FATAL) << "Cannot list services with passthrough service manager.";
419 return Void();
420 }
421
registerForNotificationsandroid::hardware::PassthroughServiceManager422 Return<bool> registerForNotifications(const hidl_string& /* fqName */,
423 const hidl_string& /* name */,
424 const sp<IServiceNotification>& /* callback */) override {
425 // This makes no sense.
426 LOG(FATAL) << "Cannot register for notifications with passthrough service manager.";
427 return false;
428 }
429
debugDumpandroid::hardware::PassthroughServiceManager430 Return<void> debugDump(debugDump_cb _hidl_cb) override {
431 using Arch = ::android::hidl::base::V1_0::DebugInfo::Architecture;
432 using std::literals::string_literals::operator""s;
433 static std::string halLibPathVndkSp64 = android::base::StringPrintf(
434 HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION, details::getVndkVersionStr().c_str());
435 static std::string halLibPathVndkSp32 = android::base::StringPrintf(
436 HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION, details::getVndkVersionStr().c_str());
437 static std::vector<std::pair<Arch, std::vector<const char*>>> sAllPaths{
438 {Arch::IS_64BIT,
439 {HAL_LIBRARY_PATH_ODM_64BIT, HAL_LIBRARY_PATH_VENDOR_64BIT,
440 halLibPathVndkSp64.c_str(), HAL_LIBRARY_PATH_SYSTEM_64BIT}},
441 {Arch::IS_32BIT,
442 {HAL_LIBRARY_PATH_ODM_32BIT, HAL_LIBRARY_PATH_VENDOR_32BIT,
443 halLibPathVndkSp32.c_str(), HAL_LIBRARY_PATH_SYSTEM_32BIT}}};
444 std::map<std::string, InstanceDebugInfo> map;
445 for (const auto &pair : sAllPaths) {
446 Arch arch = pair.first;
447 for (const auto &path : pair.second) {
448 std::vector<std::string> libs = search(path, "", ".so");
449 for (const std::string &lib : libs) {
450 std::string matchedName;
451 std::string implName;
452 if (matchPackageName(lib, &matchedName, &implName)) {
453 std::string instanceName{"* ("s + path + ")"s};
454 if (!implName.empty()) instanceName += " ("s + implName + ")"s;
455 map.emplace(path + lib, InstanceDebugInfo{.interfaceName = matchedName,
456 .instanceName = instanceName,
457 .clientPids = {},
458 .arch = arch});
459 }
460 }
461 }
462 }
463 fetchPidsForPassthroughLibraries(&map);
464 hidl_vec<InstanceDebugInfo> vec;
465 vec.resize(map.size());
466 size_t idx = 0;
467 for (auto&& pair : map) {
468 vec[idx++] = std::move(pair.second);
469 }
470 _hidl_cb(vec);
471 return Void();
472 }
473
registerPassthroughClientandroid::hardware::PassthroughServiceManager474 Return<void> registerPassthroughClient(const hidl_string &, const hidl_string &) override {
475 // This makes no sense.
476 LOG(FATAL) << "Cannot call registerPassthroughClient on passthrough service manager. "
477 << "Call it on defaultServiceManager() instead.";
478 return Void();
479 }
480
unregisterForNotificationsandroid::hardware::PassthroughServiceManager481 Return<bool> unregisterForNotifications(const hidl_string& /* fqName */,
482 const hidl_string& /* name */,
483 const sp<IServiceNotification>& /* callback */) override {
484 // This makes no sense.
485 LOG(FATAL) << "Cannot unregister for notifications with passthrough service manager.";
486 return false;
487 }
488
489 };
490
getPassthroughServiceManager()491 sp<IServiceManager1_0> getPassthroughServiceManager() {
492 return getPassthroughServiceManager1_1();
493 }
getPassthroughServiceManager1_1()494 sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
495 static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
496 return manager;
497 }
498
499 namespace details {
500
preloadPassthroughService(const std::string & descriptor)501 void preloadPassthroughService(const std::string &descriptor) {
502 PassthroughServiceManager::openLibs(descriptor,
503 [&](void* /* handle */, const std::string& /* lib */, const std::string& /* sym */) {
504 // do nothing
505 return true; // open all libs
506 });
507 }
508
509 struct Waiter : IServiceNotification {
Waiterandroid::hardware::details::Waiter510 Waiter(const std::string& interface, const std::string& instanceName,
511 const sp<IServiceManager1_1>& sm) : mInterfaceName(interface),
512 mInstanceName(instanceName), mSm(sm) {
513 }
514
onFirstRefandroid::hardware::details::Waiter515 void onFirstRef() override {
516 // If this process only has one binder thread, and we're calling wait() from
517 // that thread, it will block forever because we hung up the one and only
518 // binder thread on a condition variable that can only be notified by an
519 // incoming binder call.
520 if (IPCThreadState::self()->isOnlyBinderThread()) {
521 LOG(WARNING) << "Can't efficiently wait for " << mInterfaceName << "/"
522 << mInstanceName << ", because we are called from "
523 << "the only binder thread in this process.";
524 return;
525 }
526
527 Return<bool> ret = mSm->registerForNotifications(mInterfaceName, mInstanceName, this);
528
529 if (!ret.isOk()) {
530 LOG(ERROR) << "Transport error, " << ret.description()
531 << ", during notification registration for " << mInterfaceName << "/"
532 << mInstanceName << ".";
533 return;
534 }
535
536 if (!ret) {
537 LOG(ERROR) << "Could not register for notifications for " << mInterfaceName << "/"
538 << mInstanceName << ".";
539 return;
540 }
541
542 mRegisteredForNotifications = true;
543 }
544
~Waiterandroid::hardware::details::Waiter545 ~Waiter() {
546 if (!mDoneCalled) {
547 LOG(FATAL)
548 << "Waiter still registered for notifications, call done() before dropping ref!";
549 }
550 }
551
onRegistrationandroid::hardware::details::Waiter552 Return<void> onRegistration(const hidl_string& /* fqName */,
553 const hidl_string& /* name */,
554 bool /* preexisting */) override {
555 std::unique_lock<std::mutex> lock(mMutex);
556 if (mRegistered) {
557 return Void();
558 }
559 mRegistered = true;
560 lock.unlock();
561
562 mCondition.notify_one();
563 return Void();
564 }
565
waitandroid::hardware::details::Waiter566 void wait() {
567 using std::literals::chrono_literals::operator""s;
568
569 if (!mRegisteredForNotifications) {
570 // As an alternative, just sleep for a second and return
571 LOG(WARNING) << "Waiting one second for " << mInterfaceName << "/" << mInstanceName;
572 sleep(1);
573 return;
574 }
575
576 std::unique_lock<std::mutex> lock(mMutex);
577 while(true) {
578 mCondition.wait_for(lock, 1s, [this]{
579 return mRegistered;
580 });
581
582 if (mRegistered) {
583 break;
584 }
585
586 LOG(WARNING) << "Waited one second for " << mInterfaceName << "/" << mInstanceName
587 << ". Waiting another...";
588 }
589 }
590
591 // Be careful when using this; after calling reset(), you must always try to retrieve
592 // the corresponding service before blocking on the waiter; otherwise, you might run
593 // into a race-condition where the service has just (re-)registered, you clear the state
594 // here, and subsequently calling waiter->wait() will block forever.
resetandroid::hardware::details::Waiter595 void reset() {
596 std::unique_lock<std::mutex> lock(mMutex);
597 mRegistered = false;
598 }
599
600 // done() must be called before dropping the last strong ref to the Waiter, to make
601 // sure we can properly unregister with hwservicemanager.
doneandroid::hardware::details::Waiter602 void done() {
603 if (mRegisteredForNotifications) {
604 if (!mSm->unregisterForNotifications(mInterfaceName, mInstanceName, this)
605 .withDefault(false)) {
606 LOG(ERROR) << "Could not unregister service notification for " << mInterfaceName
607 << "/" << mInstanceName << ".";
608 } else {
609 mRegisteredForNotifications = false;
610 }
611 }
612 mDoneCalled = true;
613 }
614
615 private:
616 const std::string mInterfaceName;
617 const std::string mInstanceName;
618 const sp<IServiceManager1_1>& mSm;
619 std::mutex mMutex;
620 std::condition_variable mCondition;
621 bool mRegistered = false;
622 bool mRegisteredForNotifications = false;
623 bool mDoneCalled = false;
624 };
625
waitForHwService(const std::string & interface,const std::string & instanceName)626 void waitForHwService(
627 const std::string &interface, const std::string &instanceName) {
628 sp<Waiter> waiter = new Waiter(interface, instanceName, defaultServiceManager1_1());
629 waiter->wait();
630 waiter->done();
631 }
632
633 // Prints relevant error/warning messages for error return values from
634 // details::canCastInterface(), both transaction errors (!castReturn.isOk())
635 // as well as actual cast failures (castReturn.isOk() && castReturn = false).
636 // Returns 'true' if the error is non-fatal and it's useful to retry
handleCastError(const Return<bool> & castReturn,const std::string & descriptor,const std::string & instance)637 bool handleCastError(const Return<bool>& castReturn, const std::string& descriptor,
638 const std::string& instance) {
639 if (castReturn.isOk()) {
640 if (castReturn) {
641 details::logAlwaysFatal("Successful cast value passed into handleCastError.");
642 }
643 // This should never happen, and there's not really a point in retrying.
644 ALOGE("getService: received incompatible service (bug in hwservicemanager?) for "
645 "%s/%s.", descriptor.c_str(), instance.c_str());
646 return false;
647 }
648 if (castReturn.isDeadObject()) {
649 ALOGW("getService: found dead hwbinder service for %s/%s.", descriptor.c_str(),
650 instance.c_str());
651 return true;
652 }
653 // This can happen due to:
654 // 1) No SELinux permissions
655 // 2) Other transaction failure (no buffer space, kernel error)
656 // The first isn't recoverable, but the second is.
657 // Since we can't yet differentiate between the two, and clients depend
658 // on us not blocking in case 1), treat this as a fatal error for now.
659 ALOGW("getService: unable to call into hwbinder service for %s/%s.",
660 descriptor.c_str(), instance.c_str());
661 return false;
662 }
663
getRawServiceInternal(const std::string & descriptor,const std::string & instance,bool retry,bool getStub)664 sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
665 const std::string& instance,
666 bool retry, bool getStub) {
667 using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
668 using ::android::hidl::base::V1_0::IBase;
669 using ::android::hidl::manager::V1_0::IServiceManager;
670 sp<Waiter> waiter;
671
672 const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
673 if (sm == nullptr) {
674 ALOGE("getService: defaultServiceManager() is null");
675 return nullptr;
676 }
677
678 Return<Transport> transportRet = sm->getTransport(descriptor, instance);
679
680 if (!transportRet.isOk()) {
681 ALOGE("getService: defaultServiceManager()->getTransport returns %s",
682 transportRet.description().c_str());
683 return nullptr;
684 }
685 Transport transport = transportRet;
686 const bool vintfHwbinder = (transport == Transport::HWBINDER);
687 const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
688
689 #ifdef ENFORCE_VINTF_MANIFEST
690
691 #ifdef LIBHIDL_TARGET_DEBUGGABLE
692 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
693 const bool trebleTestingOverride = env && !strcmp(env, "true");
694 const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
695 #else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
696 const bool trebleTestingOverride = false;
697 const bool vintfLegacy = false;
698 #endif // LIBHIDL_TARGET_DEBUGGABLE
699
700 #else // not ENFORCE_VINTF_MANIFEST
701 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
702 const bool trebleTestingOverride = env && !strcmp(env, "true");
703 const bool vintfLegacy = (transport == Transport::EMPTY);
704 #endif // ENFORCE_VINTF_MANIFEST
705
706 for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
707 if (waiter == nullptr && tries > 0) {
708 waiter = new Waiter(descriptor, instance, sm);
709 }
710 if (waiter != nullptr) {
711 waiter->reset(); // don't reorder this -- see comments on reset()
712 }
713 Return<sp<IBase>> ret = sm->get(descriptor, instance);
714 if (!ret.isOk()) {
715 ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
716 ret.description().c_str(), descriptor.c_str(), instance.c_str());
717 break;
718 }
719 sp<IBase> base = ret;
720 if (base != nullptr) {
721 Return<bool> canCastRet =
722 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
723
724 if (canCastRet.isOk() && canCastRet) {
725 if (waiter != nullptr) {
726 waiter->done();
727 }
728 return base; // still needs to be wrapped by Bp class.
729 }
730
731 if (!handleCastError(canCastRet, descriptor, instance)) break;
732 }
733
734 // In case of legacy or we were not asked to retry, don't.
735 if (vintfLegacy || !retry) break;
736
737 if (waiter != nullptr) {
738 ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
739 waiter->wait();
740 }
741 }
742
743 if (waiter != nullptr) {
744 waiter->done();
745 }
746
747 if (getStub || vintfPassthru || vintfLegacy) {
748 const sp<IServiceManager> pm = getPassthroughServiceManager();
749 if (pm != nullptr) {
750 sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
751 if (!getStub || trebleTestingOverride) {
752 base = wrapPassthrough(base);
753 }
754 return base;
755 }
756 }
757
758 return nullptr;
759 }
760
761 }; // namespace details
762
763 }; // namespace hardware
764 }; // namespace android
765