diff options
author | Vishnu Nair <vishnun@google.com> | 2022-02-07 23:43:52 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-02-07 23:43:52 +0000 |
commit | 7fc62b023f0e4983e48cc62c722dd521a8850f39 (patch) | |
tree | 25f2fc1a0f10bad694d14cb498ec404068491e23 | |
parent | d5a65ea539a2bb939da68780ee6ed4ab35ae73fb (diff) | |
parent | 212dcf44f696158778939aad4619e320148890eb (diff) | |
download | native-7fc62b023f0e4983e48cc62c722dd521a8850f39.tar.gz |
InputFlinger: Add DROP_INPUT feature flags am: 212dcf44f6
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/16740115
Change-Id: I09b68edc0216094d00661d2b7c3124a7e9548830
-rw-r--r-- | include/input/InputWindow.h | 2 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 30 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 3 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 40 |
4 files changed, 74 insertions, 1 deletions
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index e2c95870cf..cea57ec10d 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -128,7 +128,7 @@ struct InputWindowInfo : public Parcelable { DISABLE_TOUCH_PAD_GESTURES = 0x00000001, NO_INPUT_CHANNEL = 0x00000002, DISABLE_USER_ACTIVITY = 0x00000004, - INPUT_FEATURE_DROP_INPUT = 0x00000008, + DROP_INPUT = 0x00000008, }; /* These values are filled in by the WM and passed through SurfaceFlinger diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index ce1f266cfb..7ed0d4eaef 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -1815,6 +1815,11 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( return InputEventInjectionResult::FAILED; } + // Drop key events if requested by input feature + if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) { + return InputEventInjectionResult::FAILED; + } + // Compatibility behavior: raise ANR if there is a focused application, but no focused window. // Only start counting when we have a focused event to dispatch. The ANR is canceled if we // start interacting with another application via touch (app switch). This code can be removed @@ -2040,6 +2045,11 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( } } + // Drop touch events if requested by input feature + if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) { + newTouchedWindowHandle = nullptr; + } + // Drop events that can't be trusted due to occlusion if (newTouchedWindowHandle != nullptr && mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) { @@ -2126,6 +2136,13 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( sp<InputWindowHandle> oldTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle(); newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState); + + // Drop touch events if requested by input feature + if (newTouchedWindowHandle != nullptr && + shouldDropInput(entry, newTouchedWindowHandle)) { + newTouchedWindowHandle = nullptr; + } + if (oldTouchedWindowHandle != newTouchedWindowHandle && oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) { if (DEBUG_FOCUS) { @@ -6128,6 +6145,19 @@ bool InputDispatcher::waitForIdle() { return result == std::cv_status::no_timeout; } +bool InputDispatcher::shouldDropInput(const EventEntry& entry, + const sp<InputWindowHandle>& windowHandle) const { + if (windowHandle->getInfo()->inputFeatures.test(InputWindowInfo::Feature::DROP_INPUT)) { + ALOGW("Dropping %s event targeting %s as requested by inputFeatures={%s} on display " + "%" PRId32 ".", + entry.getDescription().c_str(), windowHandle->getName().c_str(), + windowHandle->getInfo()->inputFeatures.string().c_str(), + windowHandle->getInfo()->displayId); + return true; + } + return false; +} + /** * Sets focus to the window identified by the token. This must be called * after updating any input window handles. diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 30652c65ee..053e82144e 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -530,6 +530,9 @@ private: std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle, const sp<InputWindowHandle>& windowHandle); + bool shouldDropInput(const EventEntry& entry, const sp<InputWindowHandle>& windowHandle) const + REQUIRES(mLock); + // Manage the dispatch cycle for a single connection. // These methods are deliberately not Interruptible because doing all of the work // with the mutex held makes it easier to ensure that connection invariants are maintained. diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 50b65cad5d..c973698b20 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -5331,4 +5331,44 @@ TEST_F(InputDispatcherDragTests, DragAndDrop_InvalidWindow) { mSecondWindow->assertNoEvents(); } +class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {}; + +TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) { + std::shared_ptr<FakeApplicationHandle> app = std::make_shared<FakeApplicationHandle>(); + + sp<FakeWindowHandle> window = + new FakeWindowHandle(app, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT); + window->setInputFeatures(InputWindowInfo::Feature::DROP_INPUT); + mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, app); + window->setFocusable(true); + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); + setFocusedWindow(window); + window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/); + + // With the flag set, window should not get any input + NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); + mDispatcher->notifyKey(&keyArgs); + window->assertNoEvents(); + + NotifyMotionArgs motionArgs = + generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT); + mDispatcher->notifyMotion(&motionArgs); + window->assertNoEvents(); + + // With the flag cleared, the window should get input + window->setInputFeatures(static_cast<InputWindowInfo::Feature>(0)); + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); + + keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT); + mDispatcher->notifyKey(&keyArgs); + window->consumeKeyUp(ADISPLAY_ID_DEFAULT); + + motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT); + mDispatcher->notifyMotion(&motionArgs); + window->consumeMotionDown(ADISPLAY_ID_DEFAULT); + window->assertNoEvents(); +} + } // namespace android::inputdispatcher |