Skip to content

Commit 8705830

Browse files
HarryCuttsAndroid (Google) Code Review
authored andcommitted
Merge "GestureConverter: add option to make 3-finger tap a shortcut" into main
2 parents 9648eda + 2a0210e commit 8705830

8 files changed

Lines changed: 68 additions & 1 deletion

File tree

services/inputflinger/include/InputReaderBase.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ struct InputReaderConfiguration {
242242
// context (a.k.a. "right") clicks.
243243
bool touchpadRightClickZoneEnabled;
244244

245+
// True to use three-finger tap as a customizable shortcut; false to use it as a middle-click.
246+
bool touchpadThreeFingerTapShortcutEnabled;
247+
245248
// The set of currently disabled input devices.
246249
std::set<int32_t> disabledDevices;
247250

@@ -293,6 +296,7 @@ struct InputReaderConfiguration {
293296
touchpadTapDraggingEnabled(false),
294297
shouldNotifyTouchpadHardwareState(false),
295298
touchpadRightClickZoneEnabled(false),
299+
touchpadThreeFingerTapShortcutEnabled(false),
296300
stylusButtonMotionEventsEnabled(true),
297301
stylusPointerIconEnabled(false),
298302
mouseReverseVerticalScrollingEnabled(false),
@@ -496,6 +500,9 @@ class InputReaderPolicyInterface : public virtual RefBase {
496500
/* Sends the Info of gestures that happen on the touchpad. */
497501
virtual void notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) = 0;
498502

503+
/* Notifies the policy that the user has performed a three-finger touchpad tap. */
504+
virtual void notifyTouchpadThreeFingerTap() = 0;
505+
499506
/* Gets the keyboard layout for a particular input device. */
500507
virtual std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
501508
const InputDeviceIdentifier& identifier,

services/inputflinger/reader/mapper/TouchpadInputMapper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,9 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,
375375
mPropertyProvider.getProperty("Button Right Click Zone Enable")
376376
.setBoolValues({config.touchpadRightClickZoneEnabled});
377377
mTouchpadHardwareStateNotificationsEnabled = config.shouldNotifyTouchpadHardwareState;
378+
379+
mGestureConverter.setThreeFingerTapShortcutEnabled(
380+
config.touchpadThreeFingerTapShortcutEnabled);
378381
}
379382
std::list<NotifyArgs> out;
380383
if ((!changes.any() && config.pointerCaptureRequest.isEnable()) ||

services/inputflinger/reader/mapper/gestures/GestureConverter.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,14 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_
261261
}
262262

263263
const uint32_t buttonsPressed = gesture.details.buttons.down;
264+
const uint32_t buttonsReleased = gesture.details.buttons.up;
265+
266+
if (mThreeFingerTapShortcutEnabled && gesture.details.buttons.is_tap &&
267+
buttonsPressed == GESTURES_BUTTON_MIDDLE && buttonsReleased == GESTURES_BUTTON_MIDDLE) {
268+
mReaderContext.getPolicy()->notifyTouchpadThreeFingerTap();
269+
return out;
270+
}
271+
264272
bool pointerDown = isPointerDown(mButtonState) ||
265273
buttonsPressed &
266274
(GESTURES_BUTTON_LEFT | GESTURES_BUTTON_MIDDLE | GESTURES_BUTTON_RIGHT);
@@ -291,7 +299,6 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_
291299
// changes: a set of buttons going down, followed by a set of buttons going up.
292300
mButtonState = newButtonState;
293301

294-
const uint32_t buttonsReleased = gesture.details.buttons.up;
295302
for (uint32_t button = 1; button <= GESTURES_BUTTON_FORWARD; button <<= 1) {
296303
if (buttonsReleased & button) {
297304
uint32_t actionButton = gesturesButtonToMotionEventButton(button);

services/inputflinger/reader/mapper/gestures/GestureConverter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class GestureConverter {
5555

5656
void setBoundsInLogicalDisplay(FloatRect bounds) { mBoundsInLogicalDisplay = bounds; }
5757

58+
void setThreeFingerTapShortcutEnabled(bool enabled) {
59+
mThreeFingerTapShortcutEnabled = enabled;
60+
}
61+
5862
void populateMotionRanges(InputDeviceInfo& info) const;
5963

6064
[[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
@@ -101,6 +105,8 @@ class GestureConverter {
101105
const bool mEnableFlingStop;
102106
const bool mEnableNoFocusChange;
103107

108+
bool mThreeFingerTapShortcutEnabled;
109+
104110
std::optional<ui::LogicalDisplayId> mDisplayId;
105111
FloatRect mBoundsInLogicalDisplay{};
106112
ui::Rotation mOrientation = ui::ROTATION_0;

services/inputflinger/tests/FakeInputReaderPolicy.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ void FakeInputReaderPolicy::assertTouchpadHardwareStateNotified() {
8080
ASSERT_TRUE(success) << "Timed out waiting for hardware state to be notified";
8181
}
8282

83+
void FakeInputReaderPolicy::assertTouchpadThreeFingerTapNotified() {
84+
std::unique_lock lock(mLock);
85+
base::ScopedLockAssertion assumeLocked(mLock);
86+
87+
const bool success =
88+
mTouchpadThreeFingerTapNotified.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
89+
return mTouchpadThreeFingerTapHasBeenReported;
90+
});
91+
ASSERT_TRUE(success) << "Timed out waiting for three-finger tap to be notified";
92+
}
93+
8394
void FakeInputReaderPolicy::clearViewports() {
8495
mViewports.clear();
8596
mConfig.setDisplayViewports(mViewports);
@@ -259,6 +270,12 @@ void FakeInputReaderPolicy::notifyTouchpadGestureInfo(GestureType type, int32_t
259270
std::scoped_lock lock(mLock);
260271
}
261272

273+
void FakeInputReaderPolicy::notifyTouchpadThreeFingerTap() {
274+
std::scoped_lock lock(mLock);
275+
mTouchpadThreeFingerTapHasBeenReported = true;
276+
mTouchpadThreeFingerTapNotified.notify_all();
277+
}
278+
262279
std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
263280
const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) {
264281
return nullptr;

services/inputflinger/tests/FakeInputReaderPolicy.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class FakeInputReaderPolicy : public InputReaderPolicyInterface {
4343
void assertStylusGestureNotified(int32_t deviceId);
4444
void assertStylusGestureNotNotified();
4545
void assertTouchpadHardwareStateNotified();
46+
void assertTouchpadThreeFingerTapNotified();
4647

4748
virtual void clearViewports();
4849
std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueId) const;
@@ -86,6 +87,7 @@ class FakeInputReaderPolicy : public InputReaderPolicyInterface {
8687
void notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
8788
int32_t deviceId) override;
8889
void notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) override;
90+
void notifyTouchpadThreeFingerTap() override;
8991
std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
9092
const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) override;
9193
std::string getDeviceAlias(const InputDeviceIdentifier&) override;
@@ -109,6 +111,9 @@ class FakeInputReaderPolicy : public InputReaderPolicyInterface {
109111
std::condition_variable mTouchpadHardwareStateNotified;
110112
std::optional<SelfContainedHardwareState> mTouchpadHardwareState GUARDED_BY(mLock){};
111113

114+
std::condition_variable mTouchpadThreeFingerTapNotified;
115+
bool mTouchpadThreeFingerTapHasBeenReported{false};
116+
112117
uint32_t mNextPointerCaptureSequenceNumber{0};
113118
};
114119

services/inputflinger/tests/GestureConverter_test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,27 @@ TEST_F(GestureConverterTest, Tap) {
12721272
WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
12731273
}
12741274

1275+
TEST_F(GestureConverterTest, ThreeFingerTap_TriggersShortcut) {
1276+
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
1277+
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
1278+
converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);
1279+
converter.setThreeFingerTapShortcutEnabled(true);
1280+
1281+
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*vx=*/0,
1282+
/*vy=*/0, GESTURES_FLING_TAP_DOWN);
1283+
std::list<NotifyArgs> args =
1284+
converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
1285+
// We don't need to check args here, since it's covered by the FlingTapDown test.
1286+
1287+
Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
1288+
/*down=*/GESTURES_BUTTON_MIDDLE, /*up=*/GESTURES_BUTTON_MIDDLE,
1289+
/*is_tap=*/true);
1290+
args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapGesture);
1291+
1292+
ASSERT_TRUE(args.empty());
1293+
mFakePolicy->assertTouchpadThreeFingerTapNotified();
1294+
}
1295+
12751296
TEST_F(GestureConverterTest, Click) {
12761297
// Click should produce button press/release events
12771298
InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);

services/inputflinger/tests/fuzzers/MapperHelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
288288
void notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
289289
int32_t deviceId) override {}
290290
void notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) override {}
291+
void notifyTouchpadThreeFingerTap() override {}
291292
std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
292293
const InputDeviceIdentifier& identifier,
293294
const std::optional<KeyboardLayoutInfo> layoutInfo) override {

0 commit comments

Comments
 (0)