ServiceManagement.cpp revision 91e3f645694514794b39a054a39a2a0087583182
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 <hidl/HidlBinderSupport.h> 20#include <hidl/ServiceManagement.h> 21#include <hidl/Static.h> 22#include <hidl/Status.h> 23 24#include <android-base/logging.h> 25#include <array> 26#include <cstdio> 27#include <dlfcn.h> 28#include <hidl-util/FQName.h> 29#include <hidl-util/StringHelper.h> 30#include <hwbinder/IPCThreadState.h> 31#include <hwbinder/Parcel.h> 32#include <iostream> 33#include <unistd.h> 34#include <vector> 35 36#include <android/hidl/manager/1.0/IServiceManager.h> 37#include <android/hidl/manager/1.0/BpHwServiceManager.h> 38#include <android/hidl/manager/1.0/BnHwServiceManager.h> 39 40using android::hidl::manager::V1_0::IServiceManager; 41using android::hidl::manager::V1_0::IServiceNotification; 42using android::hidl::manager::V1_0::BpHwServiceManager; 43using android::hidl::manager::V1_0::BnHwServiceManager; 44 45namespace android { 46namespace hardware { 47 48sp<IServiceManager> defaultServiceManager() { 49 50 if (gDefaultServiceManager != NULL) return gDefaultServiceManager; 51 if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) { 52 // HwBinder not available on this device or not accessible to 53 // this process. 54 return nullptr; 55 } 56 { 57 AutoMutex _l(gDefaultServiceManagerLock); 58 while (gDefaultServiceManager == NULL) { 59 gDefaultServiceManager = fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>( 60 ProcessState::self()->getContextObject(NULL)); 61 if (gDefaultServiceManager == NULL) 62 sleep(1); 63 } 64 } 65 66 return gDefaultServiceManager; 67} 68 69std::vector<std::string> command(const std::string &command) { 70 std::array<char, 128> buffer; 71 std::vector<std::string> results; 72 73 std::unique_ptr<FILE, std::function<decltype(pclose)>> 74 pipe(popen(command.c_str(), "r"), pclose); 75 std::string result; 76 77 while (!feof(pipe.get())) { 78 if (fgets(buffer.data(), buffer.size(), pipe.get()) == nullptr) { 79 break; 80 } 81 82 std::string partialResult(buffer.data()); 83 84 if (!partialResult.size()) { 85 LOG(ERROR) << "Command failed: " << command; 86 return {}; // this should never happen 87 } 88 89 result += partialResult; 90 91 if (result.at(result.size() - 1) != '\n') { 92 continue; // keep on reading line 93 } 94 95 result = StringHelper::RTrim(result, "\n"); 96 97 results.push_back(result); 98 result.clear(); 99 } 100 101 if (ferror(pipe.get())) { 102 LOG(ERROR) << "Command failed: " << command; 103 return {}; 104 } 105 106 return results; 107} 108 109struct PassthroughServiceManager : IServiceManager { 110 Return<sp<IBase>> get(const hidl_string& fqName, 111 const hidl_string& name) override { 112 FQName iface(fqName); 113 114 if (!iface.isValid() || 115 !iface.isFullyQualified() || 116 iface.isIdentifier()) { 117 LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName; 118 return nullptr; 119 } 120 121 const int dlMode = RTLD_LAZY; 122 void *handle = nullptr; 123 124 std::string library; 125 126 // TODO: lookup in VINTF instead 127 // TODO: warn if multiple are found 128 // TODO(b/34135607): Remove HAL_LIBRARY_PATH_SYSTEM 129 for (const std::string &path : { 130 HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM 131 }) { 132 std::string find = "find " + path + iface.getPackageAndVersion().string() 133 + "-impl*.so 2>/dev/null"; 134 135 for (const std::string &lib : command(find)) { 136 handle = dlopen(lib.c_str(), dlMode); 137 if (handle != nullptr) { 138 library = lib; 139 goto beginLookup; 140 } 141 } 142 } 143 144 if (handle == nullptr) { 145 return nullptr; 146 } 147beginLookup: 148 149 const std::string sym = "HIDL_FETCH_" + iface.name(); 150 151 IBase* (*generator)(const char* name); 152 *(void **)(&generator) = dlsym(handle, sym.c_str()); 153 if(!generator) { 154 LOG(ERROR) << "Passthrough lookup opened " << library 155 << " but could not find symbol " << sym; 156 return nullptr; 157 } 158 return (*generator)(name); 159 } 160 161 Return<bool> add(const hidl_vec<hidl_string>& /* interfaceChain */, 162 const hidl_string& /* name */, 163 const sp<IBase>& /* service */) override { 164 LOG(FATAL) << "Cannot register services with passthrough service manager."; 165 return false; 166 } 167 168 Return<void> list(list_cb /* _hidl_cb */) override { 169 // TODO: add this functionality 170 LOG(FATAL) << "Cannot list services with passthrough service manager."; 171 return Void(); 172 } 173 Return<void> listByInterface(const hidl_string& /* fqInstanceName */, 174 listByInterface_cb /* _hidl_cb */) override { 175 // TODO: add this functionality 176 LOG(FATAL) << "Cannot list services with passthrough service manager."; 177 return Void(); 178 } 179 180 Return<bool> registerForNotifications(const hidl_string& /* fqName */, 181 const hidl_string& /* name */, 182 const sp<IServiceNotification>& /* callback */) override { 183 // This makes no sense. 184 LOG(FATAL) << "Cannot register for notifications with passthrough service manager."; 185 return false; 186 } 187 188}; 189 190sp<IServiceManager> getPassthroughServiceManager() { 191 static sp<PassthroughServiceManager> manager(new PassthroughServiceManager()); 192 return manager; 193} 194 195}; // namespace hardware 196}; // namespace android 197