Przeglądaj źródła

sm8450-common: sensors: Convert nonui notifier into a generalized sensor based notifier

Change-Id: I34b9861341f4f033185fdbd066b46d779dd95cfa
Arian 7 miesięcy temu
rodzic
commit
2f0a1200a2

+ 4 - 0
BoardConfigCommon.mk

@@ -221,6 +221,10 @@ SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/private
 SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/public
 BOARD_VENDOR_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/vendor
 
+# Sensors
+TARGET_SENSOR_NOTIFIER_EXT ?= libsensor-notifier-ext
+$(call soong_config_set, xiaomiSm8450SensorVars, extensionLibs, $(TARGET_SENSOR_NOTIFIER_EXT))
+
 # VINTF
 DEVICE_MATRIX_FILE := hardware/qcom-caf/common/compatibility_matrix.xml
 

+ 3 - 3
common.mk

@@ -424,6 +424,9 @@ PRODUCT_PACKAGES += \
     [email protected] \
     [email protected]
 
+PRODUCT_PACKAGES += \
+    sensor-notifier
+
 $(foreach sku, taro diwali cape ukee, \
     $(eval PRODUCT_COPY_FILES += \
         frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/sku_$(sku)/android.hardware.sensor.accelerometer.xml \
@@ -476,9 +479,6 @@ 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
 

+ 52 - 3
sensors/Android.bp

@@ -4,14 +4,45 @@
 // SPDX-License-Identifier: Apache-2.0
 //
 
+soong_config_module_type {
+    name: "xiaomi_sm8450_sensor_notifier",
+    module_type: "cc_defaults",
+    config_namespace: "xiaomiSm8450SensorVars",
+    value_variables: ["extensionLibs"],
+    properties: [
+        "whole_static_libs",
+    ],
+}
+
+xiaomi_sm8450_sensor_notifier {
+    name: "xiaomi_sm8450_sensor_notifier_defaults",
+    soong_config_variables: {
+        extensionLibs: {
+            whole_static_libs: ["%s"],
+        },
+    },
+}
+
+cc_library_headers {
+    name: "xiaomi_sm8450_sensor_notifier_headers",
+    export_include_dirs: ["include"],
+    vendor: true,
+}
+
 cc_binary {
-    name: "nonui-notifier",
+    name: "sensor-notifier",
+    defaults: [
+        "xiaomi_sm8450_sensor_notifier_defaults",
+    ],
     vendor: true,
 
-    init_rc: ["nonui-notifier.rc"],
+    init_rc: ["sensor-notifier.rc"],
 
     srcs: [
-        "NonUiNotifier.cpp",
+        "main.cpp",
+        "notifiers/NonUiNotifier.cpp",
+        "SensorNotifier.cpp",
+        "utils/SensorNotifierUtils.cpp",
     ],
 
     shared_libs: [
@@ -23,5 +54,23 @@ cc_binary {
 
     header_libs: [
         "generated_kernel_headers",
+        "xiaomi_sm8450_sensor_notifier_headers",
+    ],
+}
+
+cc_library_static {
+    name: "libsensor-notifier-ext",
+    vendor: true,
+
+    srcs: [
+        "SensorNotifierExt.cpp",
+    ],
+
+    shared_libs: [
+        "[email protected]",
+    ],
+
+    header_libs: [
+        "xiaomi_sm8450_sensor_notifier_headers",
     ],
 }

+ 0 - 174
sensors/NonUiNotifier.cpp

@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2024 The LineageOS Project
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-
-#define LOG_TAG "NonUiNotifier"
-
-#include <android-base/logging.h>
-#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
-
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/ioctl.h>
-
-#include <linux/xiaomi_touch.h>
-
-#define SENSOR_NAME_XIAOMI_SENSOR_NONUI "xiaomi.sensor.nonui"
-
-using android::sp;
-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::SensorFlagBits;
-using android::hardware::sensors::V1_0::SensorInfo;
-using android::hardware::sensors::V1_0::SensorType;
-
-#define TOUCH_DEV_PATH "/dev/xiaomi-touch"
-
-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) {
-        int touchFd = open(TOUCH_DEV_PATH, O_RDWR);
-        if (touchFd == -1) {
-            LOG(ERROR) << "failed to open " << TOUCH_DEV_PATH;
-            return Void();
-        }
-
-        int buf[MAX_BUF_SIZE] = {0, Touch_Nonui_Mode, static_cast<int>(e.u.scalar)};
-        ioctl(touchFd, TOUCH_IOC_SET_CUR_VALUE, &buf);
-        close(touchFd);
-
-        return Void();
-    }
-};
-
-}  // namespace
-
-int main() {
-    Result res;
-    sp<IEventQueue> queue;
-
-    sp<ISensorManager> manager = ISensorManager::getService();
-    if (manager == nullptr) {
-        LOG(ERROR) << "failed to get ISensorManager";
-        return EXIT_FAILURE;
-    }
-
-    std::vector<SensorInfo> sensorList;
-    manager->getSensorList([&sensorList, &res](const auto& l, auto r) {
-        sensorList = l;
-        res = r;
-    });
-    if (res != Result::OK) {
-        LOG(ERROR) << "failed to get getSensorList";
-        return EXIT_FAILURE;
-    }
-    auto it = std::find_if(sensorList.begin(), sensorList.end(), [](const SensorInfo& sensor) {
-        return (sensor.typeAsString == SENSOR_NAME_XIAOMI_SENSOR_NONUI) &&
-               (sensor.flags & SensorFlagBits::WAKE_UP);
-    });
-
-    int32_t sensorHandle = -1;
-    if (it != sensorList.end()) {
-        sensorHandle = it->sensorHandle;
-    } else {
-        LOG(ERROR) << "failed to get wake-up version of nonui sensor";
-        return EXIT_FAILURE;
-    }
-
-    sensorList.clear();
-
-    manager->createEventQueue(new NonUiSensorCallback(), [&queue, &res](const auto& q, auto r) {
-        queue = q;
-        res = r;
-    });
-    if (res != Result::OK) {
-        LOG(ERROR) << "failed to create event queue";
-        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);
-        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(VERBOSE) << "polled change on " << paths[i];
-            }
-        }
-
-        bool enabled = false;
-        for (size_t i = 0; i < paths.size(); ++i) {
-            enabled = enabled || readBool(pollfds[i].fd);
-        }
-        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;
-}

