zenfone8: fingerprint: add a cmd runner thread to not block on HIDL calls

Change-Id: I8cc7696317148e3a2351d9d54f5f1c65464ae361
diff --git a/fingerprint/BiometricsFingerprint.cpp b/fingerprint/BiometricsFingerprint.cpp
index bbb5637..54e9b15 100644
--- a/fingerprint/BiometricsFingerprint.cpp
+++ b/fingerprint/BiometricsFingerprint.cpp
@@ -80,6 +80,16 @@
     this->mGoodixFingerprintDaemon = IGoodixFingerprintDaemon::getService();
 
     std::thread([this]() {
+        unsigned int cmd;
+
+        while (true) {
+            mCmdQueue.pop(cmd);
+            this->mGoodixFingerprintDaemon->sendCommand(cmd, {},
+                                                        [](int, const hidl_vec<signed char>&) {});
+        }
+    }).detach();
+
+    std::thread([this]() {
         int fd = open(FOD_UI_PATH, O_RDONLY);
         if (fd < 0) {
             LOG(ERROR) << "failed to open fd, err: " << fd;
@@ -100,8 +110,7 @@
             }
 
             if (readBool(fd)) {
-                this->mGoodixFingerprintDaemon->sendCommand(CMD_LIGHT_AREA_STABLE, {},
-                                                            [](int, const hidl_vec<signed char>&) {});
+                mCmdQueue.push(CMD_LIGHT_AREA_STABLE);
             }
         }
     }).detach();
@@ -127,14 +136,12 @@
 }
 
 Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) {
-    mGoodixFingerprintDaemon->sendCommand(CMD_FINGER_DOWN, {},
-                                                [](int, const hidl_vec<signed char>&) {});
+    mCmdQueue.push(CMD_FINGER_DOWN);
     return Void();
 }
 
 Return<void> BiometricsFingerprint::onFingerUp() {
-    mGoodixFingerprintDaemon->sendCommand(CMD_FINGER_UP, {},
-                                                [](int, const hidl_vec<signed char>&) {});
+    mCmdQueue.push(CMD_FINGER_UP);
     return Void();
 }
 
diff --git a/fingerprint/BiometricsFingerprint.h b/fingerprint/BiometricsFingerprint.h
index a118bab..ff5931b 100644
--- a/fingerprint/BiometricsFingerprint.h
+++ b/fingerprint/BiometricsFingerprint.h
@@ -28,6 +28,8 @@
 
 #include <vendor/goodix/hardware/biometrics/fingerprint/2.1/IGoodixFingerprintDaemon.h>
 
+#include "concurrent_queue.h"
+
 namespace android {
 namespace hardware {
 namespace biometrics {
@@ -85,6 +87,7 @@
     sp<IBiometricsFingerprintClientCallback> mClientCallback;
     fingerprint_device_t *mDevice;
     sp<IGoodixFingerprintDaemon> mGoodixFingerprintDaemon;
+    concurrent_queue<unsigned int> mCmdQueue;
 };
 
 }  // namespace implementation
diff --git a/fingerprint/concurrent_queue.h b/fingerprint/concurrent_queue.h
new file mode 100644
index 0000000..c94075d
--- /dev/null
+++ b/fingerprint/concurrent_queue.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+
+template<typename T>
+class concurrent_queue
+{
+  private:
+    std::condition_variable c;
+    mutable std::mutex m;
+    std::queue<T> q;
+
+  public:
+    void push(T const& v) {
+        std::unique_lock<std::mutex> lock(m);
+        q.push(v);
+        lock.unlock();
+        c.notify_one();
+    }
+
+    bool empty() const {
+        std::lock_guard<std::mutex> lock(m);
+        return q.empty();
+    }
+
+    void pop(T& v) {
+        std::unique_lock<std::mutex> lock(m);
+        while (q.empty()) {
+            c.wait(lock);
+        }
+
+        v = q.front();
+        q.pop();
+    }
+};