Pārlūkot izejas kodu

sm8450-common: Add nonui notifier

Change-Id: Id447dec0d6c6a384a55a25db45f2d763ba23635a
Arian 9 mēneši atpakaļ
vecāks
revīzija
e323e073d1

+ 3 - 0
common.mk

@@ -462,6 +462,9 @@ PRODUCT_PACKAGES += \
     [email protected]
 
 # Touchscreen
+PRODUCT_PACKAGES += \
+    nonui-notifier
+
 PRODUCT_COPY_FILES += \
     frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml
 

+ 29 - 0
sensors/Android.bp

@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2024 The LineageOS Project
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+
+cc_binary {
+    name: "nonui-notifier",
+    vendor: true,
+
+    init_rc: ["nonui-notifier.rc"],
+
+    srcs: [
+        "NonUiNotifier.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libutils",
+        "[email protected]",
+        "[email protected]",
+    ],
+
+    header_libs: [
+        "generated_kernel_headers",
+    ],
+}

+ 163 - 0
sensors/NonUiNotifier.cpp

@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "NonUiNotifier"
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+
+#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
+#include <android/frameworks/sensorservice/1.0/types.h>
+
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+#include <string>
+
+#include "xiaomi_touch.h"
+
+#define SENSOR_TYPE_XIAOMI_SENSOR_NONUI 33171027
+#define SENSOR_NAME_XIAOMI_SENSOR_NONUI "xiaomi.sensor.nonui"
+
+using ::android::frameworks::sensorservice::V1_0::IEventQueue;
+using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback;
+using ::android::frameworks::sensorservice::V1_0::ISensorManager;
+using ::android::frameworks::sensorservice::V1_0::Result;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::SensorType;
+
+using android::sp;
+
+#define TOUCH_DEV_PATH "/dev/xiaomi-touch"
+#define TOUCH_MAGIC 'T'
+#define TOUCH_IOC_SET_CUR_VALUE _IO(TOUCH_MAGIC, SET_CUR_VALUE)
+#define TOUCH_IOC_GET_CUR_VALUE _IO(TOUCH_MAGIC, GET_CUR_VALUE)
+
+namespace {
+
+static bool readBool(int fd) {
+    char c;
+    int rc;
+
+    rc = lseek(fd, 0, SEEK_SET);
+    if (rc) {
+        LOG(ERROR) << "failed to seek fd, err: " << rc;
+        return false;
+    }
+
+    rc = read(fd, &c, sizeof(char));
+    if (rc != 1) {
+        LOG(ERROR) << "failed to read bool from fd, err: " << rc;
+        return false;
+    }
+
+    return c != '0';
+}
+
+struct NonUiSensorCallback : IEventQueueCallback {
+    Return<void> onEvent(const Event& e) {
+        /* handle sensor event e */
+        LOG(ERROR) << "onEvent scalar: " << e.u.scalar;
+        bool nonUi = e.u.scalar == 1;
+
+        // android::base::unique_fd touch_fd_;
+        // touch_fd_ = android::base::unique_fd(open(TOUCH_DEV_PATH, O_RDWR));
+
+        int buf[MAX_BUF_SIZE] = {0, Touch_Nonui_Mode, nonUi ? 2 : 0};
+        ioctl(open(TOUCH_DEV_PATH, O_RDWR), TOUCH_IOC_SET_CUR_VALUE, &buf);
+
+        return Void();
+    }
+};
+
+}  // namespace
+
+int main() {
+    sp<ISensorManager> manager = ISensorManager::getService();
+    if (manager == nullptr) {
+        LOG(ERROR) << "failed to get ISensorManager";
+    }
+
+    int32_t sensorHandle = -1;
+    manager->getDefaultSensor(static_cast<SensorType>(SENSOR_TYPE_XIAOMI_SENSOR_NONUI),
+                              [&sensorHandle](const auto& info, auto r) {
+                                    sensorHandle = info.sensorHandle;
+                              });
+
+    sp<IEventQueue> queue;
+    Result res;
+    manager->createEventQueue(new NonUiSensorCallback(), [&queue, &res](const auto& q, auto r) {
+        queue = q;
+        res = r;
+    });
+    if (res != Result::OK) {
+        return EXIT_FAILURE;
+    }
+
+    // Enable states of touchscreen sensors
+    const std::vector<const char*> paths = {
+            "/sys/class/touch/touch_dev/fod_longpress_gesture_enabled",
+            "/sys/class/touch/touch_dev/gesture_single_tap_enabled",
+            "/sys/class/touch/touch_dev/gesture_double_tap_enabled"};
+
+    pollfd* pollfds = new pollfd[paths.size()];
+    for (size_t i = 0; i < paths.size(); ++i) {
+        int fd = open(paths[i], O_RDONLY);
+        if (fd < 0) {
+            LOG(ERROR) << "failed to open " << paths[i] << " , err: " << fd;
+            return EXIT_FAILURE;
+        }
+
+        pollfds[i].fd = fd;
+        pollfds[i].events = POLLERR | POLLPRI;
+        pollfds[i].revents = 0;
+    }
+
+    while (true) {
+        int rc = poll(pollfds, paths.size(), -1);
+        LOG(ERROR) << "poll: " << rc;
+        if (rc < 0) {
+            LOG(ERROR) << "failed to poll, err: " << rc;
+            continue;
+        }
+
+        for (size_t i = 0; i < paths.size(); ++i) {
+            if (pollfds[i].revents & (POLLERR | POLLPRI)) {
+                LOG(ERROR) << "Event on " << paths[i];
+            }
+        }
+
+        bool enabled = false;
+        for (size_t i = 0; i < paths.size(); ++i) {
+            enabled = enabled || readBool(pollfds[i].fd);
+        }
+        LOG(ERROR) << "got notified about poll, enabled: " << enabled;
+        if (enabled) {
+            res = queue->enableSensor(sensorHandle, 20000 /* sample period */, 0 /* latency */);
+            if (res != Result::OK) {
+                LOG(ERROR) << "failed to enable sensor";
+            }
+        } else {
+            res = queue->disableSensor(sensorHandle);
+            if (res != Result::OK) {
+                LOG(ERROR) << "failed to disable sensor";
+            }
+        }
+    }
+
+    /*
+     * Free the event queue.
+     * kernel calls decStrong() on server side implementation of IEventQueue,
+     * hence resources (including the callback) are freed as well.
+     */
+    queue = nullptr;
+
+    // Should never reach this
+    return EXIT_SUCCESS;
+}

