From b9ef44eff2336a625e2fc4bae7ca515dd15d27b2 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 28 Jul 2024 17:37:41 +0200 Subject: [PATCH] sm8450-common: sensors: Introduce LightNotifier and use libssccalapi@2.0 Change-Id: Iec11aa1a8ccc13db5d30cc6fa52e4b10d255c706 --- sensors/Android.bp | 2 + sensors/include/SscCalApi.h | 46 +++++++ sensors/main.cpp | 6 + sensors/notifiers/LightNotifier.cpp | 150 ++++++++++++++++++++++ sensors/notifiers/LightNotifier.h | 24 ++++ sensors/utils/SscCalApiWrapper.cpp | 53 ++++++++ sepolicy/vendor/vendor_sensor_notifier.te | 6 + 7 files changed, 287 insertions(+) create mode 100644 sensors/include/SscCalApi.h create mode 100644 sensors/notifiers/LightNotifier.cpp create mode 100644 sensors/notifiers/LightNotifier.h create mode 100644 sensors/utils/SscCalApiWrapper.cpp diff --git a/sensors/Android.bp b/sensors/Android.bp index 1e6a9a6..b75db18 100644 --- a/sensors/Android.bp +++ b/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: [ diff --git a/sensors/include/SscCalApi.h b/sensors/include/SscCalApi.h new file mode 100644 index 0000000..53afa5b --- /dev/null +++ b/sensors/include/SscCalApi.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 The LineageOS Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +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; +}; diff --git a/sensors/main.cpp b/sensors/main.cpp index 6b787cb..9073d34 100644 --- a/sensors/main.cpp +++ b/sensors/main.cpp @@ -10,7 +10,9 @@ #include #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> notifiers; notifiers.push_back(std::make_unique(manager)); + notifiers.push_back(std::make_unique(manager)); notifiers.push_back(std::make_unique(manager)); for (const auto& notifier : notifiers) { notifier->activate(); diff --git a/sensors/notifiers/LightNotifier.cpp b/sensors/notifiers/LightNotifier.cpp new file mode 100644 index 0000000..f8aa69e --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +#include "SensorNotifierUtils.h" +#include "SscCalApi.h" + +static const std::string kDispFeatureDevice = "/dev/mi_display/disp_feature"; + +LightNotifier::LightNotifier(sp 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 displays; + if (!mLightSensorsPrimary.empty()) { + displays.push_back(MI_DISP_PRIMARY); + } + if (!mLightSensorsSecondary.empty()) { + displays.push_back(MI_DISP_SECONDARY); + } + + const std::vector 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& 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); + } + } +} diff --git a/sensors/notifiers/LightNotifier.h b/sensors/notifiers/LightNotifier.h new file mode 100644 index 0000000..e4030e8 --- /dev/null +++ b/sensors/notifiers/LightNotifier.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The LineageOS Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#include "SensorNotifier.h" + +class LightNotifier : public SensorNotifier { + public: + LightNotifier(sp manager); + ~LightNotifier(); + + protected: + void notify(); + + private: + std::vector mLightSensorsPrimary; + std::vector mLightSensorsSecondary; +}; diff --git a/sensors/utils/SscCalApiWrapper.cpp b/sensors/utils/SscCalApiWrapper.cpp new file mode 100644 index 0000000..e631bf4 --- /dev/null +++ b/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 +#include + +SscCalApiWrapper::SscCalApiWrapper() { + mSscCalApiHandle = dlopen("libssccalapi@2.0.so", 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 libssccalapi@2.0.so: " << 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); + } +} diff --git a/sepolicy/vendor/vendor_sensor_notifier.te b/sepolicy/vendor/vendor_sensor_notifier.te index 891fcbf..16c9d15 100644 --- a/sepolicy/vendor/vendor_sensor_notifier.te +++ b/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 libssccalapi@2.0 +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)');