From b1e1fd634278cefdc9b0119936b30e4362ed5cdd Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Wed, 10 Apr 2024 23:45:59 +0000 Subject: Handle BR_FROZEN_REPLY in libhwbinder This means the app is frozen and will not get the transaction. This is handled in libbinder already in the same way. Test: m Bug: 313369251 Change-Id: I3e6511a971398d8d9feea214f8fa16c66c44a769 --- IPCThreadState.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp index e0c1ade..e1dfb53 100644 --- a/IPCThreadState.cpp +++ b/IPCThreadState.cpp @@ -817,6 +817,10 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) ALOGW("Sending oneway calls to frozen process."); goto finish; + case BR_FROZEN_REPLY: + err = FAILED_TRANSACTION; + goto finish; + case BR_DEAD_REPLY: err = DEAD_OBJECT; goto finish; -- cgit v1.2.3 From 6e0bd99433bfa2ad5e232379ffd625807d3526b3 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Tue, 2 Apr 2024 16:23:17 +0000 Subject: Move isHidlSupported to libhwbinder The public API `isHidlSupported` is still in libhidlbase, but now we can use the underlying logic in libhwbinder. Test: launch_cvd Bug: 324326491 Change-Id: I06a59571542e63c7f9526615304b38f61c27e942 --- ProcessState.cpp | 1 + Utils.cpp | 37 ++++++++++++++++++++++++++++++++++++ include/hwbinder/HidlSupport.h | 43 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 include/hwbinder/HidlSupport.h diff --git a/ProcessState.cpp b/ProcessState.cpp index d6dfa16..ccb69a3 100644 --- a/ProcessState.cpp +++ b/ProcessState.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/Utils.cpp b/Utils.cpp index 5a29d6b..3f3eef8 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -15,8 +15,11 @@ */ #include "Utils.h" +#include #include +#include +#include namespace android::hardware { @@ -24,4 +27,38 @@ void zeroMemory(uint8_t* data, size_t size) { memset(data, 0, size); } +static bool isHwServiceManagerInstalled() { + return access("/system_ext/bin/hwservicemanager", F_OK) == 0 || + access("/system/system_ext/bin/hwservicemanager", F_OK) == 0 || + access("/system/bin/hwservicemanager", F_OK) == 0; +} + +static bool waitForHwServiceManager() { + if (!isHwServiceManagerInstalled()) { + return false; + } + // TODO(b/31559095): need bionic host so that we can use 'prop_info' returned + // from WaitForProperty +#ifdef __ANDROID__ + static const char* kHwServicemanagerReadyProperty = "hwservicemanager.ready"; + + using std::literals::chrono_literals::operator""s; + + using android::base::WaitForProperty; + while (true) { + if (base::GetBoolProperty("hwservicemanager.disabled", false)) { + return false; + } + if (WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) { + return true; + } + LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another..."; + } +#endif // __ANDROID__ + return true; +} + +bool isHwbinderSupportedBlocking() { + return waitForHwServiceManager(); +} } // namespace android::hardware diff --git a/include/hwbinder/HidlSupport.h b/include/hwbinder/HidlSupport.h new file mode 100644 index 0000000..92c1612 --- /dev/null +++ b/include/hwbinder/HidlSupport.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include +#include +#include + +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. +namespace android::hardware { +// Return whether or not hwbinder is supported on this device based on the existence +// of hwservicemanager. +// +// If the service is installed on the device, this method blocks and waits for +// hwservicemanager to be either ready or disabled. +// +// This function will block during early init while hwservicemanager is +// starting. If hwbinder is supported on the device, it waill wait until +// the hwservicemanager.ready property is set to true. If hwbinder is not supported +// but hwservicemanager is still installed on the device, it will wait +// until hwservicemanager.enabled is set to false. +// +// return - false if the service isn't installed on the device +// false if the service is installed, but disabled +// true if the service is ready +bool isHwbinderSupportedBlocking(); +} // namespace android::hardware + -- cgit v1.2.3 From 50935d862bb5f58732f353ecd6811feeb358a581 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Tue, 16 Apr 2024 20:55:12 +0000 Subject: Log when threadpool is being used/configured and HIDL is disabled When HIDL is disabled these threads will do nothing. Add logs so we can see if/when services are trying to use or start the hwbinder threadpools on those devices. Test: launch_cvd Bug: 324326491 Change-Id: Idbd0e3c4c80eb87a35664708cd87921dd8586c6b --- IPCThreadState.cpp | 5 +++++ ProcessState.cpp | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp index e0c1ade..e7e2190 100644 --- a/IPCThreadState.cpp +++ b/IPCThreadState.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -538,6 +539,10 @@ void IPCThreadState::joinThreadPool(bool isMain) { LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid()); + if (!isHwbinderSupportedBlocking()) { + ALOGW("HwBinder is not supported on this device, but this process is calling joinThreadPool."); + } + mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); status_t result; diff --git a/ProcessState.cpp b/ProcessState.cpp index ccb69a3..d02c3c0 100644 --- a/ProcessState.cpp +++ b/ProcessState.cpp @@ -106,6 +106,9 @@ sp ProcessState::init(size_t mmapSize, bool requireMmapSize) { void ProcessState::startThreadPool() { + if (!isHwbinderSupportedBlocking()) { + ALOGW("HwBinder is not supported on this device but this process is calling startThreadPool"); + } AutoMutex _l(mLock); if (!mThreadPoolStarted) { mThreadPoolStarted = true; @@ -318,6 +321,10 @@ status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool caller LOG_ALWAYS_FATAL_IF(maxThreads == 0 && callerJoinsPool, "Binder threadpool must have a minimum of one thread if caller joins pool."); + if (!isHwbinderSupportedBlocking()) { + ALOGW("HwBinder is not supported on this device but this process is calling setThreadPoolConfiguration"); + } + size_t threadsToAllocate = maxThreads; // If the caller is going to join the pool it will contribute one thread to the threadpool. -- cgit v1.2.3