Skip to content

Commit ad55421

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "TouchInputMapper: Disable PointerUsage concept with a flag" into main
2 parents c57d7d4 + 869b89d commit ad55421

7 files changed

Lines changed: 224 additions & 42 deletions

File tree

libs/input/input_flags.aconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,16 @@ flag {
187187
is_fixed_read_only: true
188188
}
189189

190+
flag {
191+
name: "disable_touch_input_mapper_pointer_usage"
192+
namespace: "input"
193+
description: "Disable the PointerUsage concept in TouchInputMapper since the old touchpad stack is no longer used."
194+
bug: "281840344"
195+
metadata {
196+
purpose: PURPOSE_BUGFIX
197+
}
198+
}
199+
190200
flag {
191201
name: "keyboard_repeat_keys"
192202
namespace: "input"

services/inputflinger/reader/mapper/TouchInputMapper.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <android-base/stringprintf.h>
3232
#include <android/input.h>
33+
#include <com_android_input_flags.h>
3334
#include <ftl/enum.h>
3435
#include <input/PrintTools.h>
3536
#include <input/PropertyMap.h>
@@ -47,6 +48,8 @@
4748

4849
namespace android {
4950

51+
namespace input_flags = com::android::input::flags;
52+
5053
// --- Constants ---
5154

5255
// Artificial latency on synthetic events created from stylus data without corresponding touch
@@ -1575,7 +1578,8 @@ std::list<NotifyArgs> TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t re
15751578
mLastCookedState.buttonState, mCurrentCookedState.buttonState);
15761579

15771580
// Dispatch the touches either directly or by translation through a pointer on screen.
1578-
if (mDeviceMode == DeviceMode::POINTER) {
1581+
if (!input_flags::disable_touch_input_mapper_pointer_usage() &&
1582+
mDeviceMode == DeviceMode::POINTER) {
15791583
for (BitSet32 idBits(mCurrentRawState.rawPointerData.touchingIdBits); !idBits.isEmpty();) {
15801584
uint32_t id = idBits.clearFirstMarkedBit();
15811585
const RawPointerData::Pointer& pointer =
@@ -1613,7 +1617,9 @@ std::list<NotifyArgs> TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t re
16131617
}
16141618

16151619
out += dispatchPointerUsage(when, readTime, policyFlags, pointerUsage);
1616-
} else {
1620+
}
1621+
if (input_flags::disable_touch_input_mapper_pointer_usage() ||
1622+
mDeviceMode != DeviceMode::POINTER) {
16171623
if (!mCurrentMotionAborted) {
16181624
out += dispatchButtonRelease(when, readTime, policyFlags);
16191625
out += dispatchHoverExit(when, readTime, policyFlags);
@@ -2251,6 +2257,23 @@ void TouchInputMapper::cookPointerData() {
22512257
for (uint32_t i = 0; i < currentPointerCount; i++) {
22522258
const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];
22532259

2260+
bool isHovering = in.isHovering;
2261+
2262+
// A tool MOUSE pointer is only down/touching when a mouse button is pressed.
2263+
if (input_flags::disable_touch_input_mapper_pointer_usage() &&
2264+
in.toolType == ToolType::MOUSE &&
2265+
!mCurrentRawState.rawPointerData.canceledIdBits.hasBit(in.id)) {
2266+
if (isPointerDown(mCurrentRawState.buttonState)) {
2267+
isHovering = false;
2268+
mCurrentCookedState.cookedPointerData.touchingIdBits.markBit(in.id);
2269+
mCurrentCookedState.cookedPointerData.hoveringIdBits.clearBit(in.id);
2270+
} else {
2271+
isHovering = true;
2272+
mCurrentCookedState.cookedPointerData.touchingIdBits.clearBit(in.id);
2273+
mCurrentCookedState.cookedPointerData.hoveringIdBits.markBit(in.id);
2274+
}
2275+
}
2276+
22542277
// Size
22552278
float touchMajor, touchMinor, toolMajor, toolMinor, size;
22562279
switch (mCalibration.sizeCalibration) {
@@ -2340,7 +2363,7 @@ void TouchInputMapper::cookPointerData() {
23402363
pressure = in.pressure * mPressureScale;
23412364
break;
23422365
default:
2343-
pressure = in.isHovering ? 0 : 1;
2366+
pressure = isHovering ? 0 : 1;
23442367
break;
23452368
}
23462369

@@ -3697,7 +3720,10 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion(
36973720
float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
36983721
float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
36993722
if (mDeviceMode == DeviceMode::POINTER) {
3700-
xCursorPosition = yCursorPosition = 0.f;
3723+
ALOGW_IF(pointerCount != 1,
3724+
"Only single pointer events are fully supported in POINTER mode");
3725+
xCursorPosition = pointerCoords[0].getX();
3726+
yCursorPosition = pointerCoords[0].getY();
37013727
}
37023728
const DeviceId deviceId = getDeviceId();
37033729
std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();

services/inputflinger/reader/mapper/TouchInputMapper.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ class TouchInputMapper : public InputMapper {
215215
DISABLED, // input is disabled
216216
DIRECT, // direct mapping (touchscreen)
217217
NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
218-
POINTER, // pointer mapping (e.g. uncaptured touchpad, drawing tablet)
218+
POINTER, // pointer mapping (e.g. absolute mouse, drawing tablet)
219219

220220
ftl_last = POINTER
221221
};
@@ -234,6 +234,9 @@ class TouchInputMapper : public InputMapper {
234234
ftl_last = POINTER
235235
};
236236

237+
// TouchInputMapper will configure devices with INPUT_PROP_DIRECT as
238+
// DeviceType::TOUCH_SCREEN, and will otherwise use DeviceType::POINTER by default.
239+
// This can be overridden by IDC files, using the `touch.deviceType` config.
237240
DeviceType deviceType;
238241
bool hasAssociatedDisplay;
239242
bool associatedDisplayIsExternal;

services/inputflinger/tests/InputDispatcher_test.cpp

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "FakeInputDispatcherPolicy.h"
2020
#include "FakeInputTracingBackend.h"
2121
#include "FakeWindows.h"
22+
#include "ScopedFlagOverride.h"
2223
#include "TestEventMatchers.h"
2324

2425
#include <NotifyArgsBuilders.h>
@@ -138,40 +139,6 @@ static KeyEvent getTestKeyEvent() {
138139
return event;
139140
}
140141

141-
/**
142-
* Provide a local override for a flag value. The value is restored when the object of this class
143-
* goes out of scope.
144-
* This class is not intended to be used directly, because its usage is cumbersome.
145-
* Instead, a wrapper macro SCOPED_FLAG_OVERRIDE is provided.
146-
*/
147-
class ScopedFlagOverride {
148-
public:
149-
ScopedFlagOverride(std::function<bool()> read, std::function<void(bool)> write, bool value)
150-
: mInitialValue(read()), mWriteValue(write) {
151-
mWriteValue(value);
152-
}
153-
~ScopedFlagOverride() { mWriteValue(mInitialValue); }
154-
155-
private:
156-
const bool mInitialValue;
157-
std::function<void(bool)> mWriteValue;
158-
};
159-
160-
typedef bool (*readFlagValueFunction)();
161-
typedef void (*writeFlagValueFunction)(bool);
162-
163-
/**
164-
* Use this macro to locally override a flag value.
165-
* Example usage:
166-
* SCOPED_FLAG_OVERRIDE(enable_multi_device_same_window_stream, false);
167-
* Note: this works by creating a local variable in your current scope. Don't call this twice for
168-
* the same flag, because the variable names will clash!
169-
*/
170-
#define SCOPED_FLAG_OVERRIDE(NAME, VALUE) \
171-
readFlagValueFunction read##NAME = com::android::input::flags::NAME; \
172-
writeFlagValueFunction write##NAME = com::android::input::flags::NAME; \
173-
ScopedFlagOverride override##NAME(read##NAME, write##NAME, (VALUE))
174-
175142
} // namespace
176143

177144
// --- InputDispatcherTest ---

services/inputflinger/tests/InputReader_test.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <MultiTouchInputMapper.h>
2929
#include <NotifyArgsBuilders.h>
3030
#include <PeripheralController.h>
31+
#include <ScopedFlagOverride.h>
3132
#include <SingleTouchInputMapper.h>
3233
#include <TestEventMatchers.h>
3334
#include <TestInputListener.h>
@@ -4526,13 +4527,20 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
45264527

45274528
NotifyMotionArgs motionArgs;
45284529

4530+
// Hold down the mouse button for the duration of the test, since the mouse tools require
4531+
// the button to be pressed to make sure they are not hovering.
4532+
processKey(mapper, BTN_MOUSE, 1);
4533+
45294534
// default tool type is finger
45304535
processDown(mapper, 100, 200);
45314536
processSync(mapper);
45324537
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
45334538
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
45344539
ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
45354540

4541+
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4542+
WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS)));
4543+
45364544
// eraser
45374545
processKey(mapper, BTN_TOOL_RUBBER, 1);
45384546
processSync(mapper);
@@ -7175,6 +7183,10 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
71757183

71767184
NotifyMotionArgs motionArgs;
71777185

7186+
// Hold down the mouse button for the duration of the test, since the mouse tools require
7187+
// the button to be pressed to make sure they are not hovering.
7188+
processKey(mapper, BTN_MOUSE, 1);
7189+
71787190
// default tool type is finger
71797191
processId(mapper, 1);
71807192
processPosition(mapper, 100, 200);
@@ -7183,6 +7195,9 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
71837195
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
71847196
ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
71857197

7198+
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7199+
WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS)));
7200+
71867201
// eraser
71877202
processKey(mapper, BTN_TOOL_RUBBER, 1);
71887203
processSync(mapper);
@@ -7520,6 +7535,7 @@ TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
75207535
}
75217536

