Loading services/inputflinger/dispatcher/InputDispatcher.cpp +8 −6 Original line number Diff line number Diff line Loading @@ -1896,14 +1896,14 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con entry->interceptKeyWakeupTime = 0; } const ui::LogicalDisplayId displayId = getTargetDisplayId(*entry); // Give the policy a chance to intercept the key. if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) { if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) { sp<IBinder> focusedWindowToken = mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry)); sp<IBinder> focusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId); auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) { doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry); auto command = [this, focusedWindowToken, displayId, entry]() REQUIRES(mLock) { doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, displayId, *entry); }; postCommandLocked(std::move(command)); return false; // wait for the command to run Loading Loading @@ -1952,7 +1952,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets); // Add monitor channels from event's or focused display. addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry)); addGlobalMonitoringTargetsLocked(inputTargets, displayId); if (mTracer) { ensureEventTraced(*entry); Loading Loading @@ -6632,8 +6632,10 @@ void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel, } void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken, const ui::LogicalDisplayId displayId, const KeyEntry& entry) { const KeyEvent event = createKeyEvent(entry); KeyEvent event = createKeyEvent(entry); event.setDisplayId(displayId); std::variant<nsecs_t, KeyEntry::InterceptKeyResult> interceptResult; nsecs_t delay = 0; { // release lock Loading services/inputflinger/dispatcher/InputDispatcher.h +1 −0 Original line number Diff line number Diff line Loading @@ -898,6 +898,7 @@ private: const std::shared_ptr<Connection>& connection, uint32_t seq, bool handled, nsecs_t consumeTime) REQUIRES(mLock); void doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken, const ui::LogicalDisplayId displayId, const KeyEntry& entry) REQUIRES(mLock); void onFocusChangedLocked(const FocusResolver::FocusChanges& changes, const std::unique_ptr<trace::EventTrackerInterface>& traceTracker, Loading services/inputflinger/tests/FakeInputDispatcherPolicy.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -411,10 +411,14 @@ void FakeInputDispatcherPolicy::interceptMotionBeforeQueueing(ui::LogicalDisplay int32_t, nsecs_t, uint32_t&) {} std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent& event, uint32_t) { if (std::holds_alternative<inputdispatcher::KeyEntry::InterceptKeyResult>( mInterceptKeyBeforeDispatchingResult)) { if (inputdispatcher::KeyEntry::InterceptKeyResult* result = std::get_if<inputdispatcher::KeyEntry::InterceptKeyResult>( &mInterceptKeyBeforeDispatchingResult)) { if (*result == inputdispatcher::KeyEntry::InterceptKeyResult::SKIP) { mKeysConsumedByPolicy.emplace(event); } return mInterceptKeyBeforeDispatchingResult; } Loading @@ -430,6 +434,15 @@ FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, con return delay; } void FakeInputDispatcherPolicy::assertKeyConsumedByPolicy( const ::testing::Matcher<KeyEvent>& matcher) { ASSERT_THAT(*mKeysConsumedByPolicy.popWithTimeout(100ms), matcher); } void FakeInputDispatcherPolicy::assertNoKeysConsumedByPolicy() { ASSERT_TRUE(mKeysConsumedByPolicy.empty()); } std::optional<KeyEvent> FakeInputDispatcherPolicy::dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent& event, uint32_t) { Loading services/inputflinger/tests/FakeInputDispatcherPolicy.h +4 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "InputDispatcherInterface.h" #include "NotifyArgs.h" #include "TestEventMatchers.h" #include <condition_variable> #include <functional> Loading Loading @@ -119,6 +120,8 @@ public: void setInterceptKeyBeforeDispatchingResult( std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> result); void assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay); void assertKeyConsumedByPolicy(const ::testing::Matcher<KeyEvent>& matcher); void assertNoKeysConsumedByPolicy(); private: std::mutex mLock; Loading Loading @@ -150,6 +153,7 @@ private: std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> mInterceptKeyBeforeDispatchingResult; BlockingQueue<KeyEvent> mKeysConsumedByPolicy; BlockingQueue<std::pair<int32_t /*deviceId*/, std::set<gui::Uid>>> mNotifiedInteractions; Loading services/inputflinger/tests/InputDispatcher_test.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -5695,6 +5695,33 @@ TEST_F(InputDispatcherTest, InterceptKeyIfKeyUp) { window->consumeKeyUp(ui::LogicalDisplayId::DEFAULT); } /** * Keys are sent to policy with correct displayId */ TEST_F(InputDispatcherTest, InterceptKeyBeforeDispatchingPolicy_getsCorrectDisplayId) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Fake Window", ui::LogicalDisplayId(2)); window->setFocusable(true); mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); mDispatcher->setFocusedDisplay(ui::LogicalDisplayId(2)); setFocusedWindow(window); window->consumeFocusEvent(true); mFakePolicy->setInterceptKeyBeforeDispatchingResult( inputdispatcher::KeyEntry::InterceptKeyResult::SKIP); mDispatcher->notifyKey(KeyArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_KEYBOARD) .keyCode(AKEYCODE_A) .displayId(ui::LogicalDisplayId::INVALID) .build()); mFakePolicy->assertKeyConsumedByPolicy( AllOf(WithKeyCode(AKEYCODE_A), WithDisplayId(ui::LogicalDisplayId(2)))); } /** * Two windows. First is a regular window. Second does not overlap with the first, and has * WATCH_OUTSIDE_TOUCH. Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +8 −6 Original line number Diff line number Diff line Loading @@ -1896,14 +1896,14 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con entry->interceptKeyWakeupTime = 0; } const ui::LogicalDisplayId displayId = getTargetDisplayId(*entry); // Give the policy a chance to intercept the key. if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) { if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) { sp<IBinder> focusedWindowToken = mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry)); sp<IBinder> focusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId); auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) { doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry); auto command = [this, focusedWindowToken, displayId, entry]() REQUIRES(mLock) { doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, displayId, *entry); }; postCommandLocked(std::move(command)); return false; // wait for the command to run Loading Loading @@ -1952,7 +1952,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets); // Add monitor channels from event's or focused display. addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry)); addGlobalMonitoringTargetsLocked(inputTargets, displayId); if (mTracer) { ensureEventTraced(*entry); Loading Loading @@ -6632,8 +6632,10 @@ void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel, } void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken, const ui::LogicalDisplayId displayId, const KeyEntry& entry) { const KeyEvent event = createKeyEvent(entry); KeyEvent event = createKeyEvent(entry); event.setDisplayId(displayId); std::variant<nsecs_t, KeyEntry::InterceptKeyResult> interceptResult; nsecs_t delay = 0; { // release lock Loading
services/inputflinger/dispatcher/InputDispatcher.h +1 −0 Original line number Diff line number Diff line Loading @@ -898,6 +898,7 @@ private: const std::shared_ptr<Connection>& connection, uint32_t seq, bool handled, nsecs_t consumeTime) REQUIRES(mLock); void doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken, const ui::LogicalDisplayId displayId, const KeyEntry& entry) REQUIRES(mLock); void onFocusChangedLocked(const FocusResolver::FocusChanges& changes, const std::unique_ptr<trace::EventTrackerInterface>& traceTracker, Loading
services/inputflinger/tests/FakeInputDispatcherPolicy.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -411,10 +411,14 @@ void FakeInputDispatcherPolicy::interceptMotionBeforeQueueing(ui::LogicalDisplay int32_t, nsecs_t, uint32_t&) {} std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent& event, uint32_t) { if (std::holds_alternative<inputdispatcher::KeyEntry::InterceptKeyResult>( mInterceptKeyBeforeDispatchingResult)) { if (inputdispatcher::KeyEntry::InterceptKeyResult* result = std::get_if<inputdispatcher::KeyEntry::InterceptKeyResult>( &mInterceptKeyBeforeDispatchingResult)) { if (*result == inputdispatcher::KeyEntry::InterceptKeyResult::SKIP) { mKeysConsumedByPolicy.emplace(event); } return mInterceptKeyBeforeDispatchingResult; } Loading @@ -430,6 +434,15 @@ FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, con return delay; } void FakeInputDispatcherPolicy::assertKeyConsumedByPolicy( const ::testing::Matcher<KeyEvent>& matcher) { ASSERT_THAT(*mKeysConsumedByPolicy.popWithTimeout(100ms), matcher); } void FakeInputDispatcherPolicy::assertNoKeysConsumedByPolicy() { ASSERT_TRUE(mKeysConsumedByPolicy.empty()); } std::optional<KeyEvent> FakeInputDispatcherPolicy::dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent& event, uint32_t) { Loading
services/inputflinger/tests/FakeInputDispatcherPolicy.h +4 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "InputDispatcherInterface.h" #include "NotifyArgs.h" #include "TestEventMatchers.h" #include <condition_variable> #include <functional> Loading Loading @@ -119,6 +120,8 @@ public: void setInterceptKeyBeforeDispatchingResult( std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> result); void assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay); void assertKeyConsumedByPolicy(const ::testing::Matcher<KeyEvent>& matcher); void assertNoKeysConsumedByPolicy(); private: std::mutex mLock; Loading Loading @@ -150,6 +153,7 @@ private: std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> mInterceptKeyBeforeDispatchingResult; BlockingQueue<KeyEvent> mKeysConsumedByPolicy; BlockingQueue<std::pair<int32_t /*deviceId*/, std::set<gui::Uid>>> mNotifiedInteractions; Loading
services/inputflinger/tests/InputDispatcher_test.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -5695,6 +5695,33 @@ TEST_F(InputDispatcherTest, InterceptKeyIfKeyUp) { window->consumeKeyUp(ui::LogicalDisplayId::DEFAULT); } /** * Keys are sent to policy with correct displayId */ TEST_F(InputDispatcherTest, InterceptKeyBeforeDispatchingPolicy_getsCorrectDisplayId) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Fake Window", ui::LogicalDisplayId(2)); window->setFocusable(true); mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); mDispatcher->setFocusedDisplay(ui::LogicalDisplayId(2)); setFocusedWindow(window); window->consumeFocusEvent(true); mFakePolicy->setInterceptKeyBeforeDispatchingResult( inputdispatcher::KeyEntry::InterceptKeyResult::SKIP); mDispatcher->notifyKey(KeyArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_KEYBOARD) .keyCode(AKEYCODE_A) .displayId(ui::LogicalDisplayId::INVALID) .build()); mFakePolicy->assertKeyConsumedByPolicy( AllOf(WithKeyCode(AKEYCODE_A), WithDisplayId(ui::LogicalDisplayId(2)))); } /** * Two windows. First is a regular window. Second does not overlap with the first, and has * WATCH_OUTSIDE_TOUCH. Loading