Loading services/inputflinger/dispatcher/InputDispatcher.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -298,6 +298,12 @@ void InputDispatcher::dispatchOnce() { if (runCommandsLockedInterruptible()) { nextWakeupTime = LONG_LONG_MIN; } // We are about to enter an infinitely long sleep, because we have no commands or // pending or queued events if (nextWakeupTime == LONG_LONG_MAX) { mDispatcherEnteredIdle.notify_all(); } } // release lock // Wait for callback or timeout or wake. (make sure we round up, not down) Loading Loading @@ -4582,4 +4588,22 @@ void InputDispatcher::monitor() { mDispatcherIsAlive.wait(_l); } /** * Wake up the dispatcher and wait until it processes all events and commands. * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so * this method can be safely called from any thread, as long as you've ensured that * the work you are interested in completing has already been queued. */ bool InputDispatcher::waitForIdle() { /** * Timeout should represent the longest possible time that a device might spend processing * events and commands. */ constexpr std::chrono::duration TIMEOUT = 100ms; std::unique_lock lock(mLock); mLooper->wake(); std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT); return result == std::cv_status::no_timeout; } } // namespace android::inputdispatcher services/inputflinger/dispatcher/InputDispatcher.h +2 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ public: virtual void dump(std::string& dump) override; virtual void monitor() override; virtual bool waitForIdle() override; virtual void dispatchOnce() override; Loading Loading @@ -129,6 +130,7 @@ private: std::mutex mLock; std::condition_variable mDispatcherIsAlive; std::condition_variable mDispatcherEnteredIdle; sp<Looper> mLooper; Loading services/inputflinger/dispatcher/include/InputDispatcherInterface.h +8 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,14 @@ public: /* Called by the heatbeat to ensures that the dispatcher has not deadlocked. */ virtual void monitor() = 0; /** * Wait until dispatcher is idle. That means, there are no further events to be processed, * and all of the policy callbacks have been completed. * Return true if the dispatcher is idle. * Return false if the timeout waiting for the dispatcher to become idle has expired. */ virtual bool waitForIdle() = 0; /* Runs a single iteration of the dispatch loop. * Nominally processes one queued event, a timeout, or a response from an input consumer. * Loading services/inputflinger/tests/InputDispatcher_test.cpp +113 −25 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ protected: public: FakeInputDispatcherPolicy() { mOnPointerDownToken.clear(); } void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) { Loading @@ -66,17 +65,41 @@ public: void assertFilterInputEventWasNotCalled() { ASSERT_EQ(nullptr, mFilteredEvent); } void assertNotifyConfigurationChangedWasCalled(nsecs_t when) { ASSERT_TRUE(mConfigurationChangedTime) << "Timed out waiting for configuration changed call"; ASSERT_EQ(*mConfigurationChangedTime, when); mConfigurationChangedTime = std::nullopt; } void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) { ASSERT_TRUE(mLastNotifySwitch); // We do not check sequenceNum because it is not exposed to the policy EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime); EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags); EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues); EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask); mLastNotifySwitch = std::nullopt; } void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) { ASSERT_EQ(mOnPointerDownToken, touchedToken) << "Expected token from onPointerDownOutsideFocus was not matched"; reset(); ASSERT_EQ(touchedToken, mOnPointerDownToken); mOnPointerDownToken.clear(); } void assertOnPointerDownWasNotCalled() { ASSERT_TRUE(mOnPointerDownToken == nullptr) << "Expected onPointerDownOutsideFocus to not have been called"; } private: std::unique_ptr<InputEvent> mFilteredEvent; std::optional<nsecs_t> mConfigurationChangedTime; sp<IBinder> mOnPointerDownToken; std::optional<NotifySwitchArgs> mLastNotifySwitch; virtual void notifyConfigurationChanged(nsecs_t) { virtual void notifyConfigurationChanged(nsecs_t when) override { mConfigurationChangedTime = when; } virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&, Loading Loading @@ -128,7 +151,13 @@ private: return false; } virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) { virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) override { /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is * essentially a passthrough for notifySwitch. */ mLastNotifySwitch = NotifySwitchArgs(1 /*sequenceNum*/, when, policyFlags, switchValues, switchMask); } virtual void pokeUserActivity(nsecs_t, int32_t) { Loading Loading @@ -163,8 +192,6 @@ private: mFilteredEvent = nullptr; } void reset() { mOnPointerDownToken.clear(); } }; Loading Loading @@ -351,9 +378,30 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { << "Should reject motion events with duplicate pointer ids."; } /* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */ TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) { constexpr nsecs_t eventTime = 20; NotifyConfigurationChangedArgs args(10 /*sequenceNum*/, eventTime); mDispatcher->notifyConfigurationChanged(&args); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime); } TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) { NotifySwitchArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/, 2 /*switchMask*/); mDispatcher->notifySwitch(&args); // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener args.policyFlags |= POLICY_FLAG_TRUSTED; mFakePolicy->assertNotifySwitchWasCalled(args); } // --- InputDispatcherTest SetInputWindowTest --- static const int32_t INJECT_EVENT_TIMEOUT = 500; static const int32_t DISPATCHING_TIMEOUT = 100; static constexpr int32_t INJECT_EVENT_TIMEOUT = 500; static constexpr int32_t DISPATCHING_TIMEOUT = 100; class FakeApplicationHandle : public InputApplicationHandle { public: Loading Loading @@ -536,9 +584,7 @@ public: InputWindowHandle::releaseChannel(); } protected: virtual bool handled() { return true; } virtual bool handled() override { return true; } bool mFocused; Rect mFrame; Loading Loading @@ -761,6 +807,51 @@ TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) { windowRight->assertNoEvents(); } TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); window->setFocus(); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); mDispatcher->notifyKey(&keyArgs); // Window should receive key down event. window->consumeKeyDown(ADISPLAY_ID_DEFAULT); // When device reset happens, that key stream should be terminated with FLAG_CANCELED // on the app side. NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID); mDispatcher->notifyDeviceReset(&args); window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT, AKEY_EVENT_FLAG_CANCELED); } TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); NotifyMotionArgs motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT); mDispatcher->notifyMotion(&motionArgs); // Window should receive motion down event. window->consumeMotionDown(ADISPLAY_ID_DEFAULT); // When device reset happens, that motion stream should be terminated with ACTION_CANCEL // on the app side. NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID); mDispatcher->notifyDeviceReset(&args); window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*expectedFlags*/); } /* Test InputDispatcher for MultiDisplay */ class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest { public: Loading Loading @@ -924,7 +1015,7 @@ protected: motionArgs = generateMotionArgs( AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId); mDispatcher->notifyMotion(&motionArgs); ASSERT_TRUE(mDispatcher->waitForIdle()); if (expectToBeFiltered) { mFakePolicy->assertFilterInputEventWasCalled(motionArgs); } else { Loading @@ -939,6 +1030,7 @@ protected: mDispatcher->notifyKey(&keyArgs); keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP); mDispatcher->notifyKey(&keyArgs); ASSERT_TRUE(mDispatcher->waitForIdle()); if (expectToBeFiltered) { mFakePolicy->assertFilterInputEventWasCalled(keyArgs); Loading Loading @@ -1029,9 +1121,8 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Succe ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken()); } Loading @@ -1042,10 +1133,9 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPo ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); mFakePolicy->assertOnPointerDownEquals(nullptr); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownWasNotCalled(); } // Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't Loading @@ -1053,10 +1143,9 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPo TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) { ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); mFakePolicy->assertOnPointerDownEquals(nullptr); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownWasNotCalled(); } // Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action Loading @@ -1068,10 +1157,9 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, mFocusedWindowTouchPoint, mFocusedWindowTouchPoint)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); mFakePolicy->assertOnPointerDownEquals(nullptr); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownWasNotCalled(); } } // namespace android::inputdispatcher Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -298,6 +298,12 @@ void InputDispatcher::dispatchOnce() { if (runCommandsLockedInterruptible()) { nextWakeupTime = LONG_LONG_MIN; } // We are about to enter an infinitely long sleep, because we have no commands or // pending or queued events if (nextWakeupTime == LONG_LONG_MAX) { mDispatcherEnteredIdle.notify_all(); } } // release lock // Wait for callback or timeout or wake. (make sure we round up, not down) Loading Loading @@ -4582,4 +4588,22 @@ void InputDispatcher::monitor() { mDispatcherIsAlive.wait(_l); } /** * Wake up the dispatcher and wait until it processes all events and commands. * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so * this method can be safely called from any thread, as long as you've ensured that * the work you are interested in completing has already been queued. */ bool InputDispatcher::waitForIdle() { /** * Timeout should represent the longest possible time that a device might spend processing * events and commands. */ constexpr std::chrono::duration TIMEOUT = 100ms; std::unique_lock lock(mLock); mLooper->wake(); std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT); return result == std::cv_status::no_timeout; } } // namespace android::inputdispatcher
services/inputflinger/dispatcher/InputDispatcher.h +2 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ public: virtual void dump(std::string& dump) override; virtual void monitor() override; virtual bool waitForIdle() override; virtual void dispatchOnce() override; Loading Loading @@ -129,6 +130,7 @@ private: std::mutex mLock; std::condition_variable mDispatcherIsAlive; std::condition_variable mDispatcherEnteredIdle; sp<Looper> mLooper; Loading
services/inputflinger/dispatcher/include/InputDispatcherInterface.h +8 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,14 @@ public: /* Called by the heatbeat to ensures that the dispatcher has not deadlocked. */ virtual void monitor() = 0; /** * Wait until dispatcher is idle. That means, there are no further events to be processed, * and all of the policy callbacks have been completed. * Return true if the dispatcher is idle. * Return false if the timeout waiting for the dispatcher to become idle has expired. */ virtual bool waitForIdle() = 0; /* Runs a single iteration of the dispatch loop. * Nominally processes one queued event, a timeout, or a response from an input consumer. * Loading
services/inputflinger/tests/InputDispatcher_test.cpp +113 −25 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ protected: public: FakeInputDispatcherPolicy() { mOnPointerDownToken.clear(); } void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) { Loading @@ -66,17 +65,41 @@ public: void assertFilterInputEventWasNotCalled() { ASSERT_EQ(nullptr, mFilteredEvent); } void assertNotifyConfigurationChangedWasCalled(nsecs_t when) { ASSERT_TRUE(mConfigurationChangedTime) << "Timed out waiting for configuration changed call"; ASSERT_EQ(*mConfigurationChangedTime, when); mConfigurationChangedTime = std::nullopt; } void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) { ASSERT_TRUE(mLastNotifySwitch); // We do not check sequenceNum because it is not exposed to the policy EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime); EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags); EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues); EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask); mLastNotifySwitch = std::nullopt; } void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) { ASSERT_EQ(mOnPointerDownToken, touchedToken) << "Expected token from onPointerDownOutsideFocus was not matched"; reset(); ASSERT_EQ(touchedToken, mOnPointerDownToken); mOnPointerDownToken.clear(); } void assertOnPointerDownWasNotCalled() { ASSERT_TRUE(mOnPointerDownToken == nullptr) << "Expected onPointerDownOutsideFocus to not have been called"; } private: std::unique_ptr<InputEvent> mFilteredEvent; std::optional<nsecs_t> mConfigurationChangedTime; sp<IBinder> mOnPointerDownToken; std::optional<NotifySwitchArgs> mLastNotifySwitch; virtual void notifyConfigurationChanged(nsecs_t) { virtual void notifyConfigurationChanged(nsecs_t when) override { mConfigurationChangedTime = when; } virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&, Loading Loading @@ -128,7 +151,13 @@ private: return false; } virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) { virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) override { /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is * essentially a passthrough for notifySwitch. */ mLastNotifySwitch = NotifySwitchArgs(1 /*sequenceNum*/, when, policyFlags, switchValues, switchMask); } virtual void pokeUserActivity(nsecs_t, int32_t) { Loading Loading @@ -163,8 +192,6 @@ private: mFilteredEvent = nullptr; } void reset() { mOnPointerDownToken.clear(); } }; Loading Loading @@ -351,9 +378,30 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { << "Should reject motion events with duplicate pointer ids."; } /* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */ TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) { constexpr nsecs_t eventTime = 20; NotifyConfigurationChangedArgs args(10 /*sequenceNum*/, eventTime); mDispatcher->notifyConfigurationChanged(&args); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime); } TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) { NotifySwitchArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/, 2 /*switchMask*/); mDispatcher->notifySwitch(&args); // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener args.policyFlags |= POLICY_FLAG_TRUSTED; mFakePolicy->assertNotifySwitchWasCalled(args); } // --- InputDispatcherTest SetInputWindowTest --- static const int32_t INJECT_EVENT_TIMEOUT = 500; static const int32_t DISPATCHING_TIMEOUT = 100; static constexpr int32_t INJECT_EVENT_TIMEOUT = 500; static constexpr int32_t DISPATCHING_TIMEOUT = 100; class FakeApplicationHandle : public InputApplicationHandle { public: Loading Loading @@ -536,9 +584,7 @@ public: InputWindowHandle::releaseChannel(); } protected: virtual bool handled() { return true; } virtual bool handled() override { return true; } bool mFocused; Rect mFrame; Loading Loading @@ -761,6 +807,51 @@ TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) { windowRight->assertNoEvents(); } TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); window->setFocus(); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); mDispatcher->notifyKey(&keyArgs); // Window should receive key down event. window->consumeKeyDown(ADISPLAY_ID_DEFAULT); // When device reset happens, that key stream should be terminated with FLAG_CANCELED // on the app side. NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID); mDispatcher->notifyDeviceReset(&args); window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT, AKEY_EVENT_FLAG_CANCELED); } TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); NotifyMotionArgs motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT); mDispatcher->notifyMotion(&motionArgs); // Window should receive motion down event. window->consumeMotionDown(ADISPLAY_ID_DEFAULT); // When device reset happens, that motion stream should be terminated with ACTION_CANCEL // on the app side. NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID); mDispatcher->notifyDeviceReset(&args); window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*expectedFlags*/); } /* Test InputDispatcher for MultiDisplay */ class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest { public: Loading Loading @@ -924,7 +1015,7 @@ protected: motionArgs = generateMotionArgs( AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId); mDispatcher->notifyMotion(&motionArgs); ASSERT_TRUE(mDispatcher->waitForIdle()); if (expectToBeFiltered) { mFakePolicy->assertFilterInputEventWasCalled(motionArgs); } else { Loading @@ -939,6 +1030,7 @@ protected: mDispatcher->notifyKey(&keyArgs); keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP); mDispatcher->notifyKey(&keyArgs); ASSERT_TRUE(mDispatcher->waitForIdle()); if (expectToBeFiltered) { mFakePolicy->assertFilterInputEventWasCalled(keyArgs); Loading Loading @@ -1029,9 +1121,8 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Succe ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken()); } Loading @@ -1042,10 +1133,9 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPo ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); mFakePolicy->assertOnPointerDownEquals(nullptr); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownWasNotCalled(); } // Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't Loading @@ -1053,10 +1143,9 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPo TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) { ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT)) << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); mFakePolicy->assertOnPointerDownEquals(nullptr); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownWasNotCalled(); } // Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action Loading @@ -1068,10 +1157,9 @@ TEST_F(InputDispatcherOnPointerDownOutsideFocus, injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, mFocusedWindowTouchPoint, mFocusedWindowTouchPoint)) << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED"; // Call monitor to wait for the command queue to get flushed. mDispatcher->monitor(); mFakePolicy->assertOnPointerDownEquals(nullptr); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertOnPointerDownWasNotCalled(); } } // namespace android::inputdispatcher