+ 10 - 0
sensors/nonui-notifier.rc

@@ -0,0 +1,10 @@
+#
+# Copyright (C) 2024 The LineageOS Project
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+service vendor.nonui-notifier /vendor/bin/nonui-notifier
+   class main
+   user system
+   group system

+ 56 - 0
sensors/xiaomi_touch.h

@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+/*CUR,DEFAULT,MIN,MAX*/
+#define VALUE_TYPE_SIZE 6
+#define VALUE_GRIP_SIZE 9
+#define MAX_BUF_SIZE 256
+#define BTN_INFO 0x152
+#define MAX_TOUCH_ID 10
+#define RAW_BUF_NUM 4
+#define THP_CMD_BASE 1000
+
+enum MODE_CMD {
+    SET_CUR_VALUE = 0,
+    GET_CUR_VALUE,
+    GET_DEF_VALUE,
+    GET_MIN_VALUE,
+    GET_MAX_VALUE,
+    GET_MODE_VALUE,
+    RESET_MODE,
+    SET_LONG_VALUE,
+};
+
+enum MODE_TYPE {
+    Touch_Game_Mode = 0,
+    Touch_Active_MODE = 1,
+    Touch_UP_THRESHOLD = 2,
+    Touch_Tolerance = 3,
+    Touch_Aim_Sensitivity = 4,
+    Touch_Tap_Stability = 5,
+    Touch_Expert_Mode = 6,
+    Touch_Edge_Filter = 7,
+    Touch_Panel_Orientation = 8,
+    Touch_Report_Rate = 9,
+    Touch_Fod_Enable = 10,
+    Touch_Aod_Enable = 11,
+    Touch_Resist_RF = 12,
+    Touch_Idle_Time = 13,
+    Touch_Doubletap_Mode = 14,
+    Touch_Grip_Mode = 15,
+    Touch_FodIcon_Enable = 16,
+    Touch_Nonui_Mode = 17,
+    Touch_Debug_Level = 18,
+    Touch_Power_Status = 19,
+    Touch_Mode_NUM = 20,
+    THP_LOCK_SCAN_MODE = THP_CMD_BASE + 0,
+    THP_FOD_DOWNUP_CTL = THP_CMD_BASE + 1,
+    THP_SELF_CAP_SCAN = THP_CMD_BASE + 2,
+    THP_REPORT_POINT_SWITCH = THP_CMD_BASE + 3,
+    THP_HAL_INIT_READY = THP_CMD_BASE + 4,
+};

+ 1 - 0
sepolicy/vendor/file_contexts

@@ -81,6 +81,7 @@
 # Sensors
 /(vendor|system/vendor)/bin/hw/android\.hardware\[email protected]\.xiaomi-multihal u:object_r:hal_sensors_default_exec:s0
 /(vendor|system/vendor)/bin/hw/[email protected] u:object_r:vendor_hal_sensorcommunicate_default_exec:s0
+/(vendor|system/vendor)/bin/nonui-notifier u:object_r:vendor_nonui_notifier_exec:s0
 /dev/stmvl53l5 u:object_r:stmvl53l5_device:s0
 
 # Thermal

+ 17 - 0
sepolicy/vendor/vendor_nonui_notifier.te

@@ -0,0 +1,17 @@
+type vendor_nonui_notifier, domain;
+type vendor_nonui_notifier_exec, exec_type, file_type, vendor_file_type;
+
+init_daemon_domain(vendor_nonui_notifier)
+
+hwbinder_use(vendor_nonui_notifier)
+
+# for sensor callbacks
+binder_use(vendor_nonui_notifier)
+binder_call(vendor_nonui_notifier, system_server)
+binder_call(system_server, vendor_nonui_notifier)
+
+allow vendor_nonui_notifier fwk_sensor_hwservice:hwservice_manager find;
+allow vendor_nonui_notifier touchfeature_device:chr_file rw_file_perms;
+allow vendor_nonui_notifier vendor_sysfs_sensors:file r_file_perms;
+
+get_prop(vendor_nonui_notifier, hwservicemanager_prop)