xref: /aosp_15_r20/system/libhidl/transport/HidlBinderSupport.cpp (revision 8222fbe171c3d6fadfe95119c180cf3010c392a8)
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