+ 86 - 0
sensors/SensorNotifier.cpp

@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "SensorNotifier"
+
+#include "SensorNotifier.h"
+
+#include <android-base/logging.h>
+
+using android::hardware::sensors::V1_0::SensorFlagBits;
+using android::hardware::sensors::V1_0::SensorInfo;
+
+SensorNotifier::SensorNotifier(sp<ISensorManager> manager) : mManager(manager) {}
+
+SensorNotifier::~SensorNotifier() {
+    if (mQueue != nullptr) {
+        /*
+         * Free the event queue.
+         * kernel calls decStrong() on server side implementation of IEventQueue,
+         * hence resources (including the callback) are freed as well.
+         */
+        mQueue = nullptr;
+    }
+}
+
+Result SensorNotifier::initializeSensorQueue(std::string typeAsString, bool wakeup,
+                                             sp<IEventQueueCallback> callback) {
+    Result res;
+    std::vector<SensorInfo> sensorList;
+
+    mManager->getSensorList([&sensorList, &res](const auto& l, auto r) {
+        sensorList = l;
+        res = r;
+    });
+    if (res != Result::OK) {
+        LOG(ERROR) << "failed to get sensors list";
+        return res;
+    }
+    auto it = std::find_if(sensorList.begin(), sensorList.end(),
+                           [this, &typeAsString, &wakeup](const SensorInfo& sensor) {
+                               return (sensor.typeAsString == typeAsString) &&
+                                      ((sensor.flags & SensorFlagBits::WAKE_UP) == wakeup);
+                           });
+
+    if (it != sensorList.end()) {
+        mSensorHandle = it->sensorHandle;
+    } else {
+        LOG(ERROR) << "failed to get " << typeAsString << " sensor with wake-up: " << wakeup;
+        return Result::NOT_EXIST;
+    }
+
+    mManager->createEventQueue(callback, [this, &res](const auto& q, auto r) {
+        this->mQueue = q;
+        res = r;
+    });
+    if (res != Result::OK) {
+        LOG(ERROR) << "failed to create event queue";
+        return res;
+    }
+
+    return Result::OK;
+}
+
+void SensorNotifier::activate() {
+    if (mActive) {
+        return;
+    }
+    mActive = true;
+    mThread = std::thread(&SensorNotifier::notify, this);
+}
+
+void SensorNotifier::deactivate() {
+    if (!mActive) {
+        return;
+    }
+    mActive = false;
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+    if (mQueue != nullptr) {
+        mQueue->disableSensor(mSensorHandle);
+    }
+}

