blob: 0d2f1bf6dfc7451326dc094479362d736d082ac5 [file] [log] [blame]
Steven Moreland11a732a2017-03-07 17:44:17 -08001/*
2 * Copyright (C) 2017 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#include <hidl/HidlTransportSupport.h>
Steven Morelanda15479f2017-10-06 16:06:26 -070017
18#include <android/hidl/manager/1.0/IServiceManager.h>
Steven Moreland11a732a2017-03-07 17:44:17 -080019#include <hidl/HidlBinderSupport.h>
Steven Morelanda15479f2017-10-06 16:06:26 -070020#include <hidl/ServiceManagement.h>
Steven Moreland11a732a2017-03-07 17:44:17 -080021
22namespace android {
23namespace hardware {
24
25void configureRpcThreadpool(size_t maxThreads, bool callerWillJoin) {
26 // TODO(b/32756130) this should be transport-dependent
27 configureBinderRpcThreadpool(maxThreads, callerWillJoin);
28}
29void joinRpcThreadpool() {
30 // TODO(b/32756130) this should be transport-dependent
31 joinBinderRpcThreadpool();
32}
33
Martijn Coenen81ef4da2017-04-21 16:21:31 -070034bool setMinSchedulerPolicy(const sp<::android::hidl::base::V1_0::IBase>& service,
35 int policy, int priority) {
36 if (service->isRemote()) {
37 ALOGE("Can't set scheduler policy on remote service.");
38 return false;
39 }
40
41 if (policy != SCHED_NORMAL && policy != SCHED_FIFO && policy != SCHED_RR) {
42 ALOGE("Invalid scheduler policy %d", policy);
43 return false;
44 }
45
46 if (policy == SCHED_NORMAL && (priority < -20 || priority > 19)) {
47 ALOGE("Invalid priority for SCHED_NORMAL: %d", priority);
48 return false;
49 } else if (priority < 1 || priority > 99) {
50 ALOGE("Invalid priority for real-time policy: %d", priority);
51 return false;
52 }
53
54 details::gServicePrioMap.set(service, { policy, priority });
55
56 return true;
Steven Moreland11a732a2017-03-07 17:44:17 -080057}
Martijn Coenen81ef4da2017-04-21 16:21:31 -070058
Steven Morelanda15479f2017-10-06 16:06:26 -070059namespace details {
60
61sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
62 const std::string& instance,
63 bool retry, bool getStub) {
64 using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
65 using ::android::hidl::base::V1_0::IBase;
66 using ::android::hidl::manager::V1_0::IServiceManager;
67
68 const sp<IServiceManager> sm = defaultServiceManager();
69 if (sm == nullptr) {
70 ALOGE("getService: defaultServiceManager() is null");
71 return nullptr;
72 }
73
74 Return<Transport> transportRet = sm->getTransport(descriptor, instance);
75
76 if (!transportRet.isOk()) {
77 ALOGE("getService: defaultServiceManager()->getTransport returns %s",
78 transportRet.description().c_str());
79 return nullptr;
80 }
81 Transport transport = transportRet;
82 const bool vintfHwbinder = (transport == Transport::HWBINDER);
83 const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
84
85#ifdef LIBHIDL_TARGET_TREBLE
86
87#ifdef LIBHIDL_TARGET_DEBUGGABLE
88 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
89 const bool trebleTestingOverride = env && !strcmp(env, "true");
90 const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
91#else // LIBHIDL_TARGET_TREBLE but not LIBHIDL_TARGET_DEBUGGABLE
92 const bool trebleTestingOverride = false;
93 const bool vintfLegacy = false;
94#endif // LIBHIDL_TARGET_DEBUGGABLE
95
96#else // not LIBHIDL_TARGET_TREBLE
97 const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
98 const bool trebleTestingOverride = env && !strcmp(env, "true");
99 const bool vintfLegacy = (transport == Transport::EMPTY);
100#endif // LIBHIDL_TARGET_TREBLE
101
102 for (int tries = 0;
103 !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)) && (retry || tries < 1);
104 tries++) {
105 if (tries > 1) {
106 ALOGI("getService: Will do try %d for %s/%s in 1s...", tries, descriptor.c_str(),
107 instance.c_str());
108 sleep(1); // TODO(b/67425500): remove and update waitForHwService function
109 }
110 if (vintfHwbinder && tries > 0) {
111 waitForHwService(descriptor, instance);
112 }
113 Return<sp<IBase>> ret = sm->get(descriptor, instance);
114 if (!ret.isOk()) {
115 ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
116 ret.description().c_str(), descriptor.c_str(), instance.c_str());
117 break;
118 }
119 sp<IBase> base = ret;
120 if (base == nullptr) {
121 if (tries > 0) {
122 ALOGW("getService: found unexpected null hwbinder interface for %s/%s.",
123 descriptor.c_str(), instance.c_str());
124 }
125 continue;
126 }
127
128 Return<bool> canCastRet =
129 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
130
131 if (!canCastRet.isOk()) {
132 if (canCastRet.isDeadObject()) {
133 ALOGW("getService: found dead hwbinder service for %s/%s.", descriptor.c_str(),
134 instance.c_str());
135 continue;
136 }
137 // TODO(b/67425500): breaks getService == nullptr => hal available assumptions if the
138 // service has a transaction failure (one example of this is if the service's binder
139 // buffer is full). If this isn't here, you get an infinite loop when you don't have
140 // permission to talk to a service.
141 ALOGW("getService: unable to call into hwbinder service for %s/%s.", descriptor.c_str(),
142 instance.c_str());
143 break;
144 }
145
146 if (!canCastRet) {
147 ALOGW("getService: received incompatible service (bug in hwservicemanager?) for %s/%s.",
148 descriptor.c_str(), instance.c_str());
149 break;
150 }
151
152 return base; // still needs to be wrapped by Bp class.
153 }
154
155 if (getStub || vintfPassthru || vintfLegacy) {
156 const sp<IServiceManager> pm = getPassthroughServiceManager();
157 if (pm != nullptr) {
158 sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
159 if (!getStub || trebleTestingOverride) {
160 base = wrapPassthrough(base);
161 }
162 return base;
163 }
164 }
165
166 return nullptr;
Martijn Coenen81ef4da2017-04-21 16:21:31 -0700167}
Steven Morelanda15479f2017-10-06 16:06:26 -0700168
169} // namespace details
170} // namespace hardware
171} // namespace android