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

Commit 28bcd4b2 authored by Antonio Kantek's avatar Antonio Kantek Committed by Android (Google) Code Review
Browse files

Merge "(TouchMode Permission 2.1/n) Add permission check when switching touch mode"

parents eb5d1b58 ea47acbc
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
// Number of recent events to keep for debugging purposes.
constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;

// Event log tags. See EventLogTags.logtags for reference
// Event log tags. See EventLogTags.logtags for reference.
constexpr int LOGTAG_INPUT_INTERACTION = 62000;
constexpr int LOGTAG_INPUT_FOCUS = 62001;
constexpr int LOGTAG_INPUT_CANCEL = 62003;
@@ -4903,23 +4903,42 @@ void InputDispatcher::setInputFilterEnabled(bool enabled) {
    mLooper->wake();
}

void InputDispatcher::setInTouchMode(bool inTouchMode) {
bool InputDispatcher::setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid,
                                     bool hasPermission) {
    bool needWake = false;
    {
        std::scoped_lock lock(mLock);
        if (mInTouchMode == inTouchMode) {
            return;
            return false;
        }
        if (DEBUG_TOUCH_MODE) {
            ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode),
                  toString(inTouchMode));
            // TODO(b/198487159): Also print the current last interacted apps.
            ALOGD("Request to change touch mode from %s to %s (calling pid=%d, uid=%d, "
                  "hasPermission=%s)",
                  toString(mInTouchMode), toString(inTouchMode), pid, uid, toString(hasPermission));
        }
        if (!hasPermission) {
            const sp<IBinder> focusedToken =
                    mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);

            //  TODO(b/198487159): if no window is currently focused, then we need to check the last
            //      interacted window (within 1 second timeout). We should allow touch mode change
            //      if the last interacted window owner's pid/uid match the calling ones.
            if (focusedToken == nullptr) {
                return false;
            }
            const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
            if (windowHandle == nullptr) {
                return false;
            }
            const WindowInfo* windowInfo = windowHandle->getInfo();
            if (pid != windowInfo->ownerPid || uid != windowInfo->ownerUid) {
                return false;
            }
        }

        // TODO(b/198499018): Store touch mode per display.
        mInTouchMode = inTouchMode;

        // TODO(b/198487159): Enforce that only last interacted apps can change touch mode.
        auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
        needWake = enqueueInboundEventLocked(std::move(entry));
    } // release lock
@@ -4927,6 +4946,7 @@ void InputDispatcher::setInTouchMode(bool inTouchMode) {
    if (needWake) {
        mLooper->wake();
    }
    return true;
}

void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ public:
    void setFocusedDisplay(int32_t displayId) override;
    void setInputDispatchMode(bool enabled, bool frozen) override;
    void setInputFilterEnabled(bool enabled) override;
    void setInTouchMode(bool inTouchMode) override;
    bool setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission) override;
    void setMaximumObscuringOpacityForTouch(float opacity) override;
    void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) override;

+3 −1
Original line number Diff line number Diff line
@@ -123,8 +123,10 @@ public:
     * Touch mode is a global state that apps may enter / exit based on specific
     * user interactions with input devices.
     * If true, the device is in touch mode.
     *
     * Returns true when changing touch mode state.
     */
    virtual void setInTouchMode(bool inTouchMode) = 0;
    virtual bool setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission) = 0;

    /**
     * Sets the maximum allowed obscuring opacity by UID to propagate touches.
+16 −6
Original line number Diff line number Diff line
@@ -2997,6 +2997,7 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window =
            new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
    const WindowInfo& windowInfo = *window->getInfo();

    // Set focused application.
    mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -3013,7 +3014,8 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
    window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);

    SCOPED_TRACE("Disable touch mode");
    mDispatcher->setInTouchMode(false);
    mDispatcher->setInTouchMode(false, windowInfo.ownerPid, windowInfo.ownerUid,
                                /* hasPermission */ true);
    window->consumeTouchModeEvent(false);
    window->setFocusable(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
@@ -3026,7 +3028,8 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
    window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);

    SCOPED_TRACE("Enable touch mode again");
    mDispatcher->setInTouchMode(true);
    mDispatcher->setInTouchMode(true, windowInfo.ownerPid, windowInfo.ownerUid,
                                /* hasPermission */ true);
    window->consumeTouchModeEvent(true);
    window->setFocusable(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
@@ -6231,19 +6234,23 @@ protected:
        mWindow->consumeFocusEvent(true);
    }

    void changeAndVerifyTouchMode(bool inTouchMode) {
        mDispatcher->setInTouchMode(inTouchMode);
    void changeAndVerifyTouchMode(bool inTouchMode, int32_t pid, int32_t uid, bool hasPermission) {
        mDispatcher->setInTouchMode(inTouchMode, pid, uid, hasPermission);
        mWindow->consumeTouchModeEvent(inTouchMode);
        mSecondWindow->consumeTouchModeEvent(inTouchMode);
    }
};

TEST_F(InputDispatcherTouchModeChangedTests, ChangeTouchModeOnFocusedWindow) {
    changeAndVerifyTouchMode(!InputDispatcher::kDefaultInTouchMode);
    const WindowInfo& windowInfo = *mWindow->getInfo();
    changeAndVerifyTouchMode(!InputDispatcher::kDefaultInTouchMode, windowInfo.ownerPid,
                             windowInfo.ownerUid, /* hasPermission */ false);
}

TEST_F(InputDispatcherTouchModeChangedTests, EventIsNotGeneratedIfNotChangingTouchMode) {
    mDispatcher->setInTouchMode(InputDispatcher::kDefaultInTouchMode);
    const WindowInfo& windowInfo = *mWindow->getInfo();
    mDispatcher->setInTouchMode(InputDispatcher::kDefaultInTouchMode, windowInfo.ownerPid,
                                windowInfo.ownerUid, /* hasPermission */ true);
    mWindow->assertNoEvents();
    mSecondWindow->assertNoEvents();
}
@@ -6798,4 +6805,7 @@ TEST_F(InputDispatcherStylusInterceptorTest, SpyWindowStylusInterceptor) {
    window->assertNoEvents();
}

// TODO(b/198487159): Add permission tests for touch mode switch once the validation is put in
//     place.

} // namespace android::inputdispatcher