Merge changes from topic "hwbinder_logs" into main

* changes:
  Log when threadpool is being used/configured and HIDL is disabled
  Move isHidlSupported to libhwbinder
diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp
index e0c1ade..e7e2190 100644
--- a/IPCThreadState.cpp
+++ b/IPCThreadState.cpp
@@ -20,6 +20,7 @@
 
 #include <hwbinder/Binder.h>
 #include <hwbinder/BpHwBinder.h>
+#include <hwbinder/HidlSupport.h>
 
 #include <android-base/macros.h>
 #include <utils/CallStack.h>
@@ -538,6 +539,10 @@
 {
     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 d6dfa16..d02c3c0 100644
--- a/ProcessState.cpp
+++ b/ProcessState.cpp
@@ -19,6 +19,7 @@
 #include <hwbinder/ProcessState.h>
 
 #include <cutils/atomic.h>
+#include <hwbinder/HidlSupport.h>
 #include <hwbinder/BpHwBinder.h>
 #include <hwbinder/IPCThreadState.h>
 #include <utils/Log.h>
@@ -105,6 +106,9 @@
 
 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;
@@ -317,6 +321,10 @@
     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.
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 <hwbinder/HidlSupport.h>
 
 #include <string.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
 
 namespace android::hardware {
 
@@ -24,4 +27,38 @@
     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 <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+// 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
+