Loading services/inputflinger/dispatcher/InputDispatcher.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -4115,8 +4115,10 @@ status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) { options.displayId = displayId; for (const TouchedWindow& window : state.windows) { sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken()); if (channel != nullptr) { synthesizeCancelationEventsForInputChannelLocked(channel, options); } } // Then clear the current touch state so we stop dispatching to them as well. state.filterNonMonitors(); } Loading services/inputflinger/tests/InputDispatcher_test.cpp +85 −9 Original line number Diff line number Diff line Loading @@ -488,6 +488,11 @@ public: expectedFlags); } void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId, expectedFlags); } void assertNoEvents() { InputEvent* event = consume(); ASSERT_EQ(nullptr, event) Loading Loading @@ -639,6 +644,11 @@ static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t s return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y); } static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source, int32_t displayId, int32_t x = 100, int32_t y = 200) { return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, x, y); } static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) { nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC); // Define a valid key event. Loading Loading @@ -847,6 +857,81 @@ TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { 0 /*expectedFlags*/); } class FakeMonitorReceiver : public FakeInputReceiver, public RefBase { public: FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId, bool isGestureMonitor = false) : FakeInputReceiver(dispatcher, name, displayId) { mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor); } sp<IBinder> getToken() { return mServerChannel->getConnectionToken(); } }; // Tests for gesture monitors TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); sp<FakeMonitorReceiver> monitor = new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; window->consumeMotionDown(ADISPLAY_ID_DEFAULT); monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT); } TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); window->setFocus(); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); sp<FakeMonitorReceiver> monitor = new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; window->consumeKeyDown(ADISPLAY_ID_DEFAULT); monitor->assertNoEvents(); } TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); sp<FakeMonitorReceiver> monitor = new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; window->consumeMotionDown(ADISPLAY_ID_DEFAULT); monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT); window->releaseChannel(); mDispatcher->pilferPointers(monitor->getToken()); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; monitor->consumeMotionUp(ADISPLAY_ID_DEFAULT); } /* Test InputDispatcher for MultiDisplay */ class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest { public: Loading Loading @@ -934,15 +1019,6 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) windowInSecondary->assertNoEvents(); } class FakeMonitorReceiver : public FakeInputReceiver, public RefBase { public: FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId, bool isGestureMonitor = false) : FakeInputReceiver(dispatcher, name, displayId) { mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor); } }; // Test per-display input monitors for motion event. TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) { sp<FakeMonitorReceiver> monitorInPrimary = Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -4115,8 +4115,10 @@ status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) { options.displayId = displayId; for (const TouchedWindow& window : state.windows) { sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken()); if (channel != nullptr) { synthesizeCancelationEventsForInputChannelLocked(channel, options); } } // Then clear the current touch state so we stop dispatching to them as well. state.filterNonMonitors(); } Loading
services/inputflinger/tests/InputDispatcher_test.cpp +85 −9 Original line number Diff line number Diff line Loading @@ -488,6 +488,11 @@ public: expectedFlags); } void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId, expectedFlags); } void assertNoEvents() { InputEvent* event = consume(); ASSERT_EQ(nullptr, event) Loading Loading @@ -639,6 +644,11 @@ static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t s return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y); } static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source, int32_t displayId, int32_t x = 100, int32_t y = 200) { return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, x, y); } static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) { nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC); // Define a valid key event. Loading Loading @@ -847,6 +857,81 @@ TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { 0 /*expectedFlags*/); } class FakeMonitorReceiver : public FakeInputReceiver, public RefBase { public: FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId, bool isGestureMonitor = false) : FakeInputReceiver(dispatcher, name, displayId) { mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor); } sp<IBinder> getToken() { return mServerChannel->getConnectionToken(); } }; // Tests for gesture monitors TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); sp<FakeMonitorReceiver> monitor = new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; window->consumeMotionDown(ADISPLAY_ID_DEFAULT); monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT); } TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); window->setFocus(); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); sp<FakeMonitorReceiver> monitor = new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; window->consumeKeyDown(ADISPLAY_ID_DEFAULT); monitor->assertNoEvents(); } TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); sp<FakeMonitorReceiver> monitor = new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; window->consumeMotionDown(ADISPLAY_ID_DEFAULT); monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT); window->releaseChannel(); mDispatcher->pilferPointers(monitor->getToken()); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; monitor->consumeMotionUp(ADISPLAY_ID_DEFAULT); } /* Test InputDispatcher for MultiDisplay */ class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest { public: Loading Loading @@ -934,15 +1019,6 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) windowInSecondary->assertNoEvents(); } class FakeMonitorReceiver : public FakeInputReceiver, public RefBase { public: FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId, bool isGestureMonitor = false) : FakeInputReceiver(dispatcher, name, displayId) { mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor); } }; // Test per-display input monitors for motion event. TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) { sp<FakeMonitorReceiver> monitorInPrimary = Loading