diff options
Diffstat (limited to 'transport/HidlBinderSupport.cpp')
-rw-r--r-- | transport/HidlBinderSupport.cpp | 92 |
1 files changed, 88 insertions, 4 deletions
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp index 4f8d7c5..62b1755 100644 --- a/transport/HidlBinderSupport.cpp +++ b/transport/HidlBinderSupport.cpp @@ -18,6 +18,10 @@ #include <hidl/HidlBinderSupport.h> +#include <InternalStatic.h> // TODO(b/69122224): remove this include, for getOrCreateCachedBinder +#include <android/hidl/base/1.0/BpHwBase.h> +#include <hwbinder/IPCThreadState.h> + // C includes #include <inttypes.h> #include <unistd.h> @@ -46,6 +50,30 @@ wp<hidl_death_recipient> hidl_binder_death_recipient::getRecipient() { return mRecipient; } +const size_t hidl_handle::kOffsetOfNativeHandle = offsetof(hidl_handle, mHandle); +static_assert(hidl_handle::kOffsetOfNativeHandle == 0, "wrong offset"); + +status_t readEmbeddedFromParcel(const hidl_handle& /* handle */, + const Parcel &parcel, size_t parentHandle, size_t parentOffset) { + const native_handle_t *handle; + status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle( + parentHandle, + parentOffset + hidl_handle::kOffsetOfNativeHandle, + &handle); + + return _hidl_err; +} + +status_t writeEmbeddedToParcel(const hidl_handle &handle, + Parcel *parcel, size_t parentHandle, size_t parentOffset) { + status_t _hidl_err = parcel->writeEmbeddedNativeHandle( + handle.getNativeHandle(), + parentHandle, + parentOffset + hidl_handle::kOffsetOfNativeHandle); + + return _hidl_err; +} + const size_t hidl_memory::kOffsetOfHandle = offsetof(hidl_memory, mHandle); const size_t hidl_memory::kOffsetOfName = offsetof(hidl_memory, mName); static_assert(hidl_memory::kOffsetOfHandle == 0, "wrong offset"); @@ -53,6 +81,7 @@ static_assert(hidl_memory::kOffsetOfName == 24, "wrong offset"); status_t readEmbeddedFromParcel(const hidl_memory& memory, const Parcel &parcel, size_t parentHandle, size_t parentOffset) { + // TODO(b/111883309): Invoke readEmbeddedFromParcel(hidl_handle, ...). const native_handle_t *handle; ::android::status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle( parentHandle, @@ -81,6 +110,7 @@ status_t readEmbeddedFromParcel(const hidl_memory& memory, status_t writeEmbeddedToParcel(const hidl_memory &memory, Parcel *parcel, size_t parentHandle, size_t parentOffset) { + // TODO(b/111883309): Invoke writeEmbeddedToParcel(hidl_handle, ...). status_t _hidl_err = parcel->writeEmbeddedNativeHandle( memory.handle(), parentHandle, @@ -206,11 +236,63 @@ status_t writeToParcel(const Status &s, Parcel* parcel) { return status; } +sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr) { + if (ifacePtr == nullptr) { + return nullptr; + } + + if (ifacePtr->isRemote()) { + using ::android::hidl::base::V1_0::BpHwBase; + + BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr); + BpHwRefBase* bpRefBase = static_cast<BpHwRefBase*>(bpBase); + return sp<IBinder>(bpRefBase->remote()); + } + + std::string descriptor = details::getDescriptor(ifacePtr); + if (descriptor.empty()) { + // interfaceDescriptor fails + return nullptr; + } + + // for get + set + std::unique_lock<std::mutex> _lock = details::gBnMap->lock(); + + wp<BHwBinder> wBnObj = details::gBnMap->getLocked(ifacePtr, nullptr); + sp<IBinder> sBnObj = wBnObj.promote(); + + if (sBnObj == nullptr) { + auto func = details::getBnConstructorMap().get(descriptor, nullptr); + if (!func) { + // TODO(b/69122224): remove this static variable when prebuilts updated + func = details::gBnConstructorMap->get(descriptor, nullptr); + } + LOG_ALWAYS_FATAL_IF(func == nullptr, "%s gBnConstructorMap returned null for %s", __func__, + descriptor.c_str()); + + sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr))); + LOG_ALWAYS_FATAL_IF(sBnObj == nullptr, "%s Bn constructor function returned null for %s", + __func__, descriptor.c_str()); + + details::gBnMap->setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get())); + } + + return sBnObj; +} + +static bool gThreadPoolConfigured = false; + void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) { - ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin /*callerJoinsPool*/); + status_t ret = ProcessState::self()->setThreadPoolConfiguration( + maxThreads, callerWillJoin /*callerJoinsPool*/); + LOG_ALWAYS_FATAL_IF(ret != OK, "Could not setThreadPoolConfiguration: %d", ret); + + gThreadPoolConfigured = true; } void joinBinderRpcThreadpool() { + LOG_ALWAYS_FATAL_IF(!gThreadPoolConfigured, + "HIDL joinRpcThreadpool without calling configureRpcThreadPool."); IPCThreadState::self()->joinThreadPool(); } @@ -218,9 +300,7 @@ int setupBinderPolling() { int fd; int err = IPCThreadState::self()->setupPolling(&fd); - if (err != OK) { - ALOGE("Failed to setup binder polling: %d (%s)", err, strerror(err)); - } + LOG_ALWAYS_FATAL_IF(err != OK, "Failed to setup binder polling: %d (%s)", err, strerror(err)); return err == OK ? fd : -1; } @@ -229,5 +309,9 @@ status_t handleBinderPoll() { return IPCThreadState::self()->handlePolledCommands(); } +void addPostCommandTask(const std::function<void(void)> task) { + IPCThreadState::self()->addPostCommandTask(task); +} + } // namespace hardware } // namespace android |