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 30 #include <hidl/HidlBinderSupport.h> 31 #include <hidl/ServiceManagement.h> 32 #include <hidl/Status.h> 33 34 #include <android-base/logging.h> 35 #include <android-base/properties.h> 36 #include <hwbinder/IPCThreadState.h> 37 #include <hwbinder/Parcel.h> 38 39 #include <android/hidl/manager/1.0/IServiceManager.h> 40 #include <android/hidl/manager/1.0/BpHwServiceManager.h> 41 #include <android/hidl/manager/1.0/BnHwServiceManager.h> 42 43 #define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*" 44 #define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*" 45 static const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so"); 46 47 extern "C" { 48 android_namespace_t* android_get_exported_namespace(const char*); 49 } 50 51 using android::base::WaitForProperty; 52 53 using android::hidl::manager::V1_0::IServiceManager; 54 using android::hidl::manager::V1_0::IServiceNotification; 55 using android::hidl::manager::V1_0::BpHwServiceManager; 56 using android::hidl::manager::V1_0::BnHwServiceManager; 57 58 namespace android { 59 namespace hardware { 60 61 namespace details { 62 extern Mutex gDefaultServiceManagerLock; 63 extern sp<android::hidl::manager::V1_0::IServiceManager> gDefaultServiceManager; 64 } // namespace details 65 66 static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready"; 67 68 void waitForHwServiceManager() { 69 using std::literals::chrono_literals::operator""s; 70 71 while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) { 72 LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another..."; 73 } 74 } 75 76 bool endsWith(const std::string &in, const std::string &suffix) { 77 return in.size() >= suffix.size() && 78 in.substr(in.size() - suffix.size()) == suffix; 79 } 80 81 bool startsWith(const std::string &in, const std::string &prefix) { 82 return in.size() >= prefix.size() && 83 in.substr(0, prefix.size()) == prefix; 84 } 85 86 std::string binaryName() { 87 std::ifstream ifs("/proc/self/cmdline"); 88 std::string cmdline; 89 if (!ifs.is_open()) { 90 return ""; 91 } 92 ifs >> cmdline; 93 94 size_t idx = cmdline.rfind("/"); 95 if (idx != std::string::npos) { 96 cmdline = cmdline.substr(idx + 1); 97 } 98 99 return cmdline; 100 } 101 102 void tryShortenProcessName(const std::string &packageName) { 103 std::string processName = binaryName(); 104 105 if (!startsWith(processName, packageName)) { 106 return; 107 } 108 109 // e.x. android.hardware.module.foo (at) 1.0 -> foo (at) 1.0 110 size_t lastDot = packageName.rfind('.'); 111 size_t secondDot = packageName.rfind('.', lastDot - 1); 112 113 if (secondDot == std::string::npos) { 114 return; 115 } 116 117 std::string newName = processName.substr(secondDot + 1, 118 16 /* TASK_COMM_LEN */ - 1); 119 ALOGI("Removing namespace from process name %s to %s.", 120 processName.c_str(), newName.c_str()); 121 122 int rc = pthread_setname_np(pthread_self(), newName.c_str()); 123 ALOGI_IF(rc != 0, "Removing namespace from process name %s failed.", 124 processName.c_str()); 125 } 126 127 namespace details { 128 129 void onRegistration(const std::string &packageName, 130 const std::string& /* interfaceName */, 131 const std::string& /* instanceName */) { 132 tryShortenProcessName(packageName); 133 } 134 135 } // details 136 137 sp<IServiceManager> defaultServiceManager() { 138 { 139 AutoMutex _l(details::gDefaultServiceManagerLock); 140 if (details::gDefaultServiceManager != NULL) { 141 return details::gDefaultServiceManager; 142 } 143 144 if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) { 145 // HwBinder not available on this device or not accessible to 146 // this process. 147 return nullptr; 148 } 149 150 waitForHwServiceManager(); 151 152 while (details::gDefaultServiceManager == NULL) { 153 details::gDefaultServiceManager = 154 fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>( 155 ProcessState::self()->getContextObject(NULL)); 156 if (details::gDefaultServiceManager == NULL) { 157 LOG(ERROR) << "Waited for hwservicemanager, but got nullptr."; 158 sleep(1); 159 } 160 } 161 } 162 163 return details::gDefaultServiceManager; 164 } 165 166 std::vector<std::string> search(const std::string &path, 167 const std::string &prefix, 168 const std::string &suffix) { 169 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir); 170 if (!dir) return {}; 171 172 std::vector<std::string> results{}; 173 174 dirent* dp; 175 while ((dp = readdir(dir.get())) != nullptr) { 176 std::string name = dp->d_name; 177 178 if (startsWith(name, prefix) && 179 endsWith(name, suffix)) { 180 results.push_back(name); 181 } 182 } 183 184 return results; 185 } 186 187 bool matchPackageName(const std::string &lib, std::string *matchedName) { 188 std::smatch match; 189 if (std::regex_match(lib, match, gLibraryFileNamePattern)) { 190 *matchedName = match.str(1) + "::I*"; 191 return true; 192 } 193 return false; 194 } 195 196 static void registerReference(const hidl_string &interfaceName, const hidl_string &instanceName) { 197 sp<IServiceManager> binderizedManager = defaultServiceManager(); 198 if (binderizedManager == nullptr) { 199 LOG(WARNING) << "Could not registerReference for " 200 << interfaceName << "/" << instanceName 201 << ": null binderized manager."; 202 return; 203 } 204 auto ret = binderizedManager->registerPassthroughClient(interfaceName, instanceName); 205 if (!ret.isOk()) { 206 LOG(WARNING) << "Could not registerReference for " 207 << interfaceName << "/" << instanceName 208 << ": " << ret.description(); 209 return; 210 } 211 LOG(VERBOSE) << "Successfully registerReference for " 212 << interfaceName << "/" << instanceName; 213 } 214 215 struct PassthroughServiceManager : IServiceManager { 216 Return<sp<IBase>> get(const hidl_string& fqName, 217 const hidl_string& name) override { 218 std::string stdFqName(fqName.c_str()); 219 220 //fqName looks like android.hardware.foo (at) 1.0::IFoo 221 size_t idx = stdFqName.find("::"); 222 223 if (idx == std::string::npos || 224 idx + strlen("::") + 1 >= stdFqName.size()) { 225 LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName; 226 return nullptr; 227 } 228 229 std::string packageAndVersion = stdFqName.substr(0, idx); 230 std::string ifaceName = stdFqName.substr(idx + strlen("::")); 231 232 const std::string prefix = packageAndVersion + "-impl"; 233 const std::string sym = "HIDL_FETCH_" + ifaceName; 234 235 const android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal"); 236 const int dlMode = RTLD_LAZY; 237 void *handle = nullptr; 238 239 // TODO: lookup in VINTF instead 240 // TODO(b/34135607): Remove HAL_LIBRARY_PATH_SYSTEM 241 242 dlerror(); // clear 243 244 for (const std::string &path : { 245 HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM 246 }) { 247 std::vector<std::string> libs = search(path, prefix, ".so"); 248 249 for (const std::string &lib : libs) { 250 const std::string fullPath = path + lib; 251 252 // If sphal namespace is available, try to load from the 253 // namespace first. If it fails, fall back to the original 254 // dlopen, which loads from the current namespace. 255 if (sphal_namespace != nullptr && path != HAL_LIBRARY_PATH_SYSTEM) { 256 const android_dlextinfo dlextinfo = { 257 .flags = ANDROID_DLEXT_USE_NAMESPACE, 258 // const_cast is dirty but required because 259 // library_namespace field is non-const. 260 .library_namespace = const_cast<android_namespace_t*>(sphal_namespace), 261 }; 262 handle = android_dlopen_ext(fullPath.c_str(), dlMode, &dlextinfo); 263 if (handle == nullptr) { 264 const char* error = dlerror(); 265 LOG(WARNING) << "Failed to dlopen " << lib << " from sphal namespace:" 266 << (error == nullptr ? "unknown error" : error); 267 } else { 268 LOG(DEBUG) << lib << " loaded from sphal namespace."; 269 } 270 } 271 if (handle == nullptr) { 272 handle = dlopen(fullPath.c_str(), dlMode); 273 } 274 275 if (handle == nullptr) { 276 const char* error = dlerror(); 277 LOG(ERROR) << "Failed to dlopen " << lib << ": " 278 << (error == nullptr ? "unknown error" : error); 279 continue; 280 } 281 282 IBase* (*generator)(const char* name); 283 *(void **)(&generator) = dlsym(handle, sym.c_str()); 284 if(!generator) { 285 const char* error = dlerror(); 286 LOG(ERROR) << "Passthrough lookup opened " << lib 287 << " but could not find symbol " << sym << ": " 288 << (error == nullptr ? "unknown error" : error); 289 dlclose(handle); 290 continue; 291 } 292 293 IBase *interface = (*generator)(name.c_str()); 294 295 if (interface == nullptr) { 296 dlclose(handle); 297 continue; // this module doesn't provide this instance name 298 } 299 300 registerReference(fqName, name); 301 302 return interface; 303 } 304 } 305 306 return nullptr; 307 } 308 309 Return<bool> add(const hidl_string& /* name */, 310 const sp<IBase>& /* service */) override { 311 LOG(FATAL) << "Cannot register services with passthrough service manager."; 312 return false; 313 } 314 315 Return<Transport> getTransport(const hidl_string& /* fqName */, 316 const hidl_string& /* name */) { 317 LOG(FATAL) << "Cannot getTransport with passthrough service manager."; 318 return Transport::EMPTY; 319 } 320 321 Return<void> list(list_cb /* _hidl_cb */) override { 322 LOG(FATAL) << "Cannot list services with passthrough service manager."; 323 return Void(); 324 } 325 Return<void> listByInterface(const hidl_string& /* fqInstanceName */, 326 listByInterface_cb /* _hidl_cb */) override { 327 // TODO: add this functionality 328 LOG(FATAL) << "Cannot list services with passthrough service manager."; 329 return Void(); 330 } 331 332 Return<bool> registerForNotifications(const hidl_string& /* fqName */, 333 const hidl_string& /* name */, 334 const sp<IServiceNotification>& /* callback */) override { 335 // This makes no sense. 336 LOG(FATAL) << "Cannot register for notifications with passthrough service manager."; 337 return false; 338 } 339 340 Return<void> debugDump(debugDump_cb _hidl_cb) override { 341 using Arch = ::android::hidl::base::V1_0::DebugInfo::Architecture; 342 static std::vector<std::pair<Arch, std::vector<const char *>>> sAllPaths{ 343 {Arch::IS_64BIT, {HAL_LIBRARY_PATH_ODM_64BIT, 344 HAL_LIBRARY_PATH_VENDOR_64BIT, 345 HAL_LIBRARY_PATH_SYSTEM_64BIT}}, 346 {Arch::IS_32BIT, {HAL_LIBRARY_PATH_ODM_32BIT, 347 HAL_LIBRARY_PATH_VENDOR_32BIT, 348 HAL_LIBRARY_PATH_SYSTEM_32BIT}} 349 }; 350 std::vector<InstanceDebugInfo> vec; 351 for (const auto &pair : sAllPaths) { 352 Arch arch = pair.first; 353 for (const auto &path : pair.second) { 354 std::vector<std::string> libs = search(path, "", ".so"); 355 for (const std::string &lib : libs) { 356 std::string matchedName; 357 if (matchPackageName(lib, &matchedName)) { 358 vec.push_back({ 359 .interfaceName = matchedName, 360 .instanceName = "*", 361 .clientPids = {}, 362 .arch = arch 363 }); 364 } 365 } 366 } 367 } 368 _hidl_cb(vec); 369 return Void(); 370 } 371 372 Return<void> registerPassthroughClient(const hidl_string &, const hidl_string &) override { 373 // This makes no sense. 374 LOG(FATAL) << "Cannot call registerPassthroughClient on passthrough service manager. " 375 << "Call it on defaultServiceManager() instead."; 376 return Void(); 377 } 378 379 }; 380 381 sp<IServiceManager> getPassthroughServiceManager() { 382 static sp<PassthroughServiceManager> manager(new PassthroughServiceManager()); 383 return manager; 384 } 385 386 namespace details { 387 388 struct Waiter : IServiceNotification { 389 Return<void> onRegistration(const hidl_string& /* fqName */, 390 const hidl_string& /* name */, 391 bool /* preexisting */) override { 392 std::unique_lock<std::mutex> lock(mMutex); 393 if (mRegistered) { 394 return Void(); 395 } 396 mRegistered = true; 397 lock.unlock(); 398 399 mCondition.notify_one(); 400 return Void(); 401 } 402 403 void wait(const std::string &interface, const std::string &instanceName) { 404 using std::literals::chrono_literals::operator""s; 405 406 std::unique_lock<std::mutex> lock(mMutex); 407 while(true) { 408 mCondition.wait_for(lock, 1s, [this]{ 409 return mRegistered; 410 }); 411 412 if (mRegistered) { 413 break; 414 } 415 416 LOG(WARNING) << "Waited one second for " 417 << interface << "/" << instanceName 418 << ". Waiting another..."; 419 } 420 } 421 422 private: 423 std::mutex mMutex; 424 std::condition_variable mCondition; 425 bool mRegistered = false; 426 }; 427 428 void waitForHwService( 429 const std::string &interface, const std::string &instanceName) { 430 const sp<IServiceManager> manager = defaultServiceManager(); 431 432 if (manager == nullptr) { 433 LOG(ERROR) << "Could not get default service manager."; 434 return; 435 } 436 437 sp<Waiter> waiter = new Waiter(); 438 Return<bool> ret = manager->registerForNotifications(interface, instanceName, waiter); 439 440 if (!ret.isOk()) { 441 LOG(ERROR) << "Transport error, " << ret.description() 442 << ", during notification registration for " 443 << interface << "/" << instanceName << "."; 444 return; 445 } 446 447 if (!ret) { 448 LOG(ERROR) << "Could not register for notifications for " 449 << interface << "/" << instanceName << "."; 450 return; 451 } 452 453 waiter->wait(interface, instanceName); 454 } 455 456 }; // namespace details 457 458 }; // namespace hardware 459 }; // namespace android 460