Merge "libpower: Avoid holding lock during binder txn in `acquire_wake_lock`" into main am: 031bb72a72

Original change: https://android-review.googlesource.com/c/platform/hardware/libhardware_legacy/+/3106769

Change-Id: I5249c71169fb6b5ac7f0582e7475a2f0458a11c4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index b2cc315..474fcb8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -39,7 +39,19 @@
     ],
 }
 
-cc_library {
+soong_config_module_type {
+    name: "cc_library_libpower",
+    module_type: "cc_library",
+    config_namespace: "ANDROID",
+    bool_variables: [
+        "release_libpower_no_lock_binder_txn",
+    ],
+    properties: [
+        "cflags",
+    ],
+}
+
+cc_library_libpower {
     name: "libpower",
     defaults: ["libpower_defaults"],
     srcs: ["power.cpp"],
@@ -51,6 +63,11 @@
         "com.android.uwb",
     ],
     min_sdk_version: "Tiramisu",
+    soong_config_variables: {
+        release_libpower_no_lock_binder_txn: {
+            cflags: ["-DENABLE_NO_LOCK_BINDER_TXN"],
+        },
+    },
 }
 
 cc_test {
diff --git a/power.cpp b/power.cpp
index 147903d..9696f08 100644
--- a/power.cpp
+++ b/power.cpp
@@ -60,6 +60,31 @@
         return -1;
     }
 
+#ifdef ENABLE_NO_LOCK_BINDER_TXN
+    bool hasLock;
+    {
+        std::lock_guard<std::mutex> l{gLock};
+        hasLock = !!gWakeLockMap[id];
+    }
+    if (hasLock)
+        return 0;
+
+    std::shared_ptr<IWakeLock> wl = nullptr;
+    auto status =
+        suspendService->acquireWakeLock(WakeLockType::PARTIAL, id, &wl);
+    // It's possible that during device shutdown SystemSuspend service has
+    // already exited. Check that the wakelock object is not null.
+    if (!wl) {
+        LOG(ERROR) << "ISuspendService::acquireWakeLock() call failed: "
+                   << status.getDescription();
+        return -1;
+    }
+    {
+        std::lock_guard<std::mutex> l{gLock};
+        // Check if another thread has already set it.
+        if (!gWakeLockMap[id]) gWakeLockMap[id] = wl;
+    }
+#else
     std::lock_guard<std::mutex> l{gLock};
     if (!gWakeLockMap[id]) {
         std::shared_ptr<IWakeLock> wl = nullptr;
@@ -73,6 +98,7 @@
         }
         gWakeLockMap[id] = wl;
     }
+#endif
     return 0;
 }