TouchpadInputMapper: add timer provider
Adding a timer provider allows the Gestures library to perform some
asynchronous tasks, including ones which improve tap-to-click detection.
Bug: 297192727
Test: set the
persist.device_config.aconfig_flags.input.com.android.input.flags.enable_gestures_library_timer_provider
sysprop to true, restart, then make fast tap-to-click gestures
(where the finger is contacting for fewer than 3 frames) on the
touchpad, and check they're reported immediately
Change-Id: Ib9b8dacc71c88b6fd47bdd747f90ef6a44b37cc4
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index 6ea004d..3e5e01e 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -25,6 +25,7 @@
#include <android-base/stringprintf.h>
#include <android/input.h>
+#include <com_android_input_flags.h>
#include <ftl/enum.h>
#include <input/PrintTools.h>
#include <linux/input-event-codes.h>
@@ -34,8 +35,11 @@
#include "TouchCursorInputMapperCommon.h"
#include "TouchpadInputMapper.h"
#include "gestures/HardwareProperties.h"
+#include "gestures/TimerProvider.h"
#include "ui/Rotation.h"
+namespace input_flags = com::android::input::flags;
+
namespace android {
namespace {
@@ -232,6 +236,7 @@
: InputMapper(deviceContext, readerConfig),
mGestureInterpreter(NewGestureInterpreter(), DeleteGestureInterpreter),
mPointerController(getContext()->getPointerController(getDeviceId())),
+ mTimerProvider(*getContext()),
mStateConverter(deviceContext, mMotionAccumulator),
mGestureConverter(*getContext(), deviceContext, getDeviceId()),
mCapturedEventConverter(*getContext(), deviceContext, mMotionAccumulator, getDeviceId()),
@@ -253,8 +258,12 @@
// 2) TouchpadInputMapper is stored as a unique_ptr and not moved.
mGestureInterpreter->SetPropProvider(const_cast<GesturesPropProvider*>(&gesturePropProvider),
&mPropertyProvider);
+ if (input_flags::enable_gestures_library_timer_provider()) {
+ mGestureInterpreter->SetTimerProvider(const_cast<GesturesTimerProvider*>(
+ &kGestureTimerProvider),
+ &mTimerProvider);
+ }
mGestureInterpreter->SetCallback(gestureInterpreterCallback, this);
- // TODO(b/251196347): set a timer provider, so the library can use timers.
}
TouchpadInputMapper::~TouchpadInputMapper() {
@@ -262,14 +271,14 @@
mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
}
- // The gesture interpreter's destructor will call its property provider's free function for all
- // gesture properties, in this case calling PropertyProvider::freeProperty using a raw pointer
- // to mPropertyProvider. Depending on the declaration order in TouchpadInputMapper.h, this may
- // happen after mPropertyProvider has been destructed, causing allocation errors. Depending on
- // declaration order to avoid crashes seems rather fragile, so explicitly clear the property
- // provider here to ensure all the freeProperty calls happen before mPropertyProvider is
- // destructed.
+ // The gesture interpreter's destructor will try to free its property and timer providers,
+ // calling PropertyProvider::freeProperty and TimerProvider::freeTimer using a raw pointers.
+ // Depending on the declaration order in TouchpadInputMapper.h, those providers may have already
+ // been freed, causing allocation errors or use-after-free bugs. Depending on declaration order
+ // to avoid this seems rather fragile, so explicitly clear the providers here to ensure all the
+ // freeProperty and freeTimer calls happen before the providers are destructed.
mGestureInterpreter->SetPropProvider(nullptr, nullptr);
+ mGestureInterpreter->SetTimerProvider(nullptr, nullptr);
}
uint32_t TouchpadInputMapper::getSources() const {
@@ -287,9 +296,6 @@
void TouchpadInputMapper::dump(std::string& dump) {
dump += INDENT2 "Touchpad Input Mapper:\n";
- if (mProcessing) {
- dump += INDENT3 "Currently processing a hardware state\n";
- }
if (mResettingInterpreter) {
dump += INDENT3 "Currently resetting gesture interpreter\n";
}
@@ -298,6 +304,12 @@
dump += addLinePrefix(mGestureConverter.dump(), INDENT4);
dump += INDENT3 "Gesture properties:\n";
dump += addLinePrefix(mPropertyProvider.dump(), INDENT4);
+ if (input_flags::enable_gestures_library_timer_provider()) {
+ dump += INDENT3 "Timer provider:\n";
+ dump += addLinePrefix(mTimerProvider.dump(), INDENT4);
+ } else {
+ dump += INDENT3 "Timer provider: disabled by flag\n";
+ }
dump += INDENT3 "Captured event converter:\n";
dump += addLinePrefix(mCapturedEventConverter.dump(), INDENT4);
dump += StringPrintf(INDENT3 "DisplayId: %s\n", toString(mDisplayId).c_str());
@@ -443,13 +455,18 @@
std::list<NotifyArgs> TouchpadInputMapper::sendHardwareState(nsecs_t when, nsecs_t readTime,
SelfContainedHardwareState schs) {
ALOGD_IF(DEBUG_TOUCHPAD_GESTURES, "New hardware state: %s", schs.state.String().c_str());
- mProcessing = true;
mGestureInterpreter->PushHardwareState(&schs.state);
- mProcessing = false;
-
return processGestures(when, readTime);
}
+std::list<NotifyArgs> TouchpadInputMapper::timeoutExpired(nsecs_t when) {
+ if (!input_flags::enable_gestures_library_timer_provider()) {
+ return {};
+ }
+ mTimerProvider.triggerCallbacks(when);
+ return processGestures(when, when);
+}
+
void TouchpadInputMapper::consumeGesture(const Gesture* gesture) {
ALOGD_IF(DEBUG_TOUCHPAD_GESTURES, "Gesture ready: %s", gesture->String().c_str());
if (mResettingInterpreter) {
@@ -457,10 +474,6 @@
// ignore any gestures produced from the interpreter while we're resetting it.
return;
}
- if (!mProcessing) {
- ALOGE("Received gesture outside of the normal processing flow; ignoring it.");
- return;
- }
mGesturesToProcess.push_back(*gesture);
}