+ 9 - 0
sensors/SensorNotifierExt.cpp

@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "SensorNotifierExt.h"
+
+SensorNotifierExt::SensorNotifierExt(sp<ISensorManager> /* manager */) {}

+ 37 - 0
sensors/include/SensorNotifier.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
+#include <thread>
+
+using android::sp;
+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;
+
+class SensorNotifier {
+  public:
+    SensorNotifier(sp<ISensorManager> manager);
+    virtual ~SensorNotifier();
+
+    void activate();
+    void deactivate();
+
+  protected:
+    Result initializeSensorQueue(std::string typeAsString, bool wakeup, sp<IEventQueueCallback>);
+    virtual void notify() = 0;
+
+    sp<IEventQueue> mQueue;
+    int32_t mSensorHandle = -1;
+    bool mActive = false;
+
+  private:
+    sp<ISensorManager> mManager;
+    std::thread mThread;
+};

+ 20 - 0
sensors/include/SensorNotifierExt.h

@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
+
+#include "SensorNotifier.h"
+
+using android::sp;
+using android::frameworks::sensorservice::V1_0::ISensorManager;
+
+class SensorNotifierExt {
+  public:
+    SensorNotifierExt(sp<ISensorManager> manager);
+    std::vector<std::unique_ptr<SensorNotifier>> mNotifiers;
+};

+ 9 - 0
sensors/include/SensorNotifierUtils.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+bool readBool(int fd);

+ 41 - 0
sensors/main.cpp

@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "SensorNotifier"
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+
+#include "SensorNotifierExt.h"
+#include "notifiers/NonUiNotifier.h"
+
+int main() {
+    sp<ISensorManager> manager = ISensorManager::getService();
+    if (manager == nullptr) {
+        LOG(ERROR) << "failed to get ISensorManager";
+        return EXIT_FAILURE;
+    }
+
+    std::vector<std::unique_ptr<SensorNotifier>> notifiers;
+    notifiers.push_back(std::make_unique<NonUiNotifier>(manager));
+    for (const auto& notifier : notifiers) {
+        notifier->activate();
+    }
+
+    std::unique_ptr<SensorNotifierExt> sensorNotifierExt =
+            std::make_unique<SensorNotifierExt>(manager);
+    for (const auto& notifier : sensorNotifierExt->mNotifiers) {
+        notifier->activate();
+    }
+
+    while (true) {
+        // Sleep to keep the notifiers alive
+        std::this_thread::sleep_for(std::chrono::seconds(10));
+    }
+
+    // Should never reach this
+    return EXIT_SUCCESS;
+}

+ 102 - 0
sensors/notifiers/NonUiNotifier.cpp

