blob: 418e2c03612177b25aa52316fac0c678b5c10e61 [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
Martijn Coenen12f04d92016-12-07 17:29:41 +010019#include <hidl/HidlBinderSupport.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070020#include <hidl/ServiceManagement.h>
21#include <hidl/Static.h>
22#include <hidl/Status.h>
23
Steven Moreland337e6b62017-01-18 17:25:13 -080024#include <android-base/logging.h>
25#include <dlfcn.h>
26#include <hidl-util/FQName.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070027#include <hwbinder/IPCThreadState.h>
28#include <hwbinder/Parcel.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070029#include <unistd.h>
30
31#include <android/hidl/manager/1.0/IServiceManager.h>
Yifan Hong4e925992017-01-09 17:47:17 -080032#include <android/hidl/manager/1.0/BpHwServiceManager.h>
33#include <android/hidl/manager/1.0/BnHwServiceManager.h>
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070034
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070035using android::hidl::manager::V1_0::IServiceManager;
Steven Moreland337e6b62017-01-18 17:25:13 -080036using android::hidl::manager::V1_0::IServiceNotification;
Yifan Hong4e925992017-01-09 17:47:17 -080037using android::hidl::manager::V1_0::BpHwServiceManager;
38using android::hidl::manager::V1_0::BnHwServiceManager;
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070039
40namespace android {
41namespace hardware {
42
43sp<IServiceManager> defaultServiceManager() {
44
45 if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
46 if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
47 // HwBinder not available on this device or not accessible to
48 // this process.
49 return nullptr;
50 }
51 {
52 AutoMutex _l(gDefaultServiceManagerLock);
53 while (gDefaultServiceManager == NULL) {
Yifan Hong4e925992017-01-09 17:47:17 -080054 gDefaultServiceManager = fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>(
Steven Moreland5d5ef7f2016-10-20 19:19:55 -070055 ProcessState::self()->getContextObject(NULL));
56 if (gDefaultServiceManager == NULL)
57 sleep(1);
58 }
59 }
60
61 return gDefaultServiceManager;
62}
63
Steven Moreland337e6b62017-01-18 17:25:13 -080064struct PassthroughServiceManager : IServiceManager {
65 Return<sp<IBase>> get(const hidl_string& fqName,
66 const hidl_string& name) override {
67 FQName iface(fqName);
68
69 if (!iface.isValid() ||
70 !iface.isFullyQualified() ||
71 iface.isIdentifier()) {
72 LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
73 return nullptr;
74 }
75
76 const int dlMode = RTLD_LAZY;
77 void *handle = nullptr;
78
79 for (const std::string &path : {
80 HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM
81 }) {
Steven Moreland21ce1652017-01-20 23:09:58 +000082 const std::string lib = path + iface.getPackageAndVersion().string() + "-impl.so";
83 handle = dlopen(lib.c_str(), dlMode);
84 if (handle != nullptr) {
85 break;
Steven Moreland337e6b62017-01-18 17:25:13 -080086 }
87 }
88
89 if (handle == nullptr) {
90 return nullptr;
91 }
92
93 const std::string sym = "HIDL_FETCH_" + iface.name();
94
95 IBase* (*generator)(const char* name);
96 *(void **)(&generator) = dlsym(handle, sym.c_str());
97 if(!generator) {
98 return nullptr;
99 }
100 return (*generator)(name);
101 }
102
103 Return<bool> add(const hidl_vec<hidl_string>& /* interfaceChain */,
104 const hidl_string& /* name */,
105 const sp<IBase>& /* service */) override {
106 LOG(FATAL) << "Cannot register services with passthrough service manager.";
107 return false;
108 }
109
110 Return<void> list(list_cb /* _hidl_cb */) override {
111 // TODO: add this functionality
112 LOG(FATAL) << "Cannot list services with passthrough service manager.";
113 return Void();
114 }
115 Return<void> listByInterface(const hidl_string& /* fqInstanceName */,
116 listByInterface_cb /* _hidl_cb */) override {
117 // TODO: add this functionality
118 LOG(FATAL) << "Cannot list services with passthrough service manager.";
119 return Void();
120 }
121
122 Return<bool> registerForNotifications(const hidl_string& /* fqName */,
123 const hidl_string& /* name */,
124 const sp<IServiceNotification>& /* callback */) override {
125 // This makes no sense.
126 LOG(FATAL) << "Cannot register for notifications with passthrough service manager.";
127 return false;
128 }
129
130};
131
132sp<IServiceManager> getPassthroughServiceManager() {
133 static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
134 return manager;
135}
136
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700137}; // namespace hardware
138}; // namespace android