Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f86cec5a authored by Vishnu Nair's avatar Vishnu Nair Committed by Automerger Merge Worker
Browse files

InputFlinger: Add DROP_INPUT feature flags am: 0f13fe55

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/16508593

Change-Id: I3c51969c29fa3b501964651183930e7c7774b071
parents 0c340742 0f13fe55
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -1465,6 +1465,11 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
        return INPUT_EVENT_INJECTION_FAILED;
    }

    // Drop key events if requested by input feature
    if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
        return INPUT_EVENT_INJECTION_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
@@ -1694,6 +1699,11 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
            }
        }

        // Drop touch events if requested by input feature
        if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
            newTouchedWindowHandle = nullptr;
        }

        // Also don't send the new touch event to unresponsive gesture monitors
        newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);

@@ -1758,6 +1768,13 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
                    tempTouchState.getFirstForegroundWindowHandle();
            sp<InputWindowHandle> 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) {
@@ -5099,4 +5116,16 @@ 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 & InputWindowInfo::INPUT_FEATURE_DROP_INPUT) {
        ALOGW("Dropping %s event targeting %s as requested by inputFeatures=0x%08x on display "
              "%" PRId32 ".",
              EventEntry::typeToString(entry.type), windowHandle->getName().c_str(),
              windowHandle->getInfo()->inputFeatures, windowHandle->getInfo()->displayId);
        return true;
    }
    return false;
}

} // namespace android::inputdispatcher
+3 −0
Original line number Diff line number Diff line
@@ -420,6 +420,9 @@ private:
    std::string getApplicationWindowLabel(const sp<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.
+42 −0
Original line number Diff line number Diff line
@@ -785,6 +785,8 @@ public:

    void setFocus(bool hasFocus) { mInfo.hasFocus = hasFocus; }

    void setInputFeatures(int32_t inputFeatures) { mInfo.inputFeatures = inputFeatures; }

    void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
        mInfo.dispatchingTimeout = timeout.count();
    }
@@ -903,6 +905,8 @@ public:
        mInfo.ownerUid = ownerUid;
    }

    void setFlags(int32_t layoutParamsFlags) { mInfo.layoutParamsFlags = layoutParamsFlags; }

private:
    const std::string mName;
    std::unique_ptr<FakeInputReceiver> mInputReceiver;
@@ -3112,4 +3116,42 @@ TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
    mFocusedWindow->assertNoEvents();
}

class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {};

TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) {
    sp<FakeApplicationHandle> application = new FakeApplicationHandle();
    sp<FakeWindowHandle> window =
            new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
    window->setInputFeatures(InputWindowInfo::INPUT_FEATURE_DROP_INPUT);
    mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
    window->setFocus(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {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(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