From a587e4ebb8e87c3eb5e41e9eafcca0511d4b76b6 Mon Sep 17 00:00:00 2001
From: Bruno Martins <bgcngm@gmail.com>
Date: Fri, 31 Jan 2020 23:10:19 +0000
Subject: [PATCH] sm6250-common: power: Add support for DT2W feature

Co-authored-by: LuK1337 <priv.luk@gmail.com>
Co-authored-by: AbhiShek Aggarwal <warabhishek@gmail.com>
Change-Id: I2f7fb4a8b0c9cd1a16d6c2b93602d285a191f170
---
 power/Android.bp                              |  3 +
 power/Power.cpp                               | 67 ++++++++++++++++++-
 ...ardware.power@1.3-service.xiaomi_sm6250.rc |  2 +-
 sepolicy/vendor/hal_power_default.te          |  3 +
 4 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 sepolicy/vendor/hal_power_default.te

diff --git a/power/Android.bp b/power/Android.bp
index 6beabdc..c268446 100644
--- a/power/Android.bp
+++ b/power/Android.bp
@@ -22,6 +22,9 @@ cc_binary {
         "Power.cpp",
         "service.cpp",
     ],
+    header_libs: [
+        "generated_kernel_headers",
+    ],
     shared_libs: [
         "liblog",
         "libhidlbase",
diff --git a/power/Power.cpp b/power/Power.cpp
index 134228d..8812cb3 100644
--- a/power/Power.cpp
+++ b/power/Power.cpp
@@ -16,8 +16,14 @@
 
 #define LOG_TAG "android.hardware.power@1.3-service.xiaomi_sm6250"
 
+#include <linux/input.h>
+
 #include "Power.h"
 
+constexpr static char const* inputDevicesDirectory = "/dev/input/";
+constexpr static int wakeupModeOn = 5;
+constexpr static int wakeupModeOff = 4;
+
 namespace android {
 namespace hardware {
 namespace power {
@@ -33,7 +39,66 @@ Return<void> Power::powerHint(PowerHint_1_0, int32_t) {
     return Void();
 }
 
-Return<void> Power::setFeature(Feature, bool) {
+bool isSupportedInputName(char* name) {
+    return false;
+}
+
+int openInputFd() {
+    DIR *dir = opendir(inputDevicesDirectory);
+    if (dir == NULL) {
+        return -1;
+    }
+
+    struct dirent *ent;
+    int fd;
+    int rc;
+
+    while ((ent = readdir(dir)) != NULL) {
+        if (ent->d_type != DT_CHR)
+            continue;
+
+        char absolute_path[PATH_MAX] = {0};
+        char name[80] = {0};
+
+        strcpy(absolute_path, inputDevicesDirectory);
+        strcat(absolute_path, ent->d_name);
+
+        fd = open(absolute_path, O_RDWR);
+        if (fd < 0)
+            continue;
+
+        rc = ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name);
+        if (rc > 0 && isSupportedInputName(name))
+            break;
+
+        close(fd);
+        fd = -1;
+    }
+
+    closedir(dir);
+
+    return fd;
+}
+
+Return<void> Power::setFeature(Feature feature, bool activate) {
+    switch (feature) {
+        case Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE: {
+            int fd = openInputFd();
+            if (fd < 0) {
+                ALOGW("No touchscreen input devices that support DT2W were found");
+                return Void();
+            }
+
+            struct input_event ev;
+            ev.type = EV_SYN;
+            ev.code = SYN_CONFIG;
+            ev.value = activate ? wakeupModeOn : wakeupModeOff;
+            write(fd, &ev, sizeof(ev));
+            close(fd);
+            } break;
+        default:
+            break;
+    }
     return Void();
 }
 
diff --git a/power/android.hardware.power@1.3-service.xiaomi_sm6250.rc b/power/android.hardware.power@1.3-service.xiaomi_sm6250.rc
index 0e67dde..4c63209 100644
--- a/power/android.hardware.power@1.3-service.xiaomi_sm6250.rc
+++ b/power/android.hardware.power@1.3-service.xiaomi_sm6250.rc
@@ -1,4 +1,4 @@
 service vendor.power-hal-1-0 /vendor/bin/hw/android.hardware.power@1.3-service.xiaomi_sm6250
     class hal
     user system
-    group system
+    group system input
diff --git a/sepolicy/vendor/hal_power_default.te b/sepolicy/vendor/hal_power_default.te
new file mode 100644
index 0000000..c2eac2f
--- /dev/null
+++ b/sepolicy/vendor/hal_power_default.te
@@ -0,0 +1,3 @@
+# Allow hal_power_default to write to dt2w nodes
+allow hal_power_default input_device:dir r_dir_perms;
+allow hal_power_default input_device:chr_file rw_file_perms;
-- 
GitLab