summaryrefslogtreecommitdiff
path: root/transport/HidlBinderSupport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'transport/HidlBinderSupport.cpp')
-rw-r--r--transport/HidlBinderSupport.cpp92
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