1*8222fbe1SAndroid Build Coastguard Worker /*
2*8222fbe1SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*8222fbe1SAndroid Build Coastguard Worker *
4*8222fbe1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8222fbe1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8222fbe1SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8222fbe1SAndroid Build Coastguard Worker *
8*8222fbe1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8222fbe1SAndroid Build Coastguard Worker *
10*8222fbe1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8222fbe1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8222fbe1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8222fbe1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8222fbe1SAndroid Build Coastguard Worker * limitations under the License.
15*8222fbe1SAndroid Build Coastguard Worker */
16*8222fbe1SAndroid Build Coastguard Worker
17*8222fbe1SAndroid Build Coastguard Worker #define LOG_TAG "HidlSupport"
18*8222fbe1SAndroid Build Coastguard Worker
19*8222fbe1SAndroid Build Coastguard Worker #include <hidl/HidlBinderSupport.h>
20*8222fbe1SAndroid Build Coastguard Worker
21*8222fbe1SAndroid Build Coastguard Worker #include <android/hidl/base/1.0/BpHwBase.h>
22*8222fbe1SAndroid Build Coastguard Worker #include <android/hidl/manager/1.0/BpHwServiceManager.h>
23*8222fbe1SAndroid Build Coastguard Worker #include <android/hidl/manager/1.1/BpHwServiceManager.h>
24*8222fbe1SAndroid Build Coastguard Worker #include <android/hidl/manager/1.2/BpHwServiceManager.h>
25*8222fbe1SAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
26*8222fbe1SAndroid Build Coastguard Worker #include "InternalStatic.h" // TODO(b/69122224): remove this include, for getOrCreateCachedBinder
27*8222fbe1SAndroid Build Coastguard Worker
28*8222fbe1SAndroid Build Coastguard Worker // C includes
29*8222fbe1SAndroid Build Coastguard Worker #include <inttypes.h>
30*8222fbe1SAndroid Build Coastguard Worker #include <unistd.h>
31*8222fbe1SAndroid Build Coastguard Worker
32*8222fbe1SAndroid Build Coastguard Worker // C++ includes
33*8222fbe1SAndroid Build Coastguard Worker #include <fstream>
34*8222fbe1SAndroid Build Coastguard Worker #include <sstream>
35*8222fbe1SAndroid Build Coastguard Worker
36*8222fbe1SAndroid Build Coastguard Worker namespace android {
37*8222fbe1SAndroid Build Coastguard Worker namespace hardware {
38*8222fbe1SAndroid Build Coastguard Worker
hidl_binder_death_recipient(const sp<hidl_death_recipient> & recipient,uint64_t cookie,const sp<::android::hidl::base::V1_0::IBase> & base)39*8222fbe1SAndroid Build Coastguard Worker hidl_binder_death_recipient::hidl_binder_death_recipient(const sp<hidl_death_recipient> &recipient,
40*8222fbe1SAndroid Build Coastguard Worker uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base) :
41*8222fbe1SAndroid Build Coastguard Worker mRecipient(recipient), mCookie(cookie), mBase(base) {
42*8222fbe1SAndroid Build Coastguard Worker }
43*8222fbe1SAndroid Build Coastguard Worker
binderDied(const wp<IBinder> &)44*8222fbe1SAndroid Build Coastguard Worker void hidl_binder_death_recipient::binderDied(const wp<IBinder>& /*who*/) {
45*8222fbe1SAndroid Build Coastguard Worker sp<hidl_death_recipient> recipient = mRecipient.promote();
46*8222fbe1SAndroid Build Coastguard Worker if (recipient != nullptr && mBase != nullptr) {
47*8222fbe1SAndroid Build Coastguard Worker recipient->serviceDied(mCookie, mBase);
48*8222fbe1SAndroid Build Coastguard Worker }
49*8222fbe1SAndroid Build Coastguard Worker mBase = nullptr;
50*8222fbe1SAndroid Build Coastguard Worker }
51*8222fbe1SAndroid Build Coastguard Worker
getRecipient()52*8222fbe1SAndroid Build Coastguard Worker wp<hidl_death_recipient> hidl_binder_death_recipient::getRecipient() {
53*8222fbe1SAndroid Build Coastguard Worker return mRecipient;
54*8222fbe1SAndroid Build Coastguard Worker }
55*8222fbe1SAndroid Build Coastguard Worker
56*8222fbe1SAndroid Build Coastguard Worker const size_t hidl_handle::kOffsetOfNativeHandle = offsetof(hidl_handle, mHandle);
57*8222fbe1SAndroid Build Coastguard Worker static_assert(hidl_handle::kOffsetOfNativeHandle == 0, "wrong offset");
58*8222fbe1SAndroid Build Coastguard Worker
readEmbeddedFromParcel(const hidl_handle &,const Parcel & parcel,size_t parentHandle,size_t parentOffset)59*8222fbe1SAndroid Build Coastguard Worker status_t readEmbeddedFromParcel(const hidl_handle& /* handle */,
60*8222fbe1SAndroid Build Coastguard Worker const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
61*8222fbe1SAndroid Build Coastguard Worker const native_handle_t *handle;
62*8222fbe1SAndroid Build Coastguard Worker status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle(
63*8222fbe1SAndroid Build Coastguard Worker parentHandle,
64*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_handle::kOffsetOfNativeHandle,
65*8222fbe1SAndroid Build Coastguard Worker &handle);
66*8222fbe1SAndroid Build Coastguard Worker
67*8222fbe1SAndroid Build Coastguard Worker return _hidl_err;
68*8222fbe1SAndroid Build Coastguard Worker }
69*8222fbe1SAndroid Build Coastguard Worker
writeEmbeddedToParcel(const hidl_handle & handle,Parcel * parcel,size_t parentHandle,size_t parentOffset)70*8222fbe1SAndroid Build Coastguard Worker status_t writeEmbeddedToParcel(const hidl_handle &handle,
71*8222fbe1SAndroid Build Coastguard Worker Parcel *parcel, size_t parentHandle, size_t parentOffset) {
72*8222fbe1SAndroid Build Coastguard Worker status_t _hidl_err = parcel->writeEmbeddedNativeHandle(
73*8222fbe1SAndroid Build Coastguard Worker handle.getNativeHandle(),
74*8222fbe1SAndroid Build Coastguard Worker parentHandle,
75*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_handle::kOffsetOfNativeHandle);
76*8222fbe1SAndroid Build Coastguard Worker
77*8222fbe1SAndroid Build Coastguard Worker return _hidl_err;
78*8222fbe1SAndroid Build Coastguard Worker }
79*8222fbe1SAndroid Build Coastguard Worker
80*8222fbe1SAndroid Build Coastguard Worker const size_t hidl_memory::kOffsetOfHandle = offsetof(hidl_memory, mHandle);
81*8222fbe1SAndroid Build Coastguard Worker const size_t hidl_memory::kOffsetOfName = offsetof(hidl_memory, mName);
82*8222fbe1SAndroid Build Coastguard Worker static_assert(hidl_memory::kOffsetOfHandle == 0, "wrong offset");
83*8222fbe1SAndroid Build Coastguard Worker static_assert(hidl_memory::kOffsetOfName == 24, "wrong offset");
84*8222fbe1SAndroid Build Coastguard Worker
readEmbeddedFromParcel(const hidl_memory & memory,const Parcel & parcel,size_t parentHandle,size_t parentOffset)85*8222fbe1SAndroid Build Coastguard Worker status_t readEmbeddedFromParcel(const hidl_memory& memory,
86*8222fbe1SAndroid Build Coastguard Worker const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
87*8222fbe1SAndroid Build Coastguard Worker // TODO(b/111883309): Invoke readEmbeddedFromParcel(hidl_handle, ...).
88*8222fbe1SAndroid Build Coastguard Worker const native_handle_t *handle;
89*8222fbe1SAndroid Build Coastguard Worker ::android::status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle(
90*8222fbe1SAndroid Build Coastguard Worker parentHandle,
91*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_memory::kOffsetOfHandle,
92*8222fbe1SAndroid Build Coastguard Worker &handle);
93*8222fbe1SAndroid Build Coastguard Worker
94*8222fbe1SAndroid Build Coastguard Worker if (_hidl_err == ::android::OK) {
95*8222fbe1SAndroid Build Coastguard Worker _hidl_err = readEmbeddedFromParcel(
96*8222fbe1SAndroid Build Coastguard Worker memory.name(),
97*8222fbe1SAndroid Build Coastguard Worker parcel,
98*8222fbe1SAndroid Build Coastguard Worker parentHandle,
99*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_memory::kOffsetOfName);
100*8222fbe1SAndroid Build Coastguard Worker }
101*8222fbe1SAndroid Build Coastguard Worker
102*8222fbe1SAndroid Build Coastguard Worker // hidl_memory's size is stored in uint64_t, but mapMemory's mmap will map
103*8222fbe1SAndroid Build Coastguard Worker // size in size_t. If size is over SIZE_MAX, mapMemory could succeed
104*8222fbe1SAndroid Build Coastguard Worker // but the mapped memory's actual size will be smaller than the reported size.
105*8222fbe1SAndroid Build Coastguard Worker if (memory.size() > SIZE_MAX) {
106*8222fbe1SAndroid Build Coastguard Worker ALOGE("Cannot use memory with %" PRId64 " bytes because it is too large.", memory.size());
107*8222fbe1SAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "79376389");
108*8222fbe1SAndroid Build Coastguard Worker return BAD_VALUE;
109*8222fbe1SAndroid Build Coastguard Worker }
110*8222fbe1SAndroid Build Coastguard Worker
111*8222fbe1SAndroid Build Coastguard Worker return _hidl_err;
112*8222fbe1SAndroid Build Coastguard Worker }
113*8222fbe1SAndroid Build Coastguard Worker
writeEmbeddedToParcel(const hidl_memory & memory,Parcel * parcel,size_t parentHandle,size_t parentOffset)114*8222fbe1SAndroid Build Coastguard Worker status_t writeEmbeddedToParcel(const hidl_memory &memory,
115*8222fbe1SAndroid Build Coastguard Worker Parcel *parcel, size_t parentHandle, size_t parentOffset) {
116*8222fbe1SAndroid Build Coastguard Worker // TODO(b/111883309): Invoke writeEmbeddedToParcel(hidl_handle, ...).
117*8222fbe1SAndroid Build Coastguard Worker status_t _hidl_err = parcel->writeEmbeddedNativeHandle(
118*8222fbe1SAndroid Build Coastguard Worker memory.handle(),
119*8222fbe1SAndroid Build Coastguard Worker parentHandle,
120*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_memory::kOffsetOfHandle);
121*8222fbe1SAndroid Build Coastguard Worker
122*8222fbe1SAndroid Build Coastguard Worker if (_hidl_err == ::android::OK) {
123*8222fbe1SAndroid Build Coastguard Worker _hidl_err = writeEmbeddedToParcel(
124*8222fbe1SAndroid Build Coastguard Worker memory.name(),
125*8222fbe1SAndroid Build Coastguard Worker parcel,
126*8222fbe1SAndroid Build Coastguard Worker parentHandle,
127*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_memory::kOffsetOfName);
128*8222fbe1SAndroid Build Coastguard Worker }
129*8222fbe1SAndroid Build Coastguard Worker
130*8222fbe1SAndroid Build Coastguard Worker return _hidl_err;
131*8222fbe1SAndroid Build Coastguard Worker }
132*8222fbe1SAndroid Build Coastguard Worker const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
133*8222fbe1SAndroid Build Coastguard Worker static_assert(hidl_string::kOffsetOfBuffer == 0, "wrong offset");
134*8222fbe1SAndroid Build Coastguard Worker
readEmbeddedFromParcel(const hidl_string & string,const Parcel & parcel,size_t parentHandle,size_t parentOffset)135*8222fbe1SAndroid Build Coastguard Worker status_t readEmbeddedFromParcel(const hidl_string &string ,
136*8222fbe1SAndroid Build Coastguard Worker const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
137*8222fbe1SAndroid Build Coastguard Worker const void *out;
138*8222fbe1SAndroid Build Coastguard Worker
139*8222fbe1SAndroid Build Coastguard Worker status_t status = parcel.readEmbeddedBuffer(
140*8222fbe1SAndroid Build Coastguard Worker string.size() + 1,
141*8222fbe1SAndroid Build Coastguard Worker nullptr /* buffer_handle */,
142*8222fbe1SAndroid Build Coastguard Worker parentHandle,
143*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_string::kOffsetOfBuffer,
144*8222fbe1SAndroid Build Coastguard Worker &out);
145*8222fbe1SAndroid Build Coastguard Worker
146*8222fbe1SAndroid Build Coastguard Worker if (status != OK) {
147*8222fbe1SAndroid Build Coastguard Worker return status;
148*8222fbe1SAndroid Build Coastguard Worker }
149*8222fbe1SAndroid Build Coastguard Worker
150*8222fbe1SAndroid Build Coastguard Worker // Always safe to access out[string.size()] because we read size+1 bytes
151*8222fbe1SAndroid Build Coastguard Worker if (static_cast<const char *>(out)[string.size()] != '\0') {
152*8222fbe1SAndroid Build Coastguard Worker ALOGE("Received unterminated hidl_string buffer.");
153*8222fbe1SAndroid Build Coastguard Worker return BAD_VALUE;
154*8222fbe1SAndroid Build Coastguard Worker }
155*8222fbe1SAndroid Build Coastguard Worker
156*8222fbe1SAndroid Build Coastguard Worker return OK;
157*8222fbe1SAndroid Build Coastguard Worker }
158*8222fbe1SAndroid Build Coastguard Worker
writeEmbeddedToParcel(const hidl_string & string,Parcel * parcel,size_t parentHandle,size_t parentOffset)159*8222fbe1SAndroid Build Coastguard Worker status_t writeEmbeddedToParcel(const hidl_string &string,
160*8222fbe1SAndroid Build Coastguard Worker Parcel *parcel, size_t parentHandle, size_t parentOffset) {
161*8222fbe1SAndroid Build Coastguard Worker return parcel->writeEmbeddedBuffer(
162*8222fbe1SAndroid Build Coastguard Worker string.c_str(),
163*8222fbe1SAndroid Build Coastguard Worker string.size() + 1,
164*8222fbe1SAndroid Build Coastguard Worker nullptr /* handle */,
165*8222fbe1SAndroid Build Coastguard Worker parentHandle,
166*8222fbe1SAndroid Build Coastguard Worker parentOffset + hidl_string::kOffsetOfBuffer);
167*8222fbe1SAndroid Build Coastguard Worker }
168*8222fbe1SAndroid Build Coastguard Worker
readFromParcel(Status * s,const Parcel & parcel)169*8222fbe1SAndroid Build Coastguard Worker status_t readFromParcel(Status *s, const Parcel& parcel) {
170*8222fbe1SAndroid Build Coastguard Worker int32_t exception;
171*8222fbe1SAndroid Build Coastguard Worker status_t status = parcel.readInt32(&exception);
172*8222fbe1SAndroid Build Coastguard Worker if (status != OK) {
173*8222fbe1SAndroid Build Coastguard Worker s->setFromStatusT(status);
174*8222fbe1SAndroid Build Coastguard Worker return status;
175*8222fbe1SAndroid Build Coastguard Worker }
176*8222fbe1SAndroid Build Coastguard Worker
177*8222fbe1SAndroid Build Coastguard Worker if (exception == Status::EX_NONE) {
178*8222fbe1SAndroid Build Coastguard Worker *s = Status::ok();
179*8222fbe1SAndroid Build Coastguard Worker return status;
180*8222fbe1SAndroid Build Coastguard Worker }
181*8222fbe1SAndroid Build Coastguard Worker
182*8222fbe1SAndroid Build Coastguard Worker // The remote threw an exception. Get the message back.
183*8222fbe1SAndroid Build Coastguard Worker String16 message;
184*8222fbe1SAndroid Build Coastguard Worker status = parcel.readString16(&message);
185*8222fbe1SAndroid Build Coastguard Worker if (status != OK) {
186*8222fbe1SAndroid Build Coastguard Worker s->setFromStatusT(status);
187*8222fbe1SAndroid Build Coastguard Worker return status;
188*8222fbe1SAndroid Build Coastguard Worker }
189*8222fbe1SAndroid Build Coastguard Worker
190*8222fbe1SAndroid Build Coastguard Worker s->setException(exception, String8(message));
191*8222fbe1SAndroid Build Coastguard Worker
192*8222fbe1SAndroid Build Coastguard Worker return status;
193*8222fbe1SAndroid Build Coastguard Worker }
194*8222fbe1SAndroid Build Coastguard Worker
writeToParcel(const Status & s,Parcel * parcel)195*8222fbe1SAndroid Build Coastguard Worker status_t writeToParcel(const Status &s, Parcel* parcel) {
196*8222fbe1SAndroid Build Coastguard Worker // Something really bad has happened, and we're not going to even
197*8222fbe1SAndroid Build Coastguard Worker // try returning rich error data.
198*8222fbe1SAndroid Build Coastguard Worker if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
199*8222fbe1SAndroid Build Coastguard Worker return s.transactionError();
200*8222fbe1SAndroid Build Coastguard Worker }
201*8222fbe1SAndroid Build Coastguard Worker
202*8222fbe1SAndroid Build Coastguard Worker status_t status = parcel->writeInt32(s.exceptionCode());
203*8222fbe1SAndroid Build Coastguard Worker if (status != OK) { return status; }
204*8222fbe1SAndroid Build Coastguard Worker if (s.exceptionCode() == Status::EX_NONE) {
205*8222fbe1SAndroid Build Coastguard Worker // We have no more information to write.
206*8222fbe1SAndroid Build Coastguard Worker return status;
207*8222fbe1SAndroid Build Coastguard Worker }
208*8222fbe1SAndroid Build Coastguard Worker status = parcel->writeString16(String16(s.exceptionMessage()));
209*8222fbe1SAndroid Build Coastguard Worker return status;
210*8222fbe1SAndroid Build Coastguard Worker }
211*8222fbe1SAndroid Build Coastguard Worker
212*8222fbe1SAndroid Build Coastguard Worker // assume: iface != nullptr, iface isRemote
213*8222fbe1SAndroid Build Coastguard Worker // This function is to sandbox a cast through a BpHw* class into a function, so
214*8222fbe1SAndroid Build Coastguard Worker // that we can remove cfi sanitization from it. Do not add additional
215*8222fbe1SAndroid Build Coastguard Worker // functionality here.
forceGetRefBase(::android::hidl::base::V1_0::IBase * ifacePtr)216*8222fbe1SAndroid Build Coastguard Worker __attribute__((no_sanitize("cfi"))) static inline BpHwRefBase* forceGetRefBase(
217*8222fbe1SAndroid Build Coastguard Worker ::android::hidl::base::V1_0::IBase* ifacePtr) {
218*8222fbe1SAndroid Build Coastguard Worker using ::android::hidl::base::V1_0::BpHwBase;
219*8222fbe1SAndroid Build Coastguard Worker
220*8222fbe1SAndroid Build Coastguard Worker // canary only
221*8222fbe1SAndroid Build Coastguard Worker static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_0::BpHwServiceManager));
222*8222fbe1SAndroid Build Coastguard Worker static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_1::BpHwServiceManager));
223*8222fbe1SAndroid Build Coastguard Worker static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_2::BpHwServiceManager));
224*8222fbe1SAndroid Build Coastguard Worker
225*8222fbe1SAndroid Build Coastguard Worker // All BpHw* are generated the same. This may be BpHwServiceManager,
226*8222fbe1SAndroid Build Coastguard Worker // BpHwFoo, or any other class. For ABI compatibility, we can't modify the
227*8222fbe1SAndroid Build Coastguard Worker // class hierarchy of these, so we have no way to get BpHwRefBase from a
228*8222fbe1SAndroid Build Coastguard Worker // remote ifacePtr.
229*8222fbe1SAndroid Build Coastguard Worker BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr);
230*8222fbe1SAndroid Build Coastguard Worker return static_cast<BpHwRefBase*>(bpBase);
231*8222fbe1SAndroid Build Coastguard Worker }
232*8222fbe1SAndroid Build Coastguard Worker
getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase * ifacePtr)233*8222fbe1SAndroid Build Coastguard Worker sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr) {
234*8222fbe1SAndroid Build Coastguard Worker if (ifacePtr == nullptr) {
235*8222fbe1SAndroid Build Coastguard Worker return nullptr;
236*8222fbe1SAndroid Build Coastguard Worker }
237*8222fbe1SAndroid Build Coastguard Worker
238*8222fbe1SAndroid Build Coastguard Worker if (ifacePtr->isRemote()) {
239*8222fbe1SAndroid Build Coastguard Worker BpHwRefBase* bpRefBase = forceGetRefBase(ifacePtr);
240*8222fbe1SAndroid Build Coastguard Worker return sp<IBinder>(bpRefBase->remote());
241*8222fbe1SAndroid Build Coastguard Worker }
242*8222fbe1SAndroid Build Coastguard Worker
243*8222fbe1SAndroid Build Coastguard Worker std::string descriptor = details::getDescriptor(ifacePtr);
244*8222fbe1SAndroid Build Coastguard Worker if (descriptor.empty()) {
245*8222fbe1SAndroid Build Coastguard Worker // interfaceDescriptor fails
246*8222fbe1SAndroid Build Coastguard Worker return nullptr;
247*8222fbe1SAndroid Build Coastguard Worker }
248*8222fbe1SAndroid Build Coastguard Worker
249*8222fbe1SAndroid Build Coastguard Worker // for get + set
250*8222fbe1SAndroid Build Coastguard Worker std::unique_lock<std::mutex> _lock = details::gBnMap->lock();
251*8222fbe1SAndroid Build Coastguard Worker
252*8222fbe1SAndroid Build Coastguard Worker wp<BHwBinder> wBnObj = details::gBnMap->getLocked(ifacePtr, nullptr);
253*8222fbe1SAndroid Build Coastguard Worker sp<IBinder> sBnObj = wBnObj.promote();
254*8222fbe1SAndroid Build Coastguard Worker
255*8222fbe1SAndroid Build Coastguard Worker if (sBnObj == nullptr) {
256*8222fbe1SAndroid Build Coastguard Worker auto func = details::getBnConstructorMap().get(descriptor, nullptr);
257*8222fbe1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(func == nullptr, "%s getBnConstructorMap returned null for %s",
258*8222fbe1SAndroid Build Coastguard Worker __func__, descriptor.c_str());
259*8222fbe1SAndroid Build Coastguard Worker
260*8222fbe1SAndroid Build Coastguard Worker sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr)));
261*8222fbe1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(sBnObj == nullptr, "%s Bn constructor function returned null for %s",
262*8222fbe1SAndroid Build Coastguard Worker __func__, descriptor.c_str());
263*8222fbe1SAndroid Build Coastguard Worker
264*8222fbe1SAndroid Build Coastguard Worker details::gBnMap->setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));
265*8222fbe1SAndroid Build Coastguard Worker }
266*8222fbe1SAndroid Build Coastguard Worker
267*8222fbe1SAndroid Build Coastguard Worker return sBnObj;
268*8222fbe1SAndroid Build Coastguard Worker }
269*8222fbe1SAndroid Build Coastguard Worker
270*8222fbe1SAndroid Build Coastguard Worker static bool gThreadPoolConfigured = false;
271*8222fbe1SAndroid Build Coastguard Worker
configureBinderRpcThreadpool(size_t maxThreads,bool callerWillJoin)272*8222fbe1SAndroid Build Coastguard Worker void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) {
273*8222fbe1SAndroid Build Coastguard Worker status_t ret = ProcessState::self()->setThreadPoolConfiguration(
274*8222fbe1SAndroid Build Coastguard Worker maxThreads, callerWillJoin /*callerJoinsPool*/);
275*8222fbe1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(ret != OK, "Could not setThreadPoolConfiguration: %d", ret);
276*8222fbe1SAndroid Build Coastguard Worker
277*8222fbe1SAndroid Build Coastguard Worker gThreadPoolConfigured = true;
278*8222fbe1SAndroid Build Coastguard Worker }
279*8222fbe1SAndroid Build Coastguard Worker
joinBinderRpcThreadpool()280*8222fbe1SAndroid Build Coastguard Worker void joinBinderRpcThreadpool() {
281*8222fbe1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!gThreadPoolConfigured,
282*8222fbe1SAndroid Build Coastguard Worker "HIDL joinRpcThreadpool without calling configureRpcThreadPool.");
283*8222fbe1SAndroid Build Coastguard Worker IPCThreadState::self()->joinThreadPool();
284*8222fbe1SAndroid Build Coastguard Worker }
285*8222fbe1SAndroid Build Coastguard Worker
setupBinderPolling()286*8222fbe1SAndroid Build Coastguard Worker int setupBinderPolling() {
287*8222fbe1SAndroid Build Coastguard Worker int fd;
288*8222fbe1SAndroid Build Coastguard Worker int err = IPCThreadState::self()->setupPolling(&fd);
289*8222fbe1SAndroid Build Coastguard Worker
290*8222fbe1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(err != OK, "Failed to setup binder polling: %d (%s)", err, strerror(err));
291*8222fbe1SAndroid Build Coastguard Worker
292*8222fbe1SAndroid Build Coastguard Worker return err == OK ? fd : -1;
293*8222fbe1SAndroid Build Coastguard Worker }
294*8222fbe1SAndroid Build Coastguard Worker
handleBinderPoll()295*8222fbe1SAndroid Build Coastguard Worker status_t handleBinderPoll() {
296*8222fbe1SAndroid Build Coastguard Worker return IPCThreadState::self()->handlePolledCommands();
297*8222fbe1SAndroid Build Coastguard Worker }
298*8222fbe1SAndroid Build Coastguard Worker
addPostCommandTask(const std::function<void (void)> task)299*8222fbe1SAndroid Build Coastguard Worker void addPostCommandTask(const std::function<void(void)> task) {
300*8222fbe1SAndroid Build Coastguard Worker IPCThreadState::self()->addPostCommandTask(task);
301*8222fbe1SAndroid Build Coastguard Worker }
302*8222fbe1SAndroid Build Coastguard Worker
303*8222fbe1SAndroid Build Coastguard Worker } // namespace hardware
304*8222fbe1SAndroid Build Coastguard Worker } // namespace android
305