Loading services/inputflinger/UnwantedInteractionBlocker.cpp +11 −1 Original line number Diff line number Diff line Loading @@ -67,6 +67,16 @@ const bool DEBUG_OUTBOUND_MOTION = const bool DEBUG_MODEL = __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Model", ANDROID_LOG_INFO); /** * When multi-device input is enabled, we shouldn't use PreferStylusOverTouchBlocker at all. * However, multi-device input has the following default behaviour: hovering stylus rejects touch. * Therefore, if we want to disable that behaviour (and go back to a place where stylus down * blocks touch, but hovering stylus doesn't interact with touch), we should just disable the entire * multi-device input feature. */ const bool ENABLE_MULTI_DEVICE_INPUT = input_flags::enable_multi_device_input() && !input_flags::disable_reject_touch_on_stylus_hover(); // Category (=namespace) name for the input settings that are applied at boot time static const char* INPUT_NATIVE_BOOT = "input_native_boot"; /** Loading Loading @@ -347,7 +357,7 @@ void UnwantedInteractionBlocker::notifyMotion(const NotifyMotionArgs& args) { ALOGD_IF(DEBUG_INBOUND_MOTION, "%s: %s", __func__, args.dump().c_str()); { // acquire lock std::scoped_lock lock(mLock); if (input_flags::enable_multi_device_input()) { if (ENABLE_MULTI_DEVICE_INPUT) { notifyMotionLocked(args); } else { const std::vector<NotifyMotionArgs> processedArgs = Loading services/inputflinger/dispatcher/InputState.cpp +5 −31 Original line number Diff line number Diff line Loading @@ -24,19 +24,6 @@ namespace android::inputdispatcher { namespace { bool isHoverAction(int32_t action) { switch (MotionEvent::getActionMasked(action)) { case AMOTION_EVENT_ACTION_HOVER_ENTER: case AMOTION_EVENT_ACTION_HOVER_MOVE: case AMOTION_EVENT_ACTION_HOVER_EXIT: { return true; } } return false; } } // namespace InputState::InputState(const IdGenerator& idGenerator) : mIdGenerator(idGenerator) {} InputState::~InputState() {} Loading Loading @@ -113,13 +100,6 @@ bool InputState::trackMotion(const MotionEntry& entry, int32_t action, int32_t f if (isStylusEvent(lastMemento.source, lastMemento.pointerProperties) && !isStylusEvent(entry.source, entry.pointerProperties)) { // We already have a stylus stream, and the new event is not from stylus. if (!lastMemento.hovering) { // If stylus is currently down, reject the new event unconditionally. return false; } } if (!lastMemento.hovering && isHoverAction(action)) { // Reject hovers if already down return false; } } Loading Loading @@ -366,19 +346,13 @@ bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry, return false; } // We want stylus down to block touch and other source types, but stylus hover should not // have such an effect. if (isHoverAction(motionEntry.action) && !lastMemento.hovering) { // New event is a hover. Keep the current non-hovering gesture instead return false; } if (isStylusEvent(lastMemento.source, lastMemento.pointerProperties) && !lastMemento.hovering) { // We have non-hovering stylus already active. if (isStylusEvent(lastMemento.source, lastMemento.pointerProperties)) { // A stylus is already active. if (isStylusEvent(motionEntry.source, motionEntry.pointerProperties) && actionMasked == AMOTION_EVENT_ACTION_DOWN) { // If this new event is a stylus from a different device going down, then cancel the old // stylus and allow the new stylus to take over // If this new event is from a different device, then cancel the old // stylus and allow the new stylus to take over, but only if it's going down. // Otherwise, they will start to race each other. return true; } Loading services/inputflinger/tests/InputDispatcher_test.cpp +34 −38 Original line number Diff line number Diff line Loading @@ -2593,9 +2593,9 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusDownWithSpyBlocksTouchDown) { /** * One window. Stylus hover on the window. Next, touch from another device goes down. Ensure that * touch is not dropped, because stylus hover should be ignored. * touch is dropped, because stylus hover takes precedence. */ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDoesNotBlockTouchDown) { TEST_F(InputDispatcherMultiDeviceTest, StylusHoverBlocksTouchDown) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); Loading Loading @@ -2624,34 +2624,29 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDoesNotBlockTouchDown) { .pointer(PointerBuilder(0, ToolType::FINGER).x(141).y(146)) .build()); // Stylus hover is canceled because touch is down window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId), WithCoords(100, 110))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId), WithCoords(140, 145))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId), WithCoords(141, 146))); // Touch is ignored because stylus is hovering // Subsequent stylus movements are ignored // Subsequent stylus movements are delivered correctly mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(101).y(111)) .build()); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId), WithCoords(101, 111))); // but subsequent touches continue to be delivered // and subsequent touches continue to be ignored mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(142).y(147)) .build()); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId), WithCoords(142, 147))); window->assertNoEvents(); } /** * One window. Touch down on the window. Then, stylus hover on the window from another device. * Ensure that touch is not canceled, because stylus hover should be dropped. * Ensure that touch is canceled, because stylus hover should take precedence. */ TEST_F(InputDispatcherMultiDeviceTest, TouchIsNotCanceledByStylusHover) { TEST_F(InputDispatcherMultiDeviceTest, TouchIsCanceledByStylusHover) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); Loading Loading @@ -2683,15 +2678,21 @@ TEST_F(InputDispatcherMultiDeviceTest, TouchIsNotCanceledByStylusHover) { .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(101).y(111)) .build()); // Stylus hover movement is dropped // Stylus hover movement causes touch to be canceled window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDeviceId(touchDeviceId), WithCoords(141, 146))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithDeviceId(stylusDeviceId), WithCoords(100, 110))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId), WithCoords(101, 111))); // Subsequent touch movements are ignored mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(142).y(147)) .build()); // Subsequent touch movements are delivered correctly window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId), WithCoords(142, 147))); window->assertNoEvents(); } /** Loading Loading @@ -3008,11 +3009,11 @@ TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceWithSpy) { * Three windows: a window on the left, a window on the right, and a spy window positioned above * both. * Check hover in left window and touch down in the right window. * At first, spy should receive hover, but the touch down should cancel hovering inside spy. * At first, spy should receive hover. Spy shouldn't receive touch while stylus is hovering. * At the same time, left and right should be getting independent streams of hovering and touch, * respectively. */ TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceHoverBlockedByTouchWithSpy) { TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceHoverBlocksTouchWithSpy) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> spyWindow = Loading Loading @@ -3052,28 +3053,25 @@ TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceHoverBlockedByTouchWithSpy) { .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100)) .build()); leftWindow->assertNoEvents(); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId))); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId))); spyWindow->assertNoEvents(); rightWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId))); // Stylus movements continue. They should be delivered to the left window only. // Stylus movements continue. They should be delivered to the left window and the spy. mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(110).y(110)) .build()); leftWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); // Touch movements continue. They should be delivered to the right window and to the spy // Touch movements continue. They should be delivered to the right window only mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(301).y(101)) .build()); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId))); rightWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId))); Loading Loading @@ -3288,7 +3286,7 @@ TEST_F(InputDispatcherMultiDeviceTest, HoverTapAndSplitTouch) { * While the touch is down, new hover events from the stylus device should be ignored. After the * touch is gone, stylus hovering should start working again. */ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { TEST_F(InputDispatcherMultiDeviceTest, StylusHoverIgnoresTouchTap) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); Loading @@ -3314,10 +3312,7 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100)) .build())); // The touch device should cause hover to stop! window->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId))); // The touch device should be ignored! // Continue hovering with stylus. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, Loading @@ -3327,7 +3322,9 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(60).y(60)) .build())); // Hovers are now ignored // Hovers continue to work window->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); // Lift up the finger ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, Loading @@ -3337,7 +3334,6 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100)) .build())); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(touchDeviceId))); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, Loading @@ -3346,8 +3342,8 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(70).y(70)) .build())); window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER), WithDeviceId(stylusDeviceId))); window->consumeMotionEvent( AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); window->assertNoEvents(); } Loading Loading
services/inputflinger/UnwantedInteractionBlocker.cpp +11 −1 Original line number Diff line number Diff line Loading @@ -67,6 +67,16 @@ const bool DEBUG_OUTBOUND_MOTION = const bool DEBUG_MODEL = __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Model", ANDROID_LOG_INFO); /** * When multi-device input is enabled, we shouldn't use PreferStylusOverTouchBlocker at all. * However, multi-device input has the following default behaviour: hovering stylus rejects touch. * Therefore, if we want to disable that behaviour (and go back to a place where stylus down * blocks touch, but hovering stylus doesn't interact with touch), we should just disable the entire * multi-device input feature. */ const bool ENABLE_MULTI_DEVICE_INPUT = input_flags::enable_multi_device_input() && !input_flags::disable_reject_touch_on_stylus_hover(); // Category (=namespace) name for the input settings that are applied at boot time static const char* INPUT_NATIVE_BOOT = "input_native_boot"; /** Loading Loading @@ -347,7 +357,7 @@ void UnwantedInteractionBlocker::notifyMotion(const NotifyMotionArgs& args) { ALOGD_IF(DEBUG_INBOUND_MOTION, "%s: %s", __func__, args.dump().c_str()); { // acquire lock std::scoped_lock lock(mLock); if (input_flags::enable_multi_device_input()) { if (ENABLE_MULTI_DEVICE_INPUT) { notifyMotionLocked(args); } else { const std::vector<NotifyMotionArgs> processedArgs = Loading
services/inputflinger/dispatcher/InputState.cpp +5 −31 Original line number Diff line number Diff line Loading @@ -24,19 +24,6 @@ namespace android::inputdispatcher { namespace { bool isHoverAction(int32_t action) { switch (MotionEvent::getActionMasked(action)) { case AMOTION_EVENT_ACTION_HOVER_ENTER: case AMOTION_EVENT_ACTION_HOVER_MOVE: case AMOTION_EVENT_ACTION_HOVER_EXIT: { return true; } } return false; } } // namespace InputState::InputState(const IdGenerator& idGenerator) : mIdGenerator(idGenerator) {} InputState::~InputState() {} Loading Loading @@ -113,13 +100,6 @@ bool InputState::trackMotion(const MotionEntry& entry, int32_t action, int32_t f if (isStylusEvent(lastMemento.source, lastMemento.pointerProperties) && !isStylusEvent(entry.source, entry.pointerProperties)) { // We already have a stylus stream, and the new event is not from stylus. if (!lastMemento.hovering) { // If stylus is currently down, reject the new event unconditionally. return false; } } if (!lastMemento.hovering && isHoverAction(action)) { // Reject hovers if already down return false; } } Loading Loading @@ -366,19 +346,13 @@ bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry, return false; } // We want stylus down to block touch and other source types, but stylus hover should not // have such an effect. if (isHoverAction(motionEntry.action) && !lastMemento.hovering) { // New event is a hover. Keep the current non-hovering gesture instead return false; } if (isStylusEvent(lastMemento.source, lastMemento.pointerProperties) && !lastMemento.hovering) { // We have non-hovering stylus already active. if (isStylusEvent(lastMemento.source, lastMemento.pointerProperties)) { // A stylus is already active. if (isStylusEvent(motionEntry.source, motionEntry.pointerProperties) && actionMasked == AMOTION_EVENT_ACTION_DOWN) { // If this new event is a stylus from a different device going down, then cancel the old // stylus and allow the new stylus to take over // If this new event is from a different device, then cancel the old // stylus and allow the new stylus to take over, but only if it's going down. // Otherwise, they will start to race each other. return true; } Loading
services/inputflinger/tests/InputDispatcher_test.cpp +34 −38 Original line number Diff line number Diff line Loading @@ -2593,9 +2593,9 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusDownWithSpyBlocksTouchDown) { /** * One window. Stylus hover on the window. Next, touch from another device goes down. Ensure that * touch is not dropped, because stylus hover should be ignored. * touch is dropped, because stylus hover takes precedence. */ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDoesNotBlockTouchDown) { TEST_F(InputDispatcherMultiDeviceTest, StylusHoverBlocksTouchDown) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); Loading Loading @@ -2624,34 +2624,29 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDoesNotBlockTouchDown) { .pointer(PointerBuilder(0, ToolType::FINGER).x(141).y(146)) .build()); // Stylus hover is canceled because touch is down window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId), WithCoords(100, 110))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId), WithCoords(140, 145))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId), WithCoords(141, 146))); // Touch is ignored because stylus is hovering // Subsequent stylus movements are ignored // Subsequent stylus movements are delivered correctly mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(101).y(111)) .build()); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId), WithCoords(101, 111))); // but subsequent touches continue to be delivered // and subsequent touches continue to be ignored mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(142).y(147)) .build()); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId), WithCoords(142, 147))); window->assertNoEvents(); } /** * One window. Touch down on the window. Then, stylus hover on the window from another device. * Ensure that touch is not canceled, because stylus hover should be dropped. * Ensure that touch is canceled, because stylus hover should take precedence. */ TEST_F(InputDispatcherMultiDeviceTest, TouchIsNotCanceledByStylusHover) { TEST_F(InputDispatcherMultiDeviceTest, TouchIsCanceledByStylusHover) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); Loading Loading @@ -2683,15 +2678,21 @@ TEST_F(InputDispatcherMultiDeviceTest, TouchIsNotCanceledByStylusHover) { .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(101).y(111)) .build()); // Stylus hover movement is dropped // Stylus hover movement causes touch to be canceled window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDeviceId(touchDeviceId), WithCoords(141, 146))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithDeviceId(stylusDeviceId), WithCoords(100, 110))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId), WithCoords(101, 111))); // Subsequent touch movements are ignored mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(142).y(147)) .build()); // Subsequent touch movements are delivered correctly window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId), WithCoords(142, 147))); window->assertNoEvents(); } /** Loading Loading @@ -3008,11 +3009,11 @@ TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceWithSpy) { * Three windows: a window on the left, a window on the right, and a spy window positioned above * both. * Check hover in left window and touch down in the right window. * At first, spy should receive hover, but the touch down should cancel hovering inside spy. * At first, spy should receive hover. Spy shouldn't receive touch while stylus is hovering. * At the same time, left and right should be getting independent streams of hovering and touch, * respectively. */ TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceHoverBlockedByTouchWithSpy) { TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceHoverBlocksTouchWithSpy) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> spyWindow = Loading Loading @@ -3052,28 +3053,25 @@ TEST_F(InputDispatcherMultiDeviceTest, MultiDeviceHoverBlockedByTouchWithSpy) { .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100)) .build()); leftWindow->assertNoEvents(); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId))); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId))); spyWindow->assertNoEvents(); rightWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId))); // Stylus movements continue. They should be delivered to the left window only. // Stylus movements continue. They should be delivered to the left window and the spy. mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(110).y(110)) .build()); leftWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); // Touch movements continue. They should be delivered to the right window and to the spy // Touch movements continue. They should be delivered to the right window only mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(301).y(101)) .build()); spyWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId))); rightWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(touchDeviceId))); Loading Loading @@ -3288,7 +3286,7 @@ TEST_F(InputDispatcherMultiDeviceTest, HoverTapAndSplitTouch) { * While the touch is down, new hover events from the stylus device should be ignored. After the * touch is gone, stylus hovering should start working again. */ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { TEST_F(InputDispatcherMultiDeviceTest, StylusHoverIgnoresTouchTap) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); Loading @@ -3314,10 +3312,7 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100)) .build())); // The touch device should cause hover to stop! window->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId))); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId))); // The touch device should be ignored! // Continue hovering with stylus. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, Loading @@ -3327,7 +3322,9 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(60).y(60)) .build())); // Hovers are now ignored // Hovers continue to work window->consumeMotionEvent( AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); // Lift up the finger ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, Loading @@ -3337,7 +3334,6 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(touchDeviceId) .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100)) .build())); window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(touchDeviceId))); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, Loading @@ -3346,8 +3342,8 @@ TEST_F(InputDispatcherMultiDeviceTest, StylusHoverDroppedWhenTouchTap) { .deviceId(stylusDeviceId) .pointer(PointerBuilder(0, ToolType::STYLUS).x(70).y(70)) .build())); window->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER), WithDeviceId(stylusDeviceId))); window->consumeMotionEvent( AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId))); window->assertNoEvents(); } Loading