blob: 01f83bdf9aecac6172e696618f20db70bf2514f2 [file] [log] [blame]
Steven Moreland5d5ef7f2016-10-20 19:19:55 -07001/*
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
Jiyong Park3ab546c2017-04-06 20:28:07 +090019#include <android/dlext.h>
Yifan Hong9a22d1d2017-01-25 14:19:26 -080020#include <condition_variable>
21#include <dlfcn.h>
22#include <dirent.h>
Steven Moreland405d7612017-04-07 20:31:22 -070023#include <fstream>
24#include <pthread.h>
Yifan Hong9a22d1d2017-01-25 14:19:26 -080025#include <unistd.h>
26
27#include <mutex>
28#include <regex>
Yifan Hongbd0d8f72017-05-24 19:43:51 -070029#include <set>
Yifan Hong9a22d1d2017-01-25 14:19:26 -080030
Martijn Coenen12f04d92016-12-07 17:29:41 +010031#include <hidl/HidlBinderSupport.h>
Justin Yun1f048102017-12-01 15:30:08 +090032#include <hidl/HidlInternal.h>
Steven Morelande69e8d32018-03-14 10:55:42 -070033#include <hidl/HidlTransportUtils.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070034#include <hidl/ServiceManagement.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070035#include <hidl/Status.h>
36
Steven Moreland337e6b62017-01-18 17:25:13 -080037#include <android-base/logging.h>
Steven Morelandc1cee2c2017-03-24 16:23:11 +000038#include <android-base/properties.h>
Justin Yun1f048102017-12-01 15:30:08 +090039#include <android-base/stringprintf.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070040#include <hwbinder/IPCThreadState.h>
41#include <hwbinder/Parcel.h>
Jiyong Parkba8ace12017-05-15 15:44:39 +090042#include <vndksupport/linker.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070043
Steven Moreland2a2678e2017-07-21 18:07:38 -070044#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>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070047
Yifan Hong9a22d1d2017-01-25 14:19:26 -080048#define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*"
49#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
50static const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so");
51
Steven Morelandc1cee2c2017-03-24 16:23:11 +000052using android::base::WaitForProperty;
53
Steven Moreland2a2678e2017-07-21 18:07:38 -070054using IServiceManager1_0 = android::hidl::manager::V1_0::IServiceManager;
55using IServiceManager1_1 = android::hidl::manager::V1_1::IServiceManager;
Steven Moreland337e6b62017-01-18 17:25:13 -080056using android::hidl::manager::V1_0::IServiceNotification;
Steven Moreland2a2678e2017-07-21 18:07:38 -070057using android::hidl::manager::V1_1::BpHwServiceManager;
58using android::hidl::manager::V1_1::BnHwServiceManager;
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070059
60namespace android {
61namespace hardware {
62
Yifan Hong953e6b02017-03-16 14:52:40 -070063namespace details {
64extern Mutex gDefaultServiceManagerLock;
Steven Moreland2a2678e2017-07-21 18:07:38 -070065extern sp<android::hidl::manager::V1_1::IServiceManager> gDefaultServiceManager;
Yifan Hong953e6b02017-03-16 14:52:40 -070066} // namespace details
67
Steven Morelandc1cee2c2017-03-24 16:23:11 +000068static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready";
69
70void 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
Steven Moreland405d7612017-04-07 20:31:22 -070078bool endsWith(const std::string &in, const std::string &suffix) {
79 return in.size() >= suffix.size() &&
80 in.substr(in.size() - suffix.size()) == suffix;
81}
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070082
Steven Moreland405d7612017-04-07 20:31:22 -070083bool startsWith(const std::string &in, const std::string &prefix) {
84 return in.size() >= prefix.size() &&
85 in.substr(0, prefix.size()) == prefix;
86}
87
88std::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
Chih-Hung Hsieh41649d52017-08-03 14:27:21 -070096 size_t idx = cmdline.rfind('/');
Steven Moreland405d7612017-04-07 20:31:22 -070097 if (idx != std::string::npos) {
98 cmdline = cmdline.substr(idx + 1);
99 }
100
101 return cmdline;
102}
103
Steven Moreland7d09a402018-04-06 10:44:05 -0700104std::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
110void 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
Steven Moreland405d7612017-04-07 20:31:22 -0700114 std::string processName = binaryName();
115
Steven Moreland7d09a402018-04-06 10:44:05 -0700116 // e.x. android.hardware.foo is this package
117 if (!startsWith(packageWithoutVersion(processName), packageWithoutVersion(packageAndVersion))) {
Steven Moreland405d7612017-04-07 20:31:22 -0700118 return;
119 }
120
Steven Moreland7d09a402018-04-06 10:44:05 -0700121 // 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;
Steven Moreland405d7612017-04-07 20:31:22 -0700126
Steven Moreland7d09a402018-04-06 10:44:05 -0700127 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 }
Steven Moreland405d7612017-04-07 20:31:22 -0700152 }
Steven Moreland405d7612017-04-07 20:31:22 -0700153}
154
155namespace details {
156
157void onRegistration(const std::string &packageName,
158 const std::string& /* interfaceName */,
159 const std::string& /* instanceName */) {
160 tryShortenProcessName(packageName);
161}
162
163} // details
164
Steven Moreland2a2678e2017-07-21 18:07:38 -0700165sp<IServiceManager1_0> defaultServiceManager() {
166 return defaultServiceManager1_1();
167}
168sp<IServiceManager1_1> defaultServiceManager1_1() {
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700169 {
Yifan Hong953e6b02017-03-16 14:52:40 -0700170 AutoMutex _l(details::gDefaultServiceManagerLock);
Stephen Hinesfd9ecee2017-09-27 18:52:52 -0700171 if (details::gDefaultServiceManager != nullptr) {
Yifan Hong953e6b02017-03-16 14:52:40 -0700172 return details::gDefaultServiceManager;
Yifan Hong8fb656b2017-03-16 14:30:40 -0700173 }
Steven Moreland405d7612017-04-07 20:31:22 -0700174
Yifan Hong8fb656b2017-03-16 14:30:40 -0700175 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 }
Steven Morelandc1cee2c2017-03-24 16:23:11 +0000180
181 waitForHwServiceManager();
182
Stephen Hinesfd9ecee2017-09-27 18:52:52 -0700183 while (details::gDefaultServiceManager == nullptr) {
Yifan Hong953e6b02017-03-16 14:52:40 -0700184 details::gDefaultServiceManager =
Steven Moreland2a2678e2017-07-21 18:07:38 -0700185 fromBinder<IServiceManager1_1, BpHwServiceManager, BnHwServiceManager>(
Stephen Hinesfd9ecee2017-09-27 18:52:52 -0700186 ProcessState::self()->getContextObject(nullptr));
187 if (details::gDefaultServiceManager == nullptr) {
Steven Morelandc1cee2c2017-03-24 16:23:11 +0000188 LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700189 sleep(1);
Yifan Hong8fb656b2017-03-16 14:30:40 -0700190 }
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700191 }
192 }
193
Yifan Hong953e6b02017-03-16 14:52:40 -0700194 return details::gDefaultServiceManager;
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700195}
196
Steven Moreland0091c092017-01-20 23:15:18 +0000197std::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
Steven Moreland819c05d2017-04-06 17:24:22 -0700209 if (startsWith(name, prefix) &&
210 endsWith(name, suffix)) {
Steven Moreland0091c092017-01-20 23:15:18 +0000211 results.push_back(name);
212 }
213 }
214
215 return results;
216}
217
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700218bool matchPackageName(const std::string& lib, std::string* matchedName, std::string* implName) {
Yifan Hong9a22d1d2017-01-25 14:19:26 -0800219 std::smatch match;
220 if (std::regex_match(lib, match, gLibraryFileNamePattern)) {
221 *matchedName = match.str(1) + "::I*";
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700222 *implName = match.str(2);
Yifan Hong9a22d1d2017-01-25 14:19:26 -0800223 return true;
224 }
225 return false;
226}
227
Yifan Hong7f49f592017-02-03 15:11:44 -0800228static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) {
Steven Moreland2a2678e2017-07-21 18:07:38 -0700229 sp<IServiceManager1_0> binderizedManager = defaultServiceManager();
Yifan Hong7f49f592017-02-03 15:11:44 -0800230 if (binderizedManager == nullptr) {
231 LOG(WARNING) << "Could not registerReference for "
232 << interfaceName << "/" << instanceName
233 << ": null binderized manager.";
234 return;
235 }
Martijn Coenenaf4aba52017-04-27 09:41:13 -0700236 auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName);
Yifan Hong7f49f592017-02-03 15:11:44 -0800237 if (!ret.isOk()) {
238 LOG(WARNING) << "Could not registerReference for "
239 << interfaceName << "/" << instanceName
240 << ": " << ret.description();
Steven Moreland0aeaa782017-03-22 08:11:07 -0700241 return;
Yifan Hong7f49f592017-02-03 15:11:44 -0800242 }
Steven Morelande681aa52017-02-15 16:22:37 -0800243 LOG(VERBOSE) << "Successfully registerReference for "
244 << interfaceName << "/" << instanceName;
Yifan Hong7f49f592017-02-03 15:11:44 -0800245}
246
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700247using InstanceDebugInfo = hidl::manager::V1_0::IServiceManager::InstanceDebugInfo;
248static 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) {
Stephen Hinesfd9ecee2017-09-27 18:52:52 -0700257 pid_t pid = strtoll(dp->d_name, nullptr, 0);
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700258 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
Steven Moreland2a2678e2017-07-21 18:07:38 -0700285struct PassthroughServiceManager : IServiceManager1_1 {
Chih-Hung Hsieh41649d52017-08-03 14:27:21 -0700286 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) {
Steven Moreland819c05d2017-04-06 17:24:22 -0700290 //fqName looks like android.hardware.foo@1.0::IFoo
Steven Moreland519306f2017-06-06 17:14:12 -0700291 size_t idx = fqName.find("::");
Steven Moreland819c05d2017-04-06 17:24:22 -0700292
293 if (idx == std::string::npos ||
Steven Moreland519306f2017-06-06 17:14:12 -0700294 idx + strlen("::") + 1 >= fqName.size()) {
Steven Moreland337e6b62017-01-18 17:25:13 -0800295 LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
Steven Moreland519306f2017-06-06 17:14:12 -0700296 return;
Steven Moreland337e6b62017-01-18 17:25:13 -0800297 }
298
Steven Moreland519306f2017-06-06 17:14:12 -0700299 std::string packageAndVersion = fqName.substr(0, idx);
300 std::string ifaceName = fqName.substr(idx + strlen("::"));
Steven Moreland819c05d2017-04-06 17:24:22 -0700301
302 const std::string prefix = packageAndVersion + "-impl";
303 const std::string sym = "HIDL_FETCH_" + ifaceName;
Steven Moreland348802d2017-02-23 12:48:55 -0800304
Steven Moreland77f4c852017-10-12 11:05:53 -0700305 constexpr int dlMode = RTLD_LAZY;
306 void* handle = nullptr;
Steven Moreland337e6b62017-01-18 17:25:13 -0800307
Steven Morelanda29905c2017-03-01 10:42:35 -0800308 dlerror(); // clear
309
Justin Yun1f048102017-12-01 15:30:08 +0900310 static std::string halLibPathVndkSp = android::base::StringPrintf(
311 HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
Steven Morelandf7dea692017-07-14 12:49:28 -0700312 std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
Justin Yun1f048102017-12-01 15:30:08 +0900313 halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};
Steven Moreland77f4c852017-10-12 11:05:53 -0700314
Steven Morelandf7dea692017-07-14 12:49:28 -0700315#ifdef LIBHIDL_TARGET_DEBUGGABLE
316 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
317 const bool trebleTestingOverride = env && !strcmp(env, "true");
318 if (trebleTestingOverride) {
Steven Moreland77f4c852017-10-12 11:05:53 -0700319 // 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
Steven Morelandf7dea692017-07-14 12:49:28 -0700329 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;
Steven Moreland77f4c852017-10-12 11:05:53 -0700333 paths.insert(paths.begin(), halLibraryPathVtsOverride);
Steven Morelandf7dea692017-07-14 12:49:28 -0700334 }
335 }
336#endif
Steven Moreland77f4c852017-10-12 11:05:53 -0700337
Steven Morelandf7dea692017-07-14 12:49:28 -0700338 for (const std::string& path : paths) {
Steven Moreland0091c092017-01-20 23:15:18 +0000339 std::vector<std::string> libs = search(path, prefix, ".so");
340
Steven Moreland0091c092017-01-20 23:15:18 +0000341 for (const std::string &lib : libs) {
Steven Moreland348802d2017-02-23 12:48:55 -0800342 const std::string fullPath = path + lib;
343
Steven Moreland65c00cb2017-10-12 11:35:22 -0700344 if (path == HAL_LIBRARY_PATH_SYSTEM) {
Jiyong Park3ab546c2017-04-06 20:28:07 +0900345 handle = dlopen(fullPath.c_str(), dlMode);
Steven Moreland65c00cb2017-10-12 11:35:22 -0700346 } else {
347 handle = android_load_sphal_library(fullPath.c_str(), dlMode);
Jiyong Park3ab546c2017-04-06 20:28:07 +0900348 }
349
Steven Moreland348802d2017-02-23 12:48:55 -0800350 if (handle == nullptr) {
351 const char* error = dlerror();
352 LOG(ERROR) << "Failed to dlopen " << lib << ": "
353 << (error == nullptr ? "unknown error" : error);
354 continue;
Steven Moreland0091c092017-01-20 23:15:18 +0000355 }
Steven Moreland348802d2017-02-23 12:48:55 -0800356
Steven Moreland519306f2017-06-06 17:14:12 -0700357 if (!eachLib(handle, lib, sym)) {
358 return;
Steven Moreland348802d2017-02-23 12:48:55 -0800359 }
Steven Moreland337e6b62017-01-18 17:25:13 -0800360 }
361 }
Steven Moreland519306f2017-06-06 17:14:12 -0700362 }
Steven Moreland337e6b62017-01-18 17:25:13 -0800363
Steven Moreland519306f2017-06-06 17:14:12 -0700364 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
Steven Morelande69e8d32018-03-14 10:55:42 -0700387 // 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);
Steven Moreland519306f2017-06-06 17:14:12 -0700393 return false;
394 });
395
396 return ret;
Steven Moreland337e6b62017-01-18 17:25:13 -0800397 }
398
Martijn Coenen67a02492017-03-06 13:04:48 +0100399 Return<bool> add(const hidl_string& /* name */,
Steven Moreland337e6b62017-01-18 17:25:13 -0800400 const sp<IBase>& /* service */) override {
401 LOG(FATAL) << "Cannot register services with passthrough service manager.";
402 return false;
403 }
404
Steven Morelandc601c5f2017-04-06 09:26:07 -0700405 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
Yifan Hong705e5da2017-03-02 16:59:39 -0800411 Return<void> list(list_cb /* _hidl_cb */) override {
412 LOG(FATAL) << "Cannot list services with passthrough service manager.";
Steven Moreland337e6b62017-01-18 17:25:13 -0800413 return Void();
414 }
415 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
422 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
Yifan Hong705e5da2017-03-02 16:59:39 -0800430 Return<void> debugDump(debugDump_cb _hidl_cb) override {
431 using Arch = ::android::hidl::base::V1_0::DebugInfo::Architecture;
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700432 using std::literals::string_literals::operator""s;
Justin Yun1f048102017-12-01 15:30:08 +0900433 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());
Jiyong Park56eb1492017-08-04 16:16:13 +0900437 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,
Justin Yun1f048102017-12-01 15:30:08 +0900440 halLibPathVndkSp64.c_str(), HAL_LIBRARY_PATH_SYSTEM_64BIT}},
Jiyong Park56eb1492017-08-04 16:16:13 +0900441 {Arch::IS_32BIT,
442 {HAL_LIBRARY_PATH_ODM_32BIT, HAL_LIBRARY_PATH_VENDOR_32BIT,
Justin Yun1f048102017-12-01 15:30:08 +0900443 halLibPathVndkSp32.c_str(), HAL_LIBRARY_PATH_SYSTEM_32BIT}}};
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700444 std::map<std::string, InstanceDebugInfo> map;
Yifan Hong705e5da2017-03-02 16:59:39 -0800445 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;
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700451 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});
Yifan Hong705e5da2017-03-02 16:59:39 -0800459 }
460 }
461 }
462 }
Yifan Hongbd0d8f72017-05-24 19:43:51 -0700463 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 }
Yifan Hong705e5da2017-03-02 16:59:39 -0800470 _hidl_cb(vec);
Yifan Hong7f49f592017-02-03 15:11:44 -0800471 return Void();
472 }
473
Martijn Coenenaf4aba52017-04-27 09:41:13 -0700474 Return<void> registerPassthroughClient(const hidl_string &, const hidl_string &) override {
Yifan Hong7f49f592017-02-03 15:11:44 -0800475 // This makes no sense.
476 LOG(FATAL) << "Cannot call registerPassthroughClient on passthrough service manager. "
477 << "Call it on defaultServiceManager() instead.";
Yifan Hong9a22d1d2017-01-25 14:19:26 -0800478 return Void();
479 }
480
Steven Moreland2a2678e2017-07-21 18:07:38 -0700481 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
Steven Moreland337e6b62017-01-18 17:25:13 -0800489};
490
Steven Moreland2a2678e2017-07-21 18:07:38 -0700491sp<IServiceManager1_0> getPassthroughServiceManager() {
492 return getPassthroughServiceManager1_1();
493}
494sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
Steven Moreland337e6b62017-01-18 17:25:13 -0800495 static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
496 return manager;
497}
498
Steven Morelandcbefd352017-01-23 20:29:05 -0800499namespace details {
500
Steven Moreland519306f2017-06-06 17:14:12 -0700501void 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
Steven Morelandcbefd352017-01-23 20:29:05 -0800509struct Waiter : IServiceNotification {
Martijn Coenen773609e2017-10-24 09:57:53 +0200510 Waiter(const std::string& interface, const std::string& instanceName,
511 const sp<IServiceManager1_1>& sm) : mInterfaceName(interface),
512 mInstanceName(instanceName), mSm(sm) {
Martijn Coenene6cdfd32017-11-13 14:03:05 +0100513 }
514
515 void onFirstRef() override {
Martijn Coenenb88ae7f2017-10-24 11:45:41 +0200516 // 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.
Tobias Lindskog88e886f2018-01-05 10:32:43 +0100520 if (IPCThreadState::self()->isOnlyBinderThread()) {
Martijn Coenenb88ae7f2017-10-24 11:45:41 +0200521 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
Martijn Coenene6cdfd32017-11-13 14:03:05 +0100527 Return<bool> ret = mSm->registerForNotifications(mInterfaceName, mInstanceName, this);
Martijn Coenen773609e2017-10-24 09:57:53 +0200528
529 if (!ret.isOk()) {
530 LOG(ERROR) << "Transport error, " << ret.description()
Martijn Coenene6cdfd32017-11-13 14:03:05 +0100531 << ", during notification registration for " << mInterfaceName << "/"
532 << mInstanceName << ".";
Martijn Coenen773609e2017-10-24 09:57:53 +0200533 return;
534 }
535
536 if (!ret) {
Martijn Coenene6cdfd32017-11-13 14:03:05 +0100537 LOG(ERROR) << "Could not register for notifications for " << mInterfaceName << "/"
538 << mInstanceName << ".";
Martijn Coenen773609e2017-10-24 09:57:53 +0200539 return;
540 }
541
542 mRegisteredForNotifications = true;
543 }
544
545 ~Waiter() {
Martijn Coenen3fa15c22018-02-10 11:30:00 +0100546 if (!mDoneCalled) {
547 LOG(FATAL)
548 << "Waiter still registered for notifications, call done() before dropping ref!";
Martijn Coenen773609e2017-10-24 09:57:53 +0200549 }
550 }
551
Steven Morelandcbefd352017-01-23 20:29:05 -0800552 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
Martijn Coenen773609e2017-10-24 09:57:53 +0200566 void wait() {
Steven Moreland49605102017-03-28 09:33:06 -0700567 using std::literals::chrono_literals::operator""s;
568
Martijn Coenen773609e2017-10-24 09:57:53 +0200569 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
Steven Morelandcbefd352017-01-23 20:29:05 -0800576 std::unique_lock<std::mutex> lock(mMutex);
Steven Moreland49605102017-03-28 09:33:06 -0700577 while(true) {
578 mCondition.wait_for(lock, 1s, [this]{
579 return mRegistered;
580 });
581
582 if (mRegistered) {
583 break;
584 }
585
Martijn Coenen773609e2017-10-24 09:57:53 +0200586 LOG(WARNING) << "Waited one second for " << mInterfaceName << "/" << mInstanceName
Steven Moreland49605102017-03-28 09:33:06 -0700587 << ". Waiting another...";
588 }
Steven Morelandcbefd352017-01-23 20:29:05 -0800589 }
590
Martijn Coenen773609e2017-10-24 09:57:53 +0200591 // 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.
595 void reset() {
596 std::unique_lock<std::mutex> lock(mMutex);
597 mRegistered = false;
598 }
Martijn Coenen3fa15c22018-02-10 11:30:00 +0100599
600 // done() must be called before dropping the last strong ref to the Waiter, to make
601 // sure we can properly unregister with hwservicemanager.
602 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:
Martijn Coenen773609e2017-10-24 09:57:53 +0200616 const std::string mInterfaceName;
617 const std::string mInstanceName;
618 const sp<IServiceManager1_1>& mSm;
Steven Morelandcbefd352017-01-23 20:29:05 -0800619 std::mutex mMutex;
620 std::condition_variable mCondition;
621 bool mRegistered = false;
Martijn Coenen773609e2017-10-24 09:57:53 +0200622 bool mRegisteredForNotifications = false;
Martijn Coenen3fa15c22018-02-10 11:30:00 +0100623 bool mDoneCalled = false;
Steven Morelandcbefd352017-01-23 20:29:05 -0800624};
625
626void waitForHwService(
627 const std::string &interface, const std::string &instanceName) {
Martijn Coenen773609e2017-10-24 09:57:53 +0200628 sp<Waiter> waiter = new Waiter(interface, instanceName, defaultServiceManager1_1());
629 waiter->wait();
Martijn Coenen3fa15c22018-02-10 11:30:00 +0100630 waiter->done();
Martijn Coenen773609e2017-10-24 09:57:53 +0200631}
Steven Morelandcbefd352017-01-23 20:29:05 -0800632
Martijn Coenen773609e2017-10-24 09:57:53 +0200633// 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
637bool 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;
Steven Morelandcbefd352017-01-23 20:29:05 -0800647 }
Martijn Coenen773609e2017-10-24 09:57:53 +0200648 if (castReturn.isDeadObject()) {
649 ALOGW("getService: found dead hwbinder service for %s/%s.", descriptor.c_str(),
650 instance.c_str());
651 return true;
Steven Morelandcbefd352017-01-23 20:29:05 -0800652 }
Martijn Coenen773609e2017-10-24 09:57:53 +0200653 // 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;
Steven Morelandcbefd352017-01-23 20:29:05 -0800662}
663
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200664sp<::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;
Martijn Coenend35678f2018-03-07 09:51:01 +0100670 sp<Waiter> waiter;
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200671
Martijn Coenen773609e2017-10-24 09:57:53 +0200672 const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200673 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
Steven Moreland757394b2017-12-13 14:09:24 -0800689#ifdef ENFORCE_VINTF_MANIFEST
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200690
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;
Steven Moreland757394b2017-12-13 14:09:24 -0800695#else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200696 const bool trebleTestingOverride = false;
697 const bool vintfLegacy = false;
698#endif // LIBHIDL_TARGET_DEBUGGABLE
699
Steven Moreland757394b2017-12-13 14:09:24 -0800700#else // not ENFORCE_VINTF_MANIFEST
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200701 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
702 const bool trebleTestingOverride = env && !strcmp(env, "true");
703 const bool vintfLegacy = (transport == Transport::EMPTY);
Steven Moreland757394b2017-12-13 14:09:24 -0800704#endif // ENFORCE_VINTF_MANIFEST
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200705
Steven Moreland76371242018-04-19 17:11:39 -0700706 for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
707 if (waiter == nullptr && tries > 0) {
Martijn Coenend35678f2018-03-07 09:51:01 +0100708 waiter = new Waiter(descriptor, instance, sm);
709 }
Steven Moreland76371242018-04-19 17:11:39 -0700710 if (waiter != nullptr) {
711 waiter->reset(); // don't reorder this -- see comments on reset()
712 }
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200713 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;
Martijn Coenen773609e2017-10-24 09:57:53 +0200720 if (base != nullptr) {
721 Return<bool> canCastRet =
722 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
723
724 if (canCastRet.isOk() && canCastRet) {
Steven Moreland76371242018-04-19 17:11:39 -0700725 if (waiter != nullptr) {
726 waiter->done();
727 }
Martijn Coenen773609e2017-10-24 09:57:53 +0200728 return base; // still needs to be wrapped by Bp class.
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200729 }
Martijn Coenen773609e2017-10-24 09:57:53 +0200730
731 if (!handleCastError(canCastRet, descriptor, instance)) break;
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200732 }
733
Martijn Coenen773609e2017-10-24 09:57:53 +0200734 // In case of legacy or we were not asked to retry, don't.
735 if (vintfLegacy || !retry) break;
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200736
Steven Moreland76371242018-04-19 17:11:39 -0700737 if (waiter != nullptr) {
738 ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
739 waiter->wait();
740 }
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200741 }
742
Martijn Coenend35678f2018-03-07 09:51:01 +0100743 if (waiter != nullptr) {
744 waiter->done();
745 }
Martijn Coenen3fa15c22018-02-10 11:30:00 +0100746
Martijn Coenen86c3abb2017-10-24 09:33:28 +0200747 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
Steven Morelandcbefd352017-01-23 20:29:05 -0800761}; // namespace details
762
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700763}; // namespace hardware
764}; // namespace android