diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml index d966b97..33c83b7 100644 --- a/overlay/frameworks/base/core/res/res/values/config.xml +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -29,6 +29,9 @@ that can be set by the user. --> 17 + + org.lineageos.sensor.single_touch + true diff --git a/sensors/Sensor.cpp b/sensors/Sensor.cpp index 6e75b5f..b1991ee 100644 --- a/sensors/Sensor.cpp +++ b/sensors/Sensor.cpp @@ -24,6 +24,25 @@ namespace { +static bool readBool(int fd) { + char c; + int rc; + + rc = lseek(fd, 0, SEEK_SET); + if (rc) { + ALOGE("failed to seek fd, err: %d", rc); + return false; + } + + rc = read(fd, &c, sizeof(char)); + if (rc != 1) { + ALOGE("failed to read bool from fd, err: %d", rc); + return false; + } + + return c != '0'; +} + static bool readFpState(int fd, int& screenX, int& screenY) { char buffer[512]; int state = 0; @@ -333,6 +352,115 @@ void UdfpsSensor::interruptPoll() { write(mWaitPipeFd[1], &c, sizeof(c)); } +SingleTapSensor::SingleTapSensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : OneShotSensor(sensorHandle, callback) { + mSensorInfo.name = "Single Tap Sensor"; + mSensorInfo.type = + static_cast(static_cast(SensorType::DEVICE_PRIVATE_BASE) + 2); + mSensorInfo.typeAsString = "org.lineageos.sensor.single_touch"; + mSensorInfo.maxRange = 2048.0f; + mSensorInfo.resolution = 1.0f; + mSensorInfo.power = 0; + mSensorInfo.flags |= SensorFlagBits::WAKE_UP; + + int rc; + + rc = pipe(mWaitPipeFd); + if (rc < 0) { + mWaitPipeFd[0] = -1; + mWaitPipeFd[1] = -1; + ALOGE("failed to open wait pipe: %d", rc); + } + + mPollFd = open("/sys/class/spi_master/spi0/spi0.0/fts_gesture_single_tap_pressed", O_RDONLY); + if (mPollFd < 0) { + ALOGE("failed to open poll fd: %d", mPollFd); + } + + if (mWaitPipeFd[0] < 0 || mWaitPipeFd[1] < 0 || mPollFd < 0) { + mStopThread = true; + return; + } + + mPolls[0] = { + .fd = mWaitPipeFd[0], + .events = POLLIN, + }; + + mPolls[1] = { + .fd = mPollFd, + .events = POLLERR | POLLPRI, + }; +} + +SingleTapSensor::~SingleTapSensor() { + interruptPoll(); +} + +void SingleTapSensor::activate(bool enable) { + std::lock_guard lock(mRunMutex); + + if (mIsEnabled != enable) { + mIsEnabled = enable; + + interruptPoll(); + mWaitCV.notify_all(); + } +} + +void SingleTapSensor::setOperationMode(OperationMode mode) { + Sensor::setOperationMode(mode); + interruptPoll(); +} + +void SingleTapSensor::run() { + std::unique_lock runLock(mRunMutex); + + 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, 2, -1); + runLock.lock(); + + if (rc < 0) { + ALOGE("failed to poll: %d", rc); + mStopThread = true; + continue; + } + + if (mPolls[1].revents == mPolls[1].events && readBool(mPollFd)) { + mIsEnabled = false; + mCallback->postEvents(readEvents(), isWakeUpSensor()); + } else if (mPolls[0].revents == mPolls[0].events) { + char buf; + read(mWaitPipeFd[0], &buf, sizeof(buf)); + } + } + } +} + +std::vector SingleTapSensor::readEvents() { + std::vector events; + Event event; + event.sensorHandle = mSensorInfo.sensorHandle; + event.sensorType = mSensorInfo.type; + event.timestamp = ::android::elapsedRealtimeNano(); + events.push_back(event); + return events; +} + +void SingleTapSensor::interruptPoll() { + if (mWaitPipeFd[1] < 0) return; + + char c = '1'; + write(mWaitPipeFd[1], &c, sizeof(c)); +} + } // namespace implementation } // namespace subhal } // namespace V2_1 diff --git a/sensors/Sensor.h b/sensors/Sensor.h index aa1f194..7586f21 100644 --- a/sensors/Sensor.h +++ b/sensors/Sensor.h @@ -114,6 +114,26 @@ class UdfpsSensor : public OneShotSensor { int mScreenY; }; +class SingleTapSensor : public OneShotSensor { + public: + SingleTapSensor(int32_t sensorHandle, ISensorsEventCallback* callback); + virtual ~SingleTapSensor() override; + + virtual void activate(bool enable) override; + virtual void setOperationMode(OperationMode mode) override; + + protected: + virtual void run() override; + virtual std::vector readEvents(); + + private: + void interruptPoll(); + + struct pollfd mPolls[2]; + int mWaitPipeFd[2]; + int mPollFd; +}; + } // namespace implementation } // namespace subhal } // namespace V2_1 diff --git a/sensors/SensorsSubHal.cpp b/sensors/SensorsSubHal.cpp index 9306b98..2e986f5 100644 --- a/sensors/SensorsSubHal.cpp +++ b/sensors/SensorsSubHal.cpp @@ -34,6 +34,7 @@ using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock; SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) { AddSensor(); + AddSensor(); } Return SensorsSubHal::getSensorsList_2_1(ISensors::getSensorsList_2_1_cb _hidl_cb) {