75227537
TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
7538+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, true);
75237539
prepareSecondaryDisplay(ViewportType::EXTERNAL);
75247540

75257541
prepareDisplay(ui::ROTATION_0);
@@ -7532,9 +7548,9 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
75327548
processPosition(mapper, 100, 100);
75337549
processSync(mapper);
75347550

7535-
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7536-
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7537-
ASSERT_EQ(DISPLAY_ID, motionArgs.displayId);
7551+
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7552+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithDisplayId(DISPLAY_ID),
7553+
WithSource(AINPUT_SOURCE_MOUSE), WithToolType(ToolType::FINGER))));
75387554
}
75397555

75407556
/**
@@ -8604,6 +8620,8 @@ class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
86048620
* fingers start to move downwards, the gesture should be swipe.
86058621
*/
86068622
TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
8623+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8624+
86078625
// The min freeform gesture width is 25units/mm x 30mm = 750
86088626
// which is greater than fraction of the diagnal length of the touchpad (349).
86098627
// Thus, MaxSwipWidth is 750.
@@ -8664,6 +8682,8 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
86648682
* the gesture should be swipe.
86658683
*/
86668684
TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
8685+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8686+
86678687
// The min freeform gesture width is 5units/mm x 30mm = 150
86688688
// which is greater than fraction of the diagnal length of the touchpad (349).
86698689
// Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
@@ -8723,6 +8743,8 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe)
87238743
* freeform gestures after two fingers start to move downwards.
87248744
*/
87258745
TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
8746+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8747+
87268748
preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
87278749
MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
87288750

