From 9148fcdc2c35d3fae912ba44cfaaa54887b0154e Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 27 Jul 2024 16:06:00 +0200 Subject: [PATCH] sm8450-common: sensors: Add aod notifier Change-Id: I2ba35d7b7db4e6922d83f041497fe66bf52124cb --- sensors/Android.bp | 1 + sensors/include/SensorNotifierUtils.h | 3 + sensors/main.cpp | 2 + sensors/notifiers/AodNotifier.cpp | 128 ++++++++++++++++++++++ sensors/notifiers/AodNotifier.h | 18 +++ sensors/utils/SensorNotifierUtils.cpp | 27 +++++ sepolicy/vendor/vendor_sensor_notifier.te | 1 + 7 files changed, 180 insertions(+) create mode 100644 sensors/notifiers/AodNotifier.cpp create mode 100644 sensors/notifiers/AodNotifier.h diff --git a/sensors/Android.bp b/sensors/Android.bp index 856e112..1e6a9a6 100644 --- a/sensors/Android.bp +++ b/sensors/Android.bp @@ -40,6 +40,7 @@ cc_binary { srcs: [ "main.cpp", + "notifiers/AodNotifier.cpp", "notifiers/NonUiNotifier.cpp", "SensorNotifier.cpp", "utils/SensorNotifierUtils.cpp", diff --git a/sensors/include/SensorNotifierUtils.h b/sensors/include/SensorNotifierUtils.h index 400e9d4..5bd2679 100644 --- a/sensors/include/SensorNotifierUtils.h +++ b/sensors/include/SensorNotifierUtils.h @@ -6,4 +6,7 @@ #pragma once +#include + bool readBool(int fd); +disp_event_resp* parseDispEvent(int fd); diff --git a/sensors/main.cpp b/sensors/main.cpp index 2b094e5..6b787cb 100644 --- a/sensors/main.cpp +++ b/sensors/main.cpp @@ -10,6 +10,7 @@ #include #include "SensorNotifierExt.h" +#include "notifiers/AodNotifier.h" #include "notifiers/NonUiNotifier.h" int main() { @@ -20,6 +21,7 @@ int main() { } std::vector> notifiers; + 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/AodNotifier.cpp b/sensors/notifiers/AodNotifier.cpp new file mode 100644 index 0000000..7428969 --- /dev/null +++ b/sensors/notifiers/AodNotifier.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2024 The LineageOS Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_TAG "AodNotifier" + +#include "AodNotifier.h" + +#include +#include +#include +#include +#include + +#include "SensorNotifierUtils.h" + +static const std::string kDispFeatureDevice = "/dev/mi_display/disp_feature"; + +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::sensors::V1_0::Event; + +namespace { + +void requestDozeBrightness(int fd, __u32 doze_brightness) { + disp_doze_brightness_req req; + req.base.flag = 0; + req.base.disp_id = MI_DISP_PRIMARY; + req.doze_brightness = doze_brightness; + ioctl(fd, MI_DISP_IOCTL_SET_DOZE_BRIGHTNESS, &req); +} + +class AodSensorCallback : public IEventQueueCallback { + public: + AodSensorCallback() { + disp_fd_ = android::base::unique_fd(open(kDispFeatureDevice.c_str(), O_RDWR)); + if (disp_fd_.get() == -1) { + LOG(ERROR) << "failed to open " << kDispFeatureDevice; + } + } + + Return onEvent(const Event& e) { + requestDozeBrightness(disp_fd_.get(), (e.u.scalar == 3 || e.u.scalar == 5) + ? DOZE_BRIGHTNESS_LBM + : DOZE_BRIGHTNESS_HBM); + return Void(); + } + + private: + android::base::unique_fd disp_fd_; +}; + +} // namespace + +AodNotifier::AodNotifier(sp manager) : SensorNotifier(manager) { + initializeSensorQueue("xiaomi.sensor.aod", true, new AodSensorCallback()); +} + +AodNotifier::~AodNotifier() { + deactivate(); +} + +void AodNotifier::notify() { + Result res; + + 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; + } + + // Register for power events + disp_event_req req; + req.base.flag = 0; + req.base.disp_id = MI_DISP_PRIMARY; + req.type = MI_DISP_EVENT_POWER; + ioctl(disp_fd_.get(), MI_DISP_IOCTL_REGISTER_EVENT, &req); + + struct pollfd dispEventPoll = { + .fd = disp_fd_.get(), + .events = POLLIN, + .revents = 0, + }; + + 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; + } + + if (response->base.type != MI_DISP_EVENT_POWER) { + LOG(ERROR) << "unexpected display event: " << response->base.type; + continue; + } + + int value = response->data[0]; + LOG(VERBOSE) << "received data: " << std::bitset<8>(value); + + switch (response->data[0]) { + case MI_DISP_POWER_LP1: + FALLTHROUGH_INTENDED; + case MI_DISP_POWER_LP2: + res = mQueue->enableSensor(mSensorHandle, 20000 /* sample period */, + 0 /* latency */); + if (res != Result::OK) { + LOG(ERROR) << "failed to enable sensor"; + } + break; + case MI_DISP_POWER_ON: + requestDozeBrightness(disp_fd_.get(), DOZE_TO_NORMAL); + FALLTHROUGH_INTENDED; + default: + res = mQueue->disableSensor(mSensorHandle); + if (res != Result::OK) { + LOG(DEBUG) << "failed to disable sensor"; + } + break; + } + } +} diff --git a/sensors/notifiers/AodNotifier.h b/sensors/notifiers/AodNotifier.h new file mode 100644 index 0000000..b23dd42 --- /dev/null +++ b/sensors/notifiers/AodNotifier.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2024 The LineageOS Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "SensorNotifier.h" + +class AodNotifier : public SensorNotifier { + public: + AodNotifier(sp manager); + ~AodNotifier(); + + protected: + void notify(); +}; diff --git a/sensors/utils/SensorNotifierUtils.cpp b/sensors/utils/SensorNotifierUtils.cpp index 5775fd6..b60c577 100644 --- a/sensors/utils/SensorNotifierUtils.cpp +++ b/sensors/utils/SensorNotifierUtils.cpp @@ -28,3 +28,30 @@ bool readBool(int fd) { return c != '0'; } + +disp_event_resp* parseDispEvent(int fd) { + disp_event header; + ssize_t headerSize = read(fd, &header, sizeof(header)); + if (headerSize < sizeof(header)) { + LOG(ERROR) << "unexpected display event header size: " << headerSize; + return nullptr; + } + + struct disp_event_resp* response = + reinterpret_cast(malloc(header.length)); + response->base = header; + + int dataLength = response->base.length - sizeof(response->base); + if (dataLength < 0) { + LOG(ERROR) << "invalid data length: " << response->base.length; + return nullptr; + } + + ssize_t dataSize = read(fd, &response->data, dataLength); + if (dataSize < dataLength) { + LOG(ERROR) << "unexpected display event data size: " << dataSize; + return nullptr; + } + + return response; +} diff --git a/sepolicy/vendor/vendor_sensor_notifier.te b/sepolicy/vendor/vendor_sensor_notifier.te index d7d4a77..891fcbf 100644 --- a/sepolicy/vendor/vendor_sensor_notifier.te +++ b/sepolicy/vendor/vendor_sensor_notifier.te @@ -12,6 +12,7 @@ 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_displayfeature_device:chr_file rw_file_perms; allow vendor_sensor_notifier vendor_sysfs_sensors:file r_file_perms; get_prop(vendor_sensor_notifier, hwservicemanager_prop)