@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "NonUiNotifier"
+
+#include "NonUiNotifier.h"
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <linux/xiaomi_touch.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+
+#include "SensorNotifierUtils.h"
+
+static const std::string kTouchDevice = "/dev/xiaomi-touch";
+
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::sensors::V1_0::Event;
+
+namespace {
+
+class NonUiSensorCallback : public IEventQueueCallback {
+  public:
+    NonUiSensorCallback() {
+        touch_fd_ = android::base::unique_fd(open(kTouchDevice.c_str(), O_RDWR));
+        if (touch_fd_.get() == -1) {
+            LOG(ERROR) << "failed to open " << kTouchDevice;
+        }
+    }
+
+    Return<void> onEvent(const Event& e) {
+        int buf[MAX_BUF_SIZE] = {0, Touch_Nonui_Mode, static_cast<int>(e.u.scalar)};
+        ioctl(touch_fd_.get(), TOUCH_IOC_SET_CUR_VALUE, &buf);
+
+        return Void();
+    }
+
+  private:
+    android::base::unique_fd touch_fd_;
+};
+
+}  // namespace
+
+NonUiNotifier::NonUiNotifier(sp<ISensorManager> manager) : SensorNotifier(manager) {
+    initializeSensorQueue("xiaomi.sensor.nonui", true, new NonUiSensorCallback());
+}
+
+NonUiNotifier::~NonUiNotifier() {
+    deactivate();
+}
+
+void NonUiNotifier::notify() {
+    Result res;
+
+    // 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;
+            mActive = false;
+            return;
+        }
+
+        pollfds[i].fd = fd;
+        pollfds[i].events = POLLPRI;
+    }
+
+    while (mActive) {
+        int rc = poll(pollfds, paths.size(), -1);
+        if (rc < 0) {
+            LOG(ERROR) << "failed to poll, err: " << rc;
+            continue;
+        }
+
+        bool enabled = false;
+        for (size_t i = 0; i < paths.size(); ++i) {
+            enabled = enabled || readBool(pollfds[i].fd);
+        }
+        if (enabled) {
+            res = mQueue->enableSensor(mSensorHandle, 20000 /* sample period */, 0 /* latency */);
+            if (res != Result::OK) {
+                LOG(ERROR) << "failed to enable sensor";
+            }
+        } else {
+            res = mQueue->disableSensor(mSensorHandle);
+            if (res != Result::OK) {
+                LOG(DEBUG) << "failed to disable sensor";
+            }
+        }
+    }
+}

+ 18 - 0
sensors/notifiers/NonUiNotifier.h

@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "SensorNotifier.h"
+
+class NonUiNotifier : public SensorNotifier {
+  public:
+    NonUiNotifier(sp<ISensorManager> manager);
+    ~NonUiNotifier();
+
+  protected:
+    void notify();
+};

+ 1 - 1
sensors/nonui-notifier.rc → sensors/sensor-notifier.rc

@@ -4,7 +4,7 @@
 # SPDX-License-Identifier: Apache-2.0
 #
 
-service vendor.nonui-notifier /vendor/bin/nonui-notifier
+service vendor.sensor-notifier /vendor/bin/sensor-notifier
    class main
    user system
    group system

+ 30 - 0
sensors/utils/SensorNotifierUtils.cpp

@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "SensorNotifierUtils"
+
+#include "SensorNotifierUtils.h"
+
+#include <android-base/logging.h>
+
+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';
+}

+ 1 - 1
sepolicy/vendor/file_contexts

@@ -81,7 +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
+/(vendor|system/vendor)/bin/sensor-notifier u:object_r:vendor_sensor_notifier_exec:s0
 /dev/stmvl53l5 u:object_r:stmvl53l5_device:s0
 
 # Thermal

+ 0 - 17
sepolicy/vendor/vendor_nonui_notifier.te

@@ -1,17 +0,0 @@
-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)

+ 17 - 0
sepolicy/vendor/vendor_sensor_notifier.te

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