@@ -8818,6 +8840,8 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
88188840
}
88198841

88208842
TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
8843+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8844+
88218845
preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
88228846
MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
88238847
NotifyMotionArgs motionArgs;
@@ -8864,6 +8888,8 @@ TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
88648888
}
88658889

88668890
TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
8891+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8892+
88678893
preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
88688894
mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
88698895
MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();

services/inputflinger/tests/MultiTouchInputMapper_test.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323

2424
#include "InputMapperTest.h"
2525
#include "InterfaceMocks.h"
26+
#include "ScopedFlagOverride.h"
2627
#include "TestEventMatchers.h"
2728

2829
#define TAG "MultiTouchpadInputMapperUnit_test"
2930

3031
namespace android {
3132

3233
using testing::_;
34+
using testing::AllOf;
3335
using testing::IsEmpty;
3436
using testing::Return;
3537
using testing::SetArgPointee;
@@ -266,4 +268,94 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) {
266268
VariantWith<NotifyMotionArgs>(WithMotionAction(AMOTION_EVENT_ACTION_UP))));
267269
}
268270

271+
class MultiTouchInputMapperPointerModeUnitTest : public MultiTouchInputMapperUnitTest {
272+
protected:
273+
void SetUp() override {
274+
MultiTouchInputMapperUnitTest::SetUp();
275+
276+
// TouchInputMapper goes into POINTER mode whenever INPUT_PROP_DIRECT is not set.
277+
EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_DIRECT))
278+
.WillRepeatedly(Return(false));
279+
280+
mMapper = createInputMapper<MultiTouchInputMapper>(*mDeviceContext,
281+
mFakePolicy->getReaderConfiguration());
282+
}
283+
};
284+
285+
TEST_F(MultiTouchInputMapperPointerModeUnitTest, MouseToolOnlyDownWhenMouseButtonsAreDown) {
286+
SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, true);
287+
288+
std::list<NotifyArgs> args;
289+
290+
// Set the tool type to mouse.
291+
args += processKey(BTN_TOOL_MOUSE, 1);
292+
293+
args += processPosition(100, 100);
294+
args += processId(1);
295+
ASSERT_THAT(args, IsEmpty());
296+
297+
args = processSync();
298+
ASSERT_THAT(args,
299+
ElementsAre(VariantWith<NotifyMotionArgs>(
300+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
301+
WithToolType(ToolType::MOUSE))),
302+
VariantWith<NotifyMotionArgs>(
303+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
304+
WithToolType(ToolType::MOUSE)))));
305+
306+
// Setting BTN_TOUCH does not make a mouse pointer go down.
307+
args = processKey(BTN_TOUCH, 1);
308+
args += processSync();
309+
ASSERT_THAT(args,
310+
ElementsAre(VariantWith<NotifyMotionArgs>(
311+
WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
312+
313+
// The mouse button is pressed, so the mouse goes down.
314+
args = processKey(BTN_MOUSE, 1);
315+
args += processSync();
316+
ASSERT_THAT(args,
317+
ElementsAre(VariantWith<NotifyMotionArgs>(
318+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
319+
WithToolType(ToolType::MOUSE))),
320+
VariantWith<NotifyMotionArgs>(
321+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
322+
WithToolType(ToolType::MOUSE),
323+
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))),
324+
VariantWith<NotifyMotionArgs>(
325+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
326+
WithToolType(ToolType::MOUSE),
327+
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
328+
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY)))));
329+
330+
// The mouse button is released, so the mouse starts hovering.
331+
args = processKey(BTN_MOUSE, 0);
332+
args += processSync();
333+
ASSERT_THAT(args,
334+
ElementsAre(VariantWith<NotifyMotionArgs>(
335+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
336+
WithButtonState(0), WithToolType(ToolType::MOUSE),
337+
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY))),
338+
VariantWith<NotifyMotionArgs>(
339+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
340+
WithToolType(ToolType::MOUSE), WithButtonState(0))),
341+
VariantWith<NotifyMotionArgs>(
342+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
343+
WithToolType(ToolType::MOUSE))),
344+
VariantWith<NotifyMotionArgs>(
345+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
346+
WithToolType(ToolType::MOUSE)))));
347+
348+
// Change the tool type so that it is no longer a mouse.
349+
// The default tool type is finger, and the finger is already down.
350+
args = processKey(BTN_TOOL_MOUSE, 0);
351+
args += processSync();
352+
ASSERT_THAT(args,
353+
ElementsAre(VariantWith<NotifyMotionArgs>(
354+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
355+
WithToolType(ToolType::MOUSE))),
356+
VariantWith<NotifyMotionArgs>(
357+
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
358+
WithToolType(ToolType::FINGER)))));
359+
}
360+
269361
} // namespace android

0 commit comments

Comments
 (0)