Browse Source

sm8450-common: sensors: Introduce LightNotifier and use [email protected]

Change-Id: Iec11aa1a8ccc13db5d30cc6fa52e4b10d255c706
Arian 11 months ago
parent
commit
1452dd82ea

+ 2 - 0
sensors/Android.bp

@@ -41,9 +41,11 @@ cc_binary {
     srcs: [
         "main.cpp",
         "notifiers/AodNotifier.cpp",
+        "notifiers/LightNotifier.cpp",
         "notifiers/NonUiNotifier.cpp",
         "SensorNotifier.cpp",
         "utils/SensorNotifierUtils.cpp",
+        "utils/SscCalApiWrapper.cpp",
     ],
 
     shared_libs: [

+ 46 - 0
sensors/include/SscCalApi.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <cstdint>
+
+enum notify_t {
+    BRIGHTNESS = 17,
+    DC_STATE = 18,
+    DISPLAY_FREQUENCY = 20,
+    REPORT_VALUE = 201,
+    POWER_STATE = 202,
+};
+
+struct _oem_msg {
+    uint32_t sensorType;
+    notify_t notifyType;
+    float unknown1;
+    float unknown2;
+    float notifyTypeFloat;
+    float value;
+    float unused[10];
+};
+
+typedef void (*init_current_sensors_t)(bool debug);
+typedef void (*process_msg_t)(_oem_msg* msg);
+
+class SscCalApiWrapper {
+  public:
+    static SscCalApiWrapper& getInstance();
+
+    void initCurrentSensors(bool debug);
+    void processMsg(_oem_msg* msg);
+
+  private:
+    SscCalApiWrapper();
+    ~SscCalApiWrapper();
+
+    void* mSscCalApiHandle;
+    process_msg_t process_msg;
+    init_current_sensors_t init_current_sensors;
+};

+ 6 - 0
sensors/main.cpp

@@ -10,7 +10,9 @@
 #include <android-base/properties.h>
 
 #include "SensorNotifierExt.h"
+#include "SscCalApi.h"
 #include "notifiers/AodNotifier.h"
+#include "notifiers/LightNotifier.h"
 #include "notifiers/NonUiNotifier.h"
 
 int main() {
@@ -20,8 +22,12 @@ int main() {
         return EXIT_FAILURE;
     }
 
+    SscCalApiWrapper::getInstance().initCurrentSensors(
+            android::base::GetBoolProperty("persist.vendor.debug.ssccalapi", false));
+
     std::vector<std::unique_ptr<SensorNotifier>> notifiers;
     notifiers.push_back(std::make_unique<AodNotifier>(manager));
+    notifiers.push_back(std::make_unique<LightNotifier>(manager));
     notifiers.push_back(std::make_unique<NonUiNotifier>(manager));
     for (const auto& notifier : notifiers) {
         notifier->activate();

+ 150 - 0
sensors/notifiers/LightNotifier.cpp

@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "LightNotifier"
+
+#include "LightNotifier.h"
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+#include <display/drm/mi_disp.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+
+#include "SensorNotifierUtils.h"
+#include "SscCalApi.h"
+
+static const std::string kDispFeatureDevice = "/dev/mi_display/disp_feature";
+
+LightNotifier::LightNotifier(sp<ISensorManager> manager) : SensorNotifier(manager) {
+    std::stringstream lightSensorsPrimary(
+            android::base::GetProperty("ro.vendor.sensors.notifier.light_sensors.primary", ""));
+    std::stringstream lightSensorsSecondary(
+            android::base::GetProperty("ro.vendor.sensors.notifier.light_sensors.secondary", ""));
+
+    std::string sensor;
+    while (std::getline(lightSensorsPrimary, sensor, ',')) {
+        mLightSensorsPrimary.push_back(std::stoi(sensor));
+    }
+    while (std::getline(lightSensorsSecondary, sensor, ',')) {
+        mLightSensorsSecondary.push_back(std::stoi(sensor));
+    }
+}
+
+LightNotifier::~LightNotifier() {
+    deactivate();
+}
+
+void LightNotifier::notify() {
+    if (mLightSensorsPrimary.empty() && mLightSensorsSecondary.empty()) {
+        LOG(DEBUG) << "no light sensors to notify defined, skip light notifications";
+        mActive = false;
+        return;
+    }
+
+    android::base::unique_fd disp_fd_ =
+            android::base::unique_fd(open(kDispFeatureDevice.c_str(), O_RDWR));
+    if (disp_fd_.get() == -1) {
+        LOG(ERROR) << "failed to open " << kDispFeatureDevice;
+        mActive = false;
+        return;
+    }
+
+    std::vector<disp_display_type> displays;
+    if (!mLightSensorsPrimary.empty()) {
+        displays.push_back(MI_DISP_PRIMARY);
+    }
+    if (!mLightSensorsSecondary.empty()) {
+        displays.push_back(MI_DISP_SECONDARY);
+    }
+
+    const std::vector<disp_event_type> notifyEvents = {MI_DISP_EVENT_POWER, MI_DISP_EVENT_FPS,
+                                                       MI_DISP_EVENT_51_BRIGHTNESS,
+                                                       MI_DISP_EVENT_HBM, MI_DISP_EVENT_DC};
+
+    // Register for events
+    for (const disp_display_type& display : displays) {
+        for (const disp_event_type& event : notifyEvents) {
+            disp_event_req req;
+            req.base.flag = 0;
+            req.base.disp_id = display;
+            req.type = event;
+            ioctl(disp_fd_.get(), MI_DISP_IOCTL_REGISTER_EVENT, &req);
+        }
+    }
+
+    struct pollfd dispEventPoll = {
+            .fd = disp_fd_.get(),
+            .events = POLLIN,
+    };
+
+    _oem_msg* msg = new _oem_msg;
+    notify_t notifyType;
+    float value;
+
+    while (mActive) {
+        int rc = poll(&dispEventPoll, 1, -1);
+        if (rc < 0) {
+            LOG(ERROR) << "failed to poll " << kDispFeatureDevice << ", err: " << rc;
+            continue;
+        }
+
+        struct disp_event_resp* response = parseDispEvent(disp_fd_.get());
+        if (response == nullptr) {
+            continue;
+        }
+
+        std::vector<int>& sensorsToNotify = mLightSensorsPrimary;
+        switch (response->base.disp_id) {
+            case MI_DISP_PRIMARY:
+                break;
+            case MI_DISP_SECONDARY:
+                sensorsToNotify = mLightSensorsSecondary;
+                break;
+            default:
+                LOG(ERROR) << "got notified for unknown display: " << response->base.disp_id;
+                continue;
+        }
+
+        switch (response->base.type) {
+            case MI_DISP_EVENT_POWER:
+                notifyType = POWER_STATE;
+                value = response->data[0];
+                break;
+            case MI_DISP_EVENT_FPS:
+                notifyType = DISPLAY_FREQUENCY;
+                value = response->data[0];
+                break;
+            case MI_DISP_EVENT_51_BRIGHTNESS:
+                notifyType = BRIGHTNESS;
+                value = *(uint16_t*)response->data;
+                break;
+            case MI_DISP_EVENT_HBM:
+                notifyType = BRIGHTNESS;
+                value = response->data[0] ? -1 : -2;
+                break;
+            case MI_DISP_EVENT_DC:
+                notifyType = DC_STATE;
+                value = response->data[0];
+                break;
+            default:
+                LOG(ERROR) << "got unknown event: " << response->base.type;
+                continue;
+        };
+
+        for (const auto sensorId : sensorsToNotify) {
+            msg->sensorType = sensorId;
+            msg->notifyType = notifyType;
+            msg->notifyTypeFloat = notifyType;
+            msg->value = value;
+            msg->unknown1 = 1;
+            msg->unknown2 = 5;
+
+            SscCalApiWrapper::getInstance().processMsg(msg);
+        }
+    }
+}

+ 24 - 0
sensors/notifiers/LightNotifier.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <android-base/unique_fd.h>
+
+#include "SensorNotifier.h"
+
+class LightNotifier : public SensorNotifier {
+  public:
+    LightNotifier(sp<ISensorManager> manager);
+    ~LightNotifier();
+
+  protected:
+    void notify();
+
+  private:
+    std::vector<int> mLightSensorsPrimary;
+    std::vector<int> mLightSensorsSecondary;
+};

+ 53 - 0
sensors/utils/SscCalApiWrapper.cpp

@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "SscCalApiWrapper"
+
+#include "SscCalApi.h"
+
+#include <android-base/logging.h>
+#include <dlfcn.h>
+
+SscCalApiWrapper::SscCalApiWrapper() {
+    mSscCalApiHandle = dlopen("[email protected]", RTLD_NOW);
+    if (mSscCalApiHandle) {
+        init_current_sensors =
+                (init_current_sensors_t)dlsym(mSscCalApiHandle, "_Z20init_current_sensorsb");
+        if (init_current_sensors == NULL) {
+            LOG(ERROR) << "could not find init_current_sensors: " << dlerror();
+        }
+
+        process_msg = (process_msg_t)dlsym(mSscCalApiHandle, "_Z11process_msgP8_oem_msg");
+        if (process_msg == NULL) {
+            LOG(ERROR) << "could not find process_msg: " << dlerror();
+        }
+    } else {
+        LOG(INFO) << "could not dlopen [email protected]: " << dlerror();
+    }
+}
+
+SscCalApiWrapper::~SscCalApiWrapper() {
+    dlclose(mSscCalApiHandle);
+}
+
+SscCalApiWrapper& SscCalApiWrapper::getInstance() {
+    static SscCalApiWrapper instance;
+    return instance;
+}
+
+void SscCalApiWrapper::initCurrentSensors(bool debug) {
+    if (init_current_sensors != NULL) {
+        init_current_sensors(debug);
+    }
+}
+
+void SscCalApiWrapper::processMsg(_oem_msg* msg) {
+    if (process_msg != NULL) {
+        LOG(DEBUG) << "sending oem_msg for sensor " << msg->sensorType
+                   << " with type: " << msg->notifyType << " and value: " << msg->value;
+        process_msg(msg);
+    }
+}

+ 6 - 0
sepolicy/vendor/vendor_sensor_notifier.te

@@ -15,4 +15,10 @@ allow vendor_sensor_notifier touchfeature_device:chr_file rw_file_perms;
 allow vendor_sensor_notifier vendor_displayfeature_device:chr_file rw_file_perms;
 allow vendor_sensor_notifier vendor_sysfs_sensors:file r_file_perms;
 
+# for [email protected]
+allow vendor_sensor_notifier self:{ socket qipcrtr_socket} create_socket_perms;
+allowxperm vendor_sensor_notifier self:{ socket qipcrtr_socket} ioctl msm_sock_ipc_ioctls;
+
 get_prop(vendor_sensor_notifier, hwservicemanager_prop)
+get_prop(vendor_sensor_notifier, vendor_sensors_prop)
+userdebug_or_eng(`get_prop(vendor_sensor_notifier, vendor_sensors_debug_prop)');