From 19f1c1d6f0143fbdadeadea7eedcdb0723678423 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sun, 20 Feb 2022 19:34:44 +0200 Subject: [PATCH] eqs: sensors: Create input event polling one shot sensor * for double tap to wake in screen off and in aod Co-authored-by: SGCMarkus Change-Id: Ie78d7729201836bacd65a57f76e22adb61159192 --- BoardConfig.mk | 5 - device.mk | 2 +- .../eqs/Frameworks/res/values/config.xml | 4 +- sensors/Android.bp | 5 +- sensors/Sensor.cpp | 200 ++++++++++++++++++ sensors/Sensor.h | 29 +++ sensors/SensorsSubHal.cpp | 4 +- sensors/hals.conf | 2 +- 8 files changed, 239 insertions(+), 12 deletions(-) diff --git a/BoardConfig.mk b/BoardConfig.mk index 2027b10..e4401e9 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -65,11 +65,6 @@ endif BOARD_MOT_DP_GROUP_SIZE := 11806965760 # ( BOARD_SUPER_PARTITION_SIZE - 4MB ) BOARD_SUPER_PARTITION_SIZE := 11811160064 -# Power -TARGET_TAP_TO_WAKE_NODE := "/sys/class/touchscreen/primary/gesture" -TARGET_TAP_TO_WAKE_NODE_ENABLE := "49" -TARGET_TAP_TO_WAKE_NODE_DISABLE := "48" - # Properties TARGET_SYSTEM_PROP += $(DEVICE_PATH)/system.prop TARGET_VENDOR_PROP += $(DEVICE_PATH)/vendor.prop diff --git a/device.mk b/device.mk index 64b8e9e..2e7d191 100644 --- a/device.mk +++ b/device.mk @@ -92,7 +92,7 @@ PRODUCT_COPY_FILES += \ # Sensors PRODUCT_PACKAGES += \ - sensors.dubai + sensors.eqs PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/sensors/hals.conf:$(TARGET_COPY_OUT_VENDOR)/etc/sensors/hals.conf diff --git a/resource-overlay/eqs/Frameworks/res/values/config.xml b/resource-overlay/eqs/Frameworks/res/values/config.xml index a356a98..87835ea 100644 --- a/resource-overlay/eqs/Frameworks/res/values/config.xml +++ b/resource-overlay/eqs/Frameworks/res/values/config.xml @@ -276,6 +276,6 @@ 32 - - true + + org.lineageos.sensor.dt2w diff --git a/sensors/Android.bp b/sensors/Android.bp index 4efaaae..7a87b29 100644 --- a/sensors/Android.bp +++ b/sensors/Android.bp @@ -5,7 +5,7 @@ // cc_library_shared { - name: "sensors.dubai", + name: "sensors.eqs", defaults: ["hidl_defaults"], srcs: [ "Sensor.cpp", @@ -16,6 +16,7 @@ cc_library_shared { "android.hardware.sensors@2.0", "android.hardware.sensors@2.0-ScopedWakelock", "android.hardware.sensors@2.1", + "libc", "libcutils", "libfmq", "libhardware", @@ -29,7 +30,7 @@ cc_library_shared { "android.hardware.sensors@2.X-multihal", ], cflags: [ - "-DLOG_TAG=\"sensors.dubai\"", + "-DLOG_TAG=\"sensors.eqs\"", ], vendor: true, } diff --git a/sensors/Sensor.cpp b/sensors/Sensor.cpp index 991e723..0b1a152 100644 --- a/sensors/Sensor.cpp +++ b/sensors/Sensor.cpp @@ -17,9 +17,44 @@ #include "Sensor.h" #include +#include #include #include +#include + +static bool readEvent(int fd, struct input_event *event) { + int rc; + + rc = read(fd, event, sizeof(struct input_event)); + if (rc != sizeof(struct input_event)) { + ALOGE("failed to read event from fd, err: %d", rc); + return false; + } + + return true; +} + +static bool readBool(int fd, bool seek) { + char c; + int rc; + + if (seek) { + rc = lseek(fd, 0, SEEK_SET); + if (rc) { + ALOGE("failed to seek: %d", rc); + return false; + } + } + + rc = read(fd, &c, sizeof(c)); + if (rc != 1) { + ALOGE("failed to read bool: %d", rc); + return false; + } + + return c != '0'; +} namespace android { namespace hardware { @@ -191,6 +226,171 @@ OneShotSensor::OneShotSensor(int32_t sensorHandle, ISensorsEventCallback* callba mSensorInfo.flags |= SensorFlagBits::ONE_SHOT_MODE; } +#define INPUT_DT2W_SENSOR_PATH "/dev/input/event10" +#define INPUT_TOUCHSCREEN_PATH "/dev/input/event11" + +#define GESTURE_PATH "/sys/class/touchscreen/primary/gesture" + +InputEventDT2WSensor::InputEventDT2WSensor( + int32_t sensorHandle, ISensorsEventCallback* callback) + : OneShotSensor(sensorHandle, callback) { + mSensorInfo.name = "DT2W sensor"; + mSensorInfo.type = static_cast(static_cast(SensorType::DEVICE_PRIVATE_BASE) + 1); + mSensorInfo.typeAsString = "org.lineageos.sensor.dt2w"; + mSensorInfo.maxRange = 2048.0f; + mSensorInfo.resolution = 1.0f; + mSensorInfo.power = 0; + mSensorInfo.flags |= SensorFlagBits::WAKE_UP; + + std::ofstream mGestureEnable; + mGestureEnable.open(GESTURE_PATH); + + if(!mGestureEnable) { + ALOGE("could not open gesture path"); + mStopThread = true; + return; + } + + mGestureEnable << "49" << std::flush; + + int rc; + + rc = pipe(mWaitPipeFd); + if (rc < 0) { + mWaitPipeFd[0] = -1; + mWaitPipeFd[1] = -1; + ALOGE("failed to open wait pipe: %d", rc); + } + + mPollFds[0] = open(INPUT_DT2W_SENSOR_PATH, O_RDONLY | O_NONBLOCK); + if (mPollFds[0] < 0) { + ALOGE("failed to open poll fd: %d", mPollFds[0]); + } + mPollFds[1] = open(INPUT_TOUCHSCREEN_PATH, O_RDONLY | O_NONBLOCK); + if (mPollFds[1] < 0) { + ALOGE("failed to open poll fd: %d", mPollFds[1]); + } + + if (mWaitPipeFd[0] < 0 || mWaitPipeFd[1] < 0 || mPollFds[0] < 0 || mPollFds[1] < 0) { + mStopThread = true; + return; + } + + mPolls[0] = { + .fd = mWaitPipeFd[0], + .events = POLLIN, + }; + + mPolls[1] = { + .fd = mPollFds[0], + .events = POLLIN, + }; + + mPolls[2] = { + .fd = mPollFds[1], + .events = POLLIN, + }; +} + +InputEventDT2WSensor::~InputEventDT2WSensor() { + interruptPoll(); +} + +void InputEventDT2WSensor::activate(bool enable) { + std::lock_guard lock(mRunMutex); + + if (mIsEnabled != enable) { + mIsEnabled = enable; + + interruptPoll(); + mWaitCV.notify_all(); + } +} + +void InputEventDT2WSensor::setOperationMode(OperationMode mode) { + Sensor::setOperationMode(mode); + interruptPoll(); +} + +void InputEventDT2WSensor::run() { + std::unique_lock runLock(mRunMutex); + + long old_time = 0; + long new_time = 0; + + int old_x = 0; + int new_x = 0; + int old_y = 0; + int new_y = 0; + + while (!mStopThread) { + if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) { + mWaitCV.wait(runLock, [&] { + return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread); + }); + } else { + // Cannot hold lock while polling. + runLock.unlock(); + int rc = poll(mPolls, 3, -1); + runLock.lock(); + + struct input_event event; + + if (rc < 0) { + ALOGE("failed to poll: %d", rc); + mStopThread = true; + continue; + } + + if((mPolls[1].revents == mPolls[1].events) && readEvent(mPolls[1].fd, &event)) { + if(event.type == EV_KEY && event.value == 1 && event.code == KEY_F4) { + mIsEnabled = false; + mCallback->postEvents(readEvents(), isWakeUpSensor()); + } + } else if((mPolls[2].revents == mPolls[2].events) && readEvent(mPolls[2].fd, &event)) { + if(event.type == EV_KEY && event.value == 1) { // Touchscreen down/up + old_time = new_time; + new_time = event.time.tv_sec * 1000000 + event.time.tv_usec; + if((new_time - old_time < 200000) && // 200ms + (abs(sqrt(pow(old_x, 2) + pow(old_y, 2)) - sqrt(pow(new_x, 2) + pow(new_y, 2))) < 500)) { + mIsEnabled = false; + mCallback->postEvents(readEvents(), isWakeUpSensor()); + } + } else if(event.type == EV_ABS) { // send order: touch pos x -> touch y -> down/up + if(event.code == ABS_MT_POSITION_X) { + old_x = new_x; + new_x = event.value; + } else if (event.code == ABS_MT_POSITION_Y) { + old_y = new_y; + new_y = event.value; + } + } + } else if (mPolls[0].revents == mPolls[0].events) { + readBool(mWaitPipeFd[0], false /* seek */); + } + } + } +} + +void InputEventDT2WSensor::interruptPoll() { + if (mWaitPipeFd[1] < 0) return; + + char c = '1'; + write(mWaitPipeFd[1], &c, sizeof(c)); +} + +std::vector InputEventDT2WSensor::readEvents() { + std::vector events; + Event event; + event.sensorHandle = mSensorInfo.sensorHandle; + event.sensorType = mSensorInfo.type; + event.timestamp = ::android::elapsedRealtimeNano(); + event.u.data[0] = 0; + event.u.data[1] = 0; + events.push_back(event); + return events; +} + } // namespace implementation } // namespace subhal } // namespace V2_1 diff --git a/sensors/Sensor.h b/sensors/Sensor.h index b7cd4a5..538e6d9 100644 --- a/sensors/Sensor.h +++ b/sensors/Sensor.h @@ -17,8 +17,12 @@ #pragma once #include +#include +#include +#include #include +#include #include #include #include @@ -88,6 +92,31 @@ class OneShotSensor : public Sensor { virtual Result flush() override { return Result::BAD_VALUE; } }; +class InputEventDT2WSensor : public OneShotSensor { + public: + InputEventDT2WSensor(int32_t sensorHandle, ISensorsEventCallback* callback); + virtual ~InputEventDT2WSensor() override; + + virtual void activate(bool enable) override; + virtual void activate(bool enable, bool notify, bool lock); + virtual void writeEnable(bool enable); + virtual void setOperationMode(OperationMode mode) override; + virtual std::vector readEvents() override; + virtual void fillEventData(Event& event); + + protected: + virtual void run() override; + + std::ofstream mGestureEnable; + + private: + void interruptPoll(); + + struct pollfd mPolls[3]; + int mWaitPipeFd[2]; + int mPollFds[2]; +}; + } // namespace implementation } // namespace subhal } // namespace V2_1 diff --git a/sensors/SensorsSubHal.cpp b/sensors/SensorsSubHal.cpp index 6cbcb56..0e638a4 100644 --- a/sensors/SensorsSubHal.cpp +++ b/sensors/SensorsSubHal.cpp @@ -32,7 +32,9 @@ namespace implementation { using ::android::hardware::Void; using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock; -SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {} +SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) { + AddSensor(); +} Return SensorsSubHal::getSensorsList_2_1(ISensors::getSensorsList_2_1_cb _hidl_cb) { std::vector sensors; diff --git a/sensors/hals.conf b/sensors/hals.conf index d22335b..dc88645 100644 --- a/sensors/hals.conf +++ b/sensors/hals.conf @@ -1,3 +1,3 @@ sensors.ssc.so sensors.moto.so -sensors.dubai.so +sensors.eqs.so