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

Commit 4d5c21d5 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11591048 from a080e370 to 24Q3-release

Change-Id: Ib81f18b9dc79bfad2bf14e398b362cc06e1d3425
parents a431be1b a080e370
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -73,14 +73,6 @@ void WindowInfo::addTouchableRegion(const Rect& region) {
    touchableRegion.orSelf(region);
}

bool WindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
    return touchableRegion.contains(x, y);
}

bool WindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
    return x >= frame.left && x < frame.right && y >= frame.top && y < frame.bottom;
}

bool WindowInfo::supportsSplitTouch() const {
    return !inputConfig.test(InputConfig::PREVENT_SPLITTING);
}
+0 −4
Original line number Diff line number Diff line
@@ -254,10 +254,6 @@ struct WindowInfo : public Parcelable {

    void addTouchableRegion(const Rect& region);

    bool touchableRegionContainsPoint(int32_t x, int32_t y) const;

    bool frameContainsPoint(int32_t x, int32_t y) const;

    bool supportsSplitTouch() const;

    bool isSpy() const;
+17 −4
Original line number Diff line number Diff line
@@ -598,6 +598,18 @@ bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, float
    return true;
}

// Returns true if the given window's frame can occlude pointer events at the given display
// location.
bool windowOccludesTouchAt(const WindowInfo& windowInfo, int displayId, float x, float y,
                           const ui::Transform& displayTransform) {
    if (windowInfo.displayId != displayId) {
        return false;
    }
    const auto frame = displayTransform.transform(windowInfo.frame);
    const auto p = floor(displayTransform.transform(x, y));
    return p.x >= frame.left && p.x < frame.right && p.y >= frame.top && p.y < frame.bottom;
}

bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
    return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
            isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
@@ -3105,7 +3117,7 @@ static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
 * If neither of those is true, then it means the touch can be allowed.
 */
InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
        const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
        const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
    const WindowInfo* windowInfo = windowHandle->getInfo();
    int32_t displayId = windowInfo->displayId;
    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
@@ -3119,7 +3131,8 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo
            break; // All future windows are below us. Exit early.
        }
        const WindowInfo* otherInfo = otherHandle->getInfo();
        if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
        if (canBeObscuredBy(windowHandle, otherHandle) &&
            windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(displayId)) &&
            !haveSameApplicationToken(windowInfo, otherInfo)) {
            if (DEBUG_TOUCH_OCCLUSION) {
                info.debugInfo.push_back(
@@ -3189,7 +3202,7 @@ bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionIn
}

bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
                                                    int32_t x, int32_t y) const {
                                                    float x, float y) const {
    int32_t displayId = windowHandle->getInfo()->displayId;
    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
    for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
@@ -3198,7 +3211,7 @@ bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>&
        }
        const WindowInfo* otherInfo = otherHandle->getInfo();
        if (canBeObscuredBy(windowHandle, otherHandle) &&
            otherInfo->frameContainsPoint(x, y)) {
            windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(displayId))) {
            return true;
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -566,11 +566,11 @@ private:
    };

    TouchOcclusionInfo computeTouchOcclusionInfoLocked(
            const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const
            const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const
            REQUIRES(mLock);
    bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock);
    bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
                                       int32_t x, int32_t y) const REQUIRES(mLock);
                                       float x, float y) const REQUIRES(mLock);
    bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
            REQUIRES(mLock);
    std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info,
+88 −0
Original line number Diff line number Diff line
@@ -5367,6 +5367,94 @@ TEST_P(InputDispatcherDisplayOrientationFixture, HitTestInDifferentOrientations)
    window->assertNoEvents();
}
// This test verifies the occlusion detection for all rotations of the display by tapping
// in different locations on the display, specifically points close to the four corners of a
// window.
TEST_P(InputDispatcherDisplayOrientationFixture, BlockUntrustClickInDifferentOrientations) {
    constexpr static int32_t displayWidth = 400;
    constexpr static int32_t displayHeight = 800;
    std::shared_ptr<FakeApplicationHandle> untrustedWindowApplication =
            std::make_shared<FakeApplicationHandle>();
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    const auto rotation = GetParam();
    // Set up the display with the specified rotation.
    const bool isRotated = rotation == ui::ROTATION_90 || rotation == ui::ROTATION_270;
    const int32_t logicalDisplayWidth = isRotated ? displayHeight : displayWidth;
    const int32_t logicalDisplayHeight = isRotated ? displayWidth : displayHeight;
    const ui::Transform displayTransform(ui::Transform::toRotationFlags(rotation),
                                         logicalDisplayWidth, logicalDisplayHeight);
    addDisplayInfo(ADISPLAY_ID_DEFAULT, displayTransform);
    // Create a window that not trusted.
    const Rect untrustedWindowFrameInLogicalDisplay(100, 100, 200, 300);
    const Rect untrustedWindowFrameInDisplay =
            displayTransform.inverse().transform(untrustedWindowFrameInLogicalDisplay);
    sp<FakeWindowHandle> untrustedWindow =
            sp<FakeWindowHandle>::make(untrustedWindowApplication, mDispatcher, "UntrustedWindow",
                                       ADISPLAY_ID_DEFAULT);
    untrustedWindow->setFrame(untrustedWindowFrameInDisplay, displayTransform);
    untrustedWindow->setTrustedOverlay(false);
    untrustedWindow->setTouchOcclusionMode(TouchOcclusionMode::BLOCK_UNTRUSTED);
    untrustedWindow->setTouchable(false);
    untrustedWindow->setAlpha(1.0f);
    untrustedWindow->setOwnerInfo(gui::Pid{1}, gui::Uid{101});
    addWindow(untrustedWindow);
    // Create a simple app window below the untrusted window.
    const Rect simpleAppWindowFrameInLogicalDisplay(0, 0, 300, 600);
    const Rect simpleAppWindowFrameInDisplay =
            displayTransform.inverse().transform(simpleAppWindowFrameInLogicalDisplay);
    sp<FakeWindowHandle> simpleAppWindow =
            sp<FakeWindowHandle>::make(application, mDispatcher, "SimpleAppWindow",
                                       ADISPLAY_ID_DEFAULT);
    simpleAppWindow->setFrame(simpleAppWindowFrameInDisplay, displayTransform);
    simpleAppWindow->setOwnerInfo(gui::Pid{2}, gui::Uid{202});
    addWindow(simpleAppWindow);
    // The following points in logical display space should be inside the untrusted window, so
    // the simple window could not receive events that coordinate is these point.
    static const std::array<vec2, 4> untrustedPoints{
            {{100, 100}, {199.99, 100}, {100, 299.99}, {199.99, 299.99}}};
    for (const auto untrustedPoint : untrustedPoints) {
        const vec2 p = displayTransform.inverse().transform(untrustedPoint);
        const PointF pointInDisplaySpace{p.x, p.y};
        mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
                                                     AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
                                                     {pointInDisplaySpace}));
        mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_UP,
                                                     AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
                                                     {pointInDisplaySpace}));
    }
    untrustedWindow->assertNoEvents();
    simpleAppWindow->assertNoEvents();
    // The following points in logical display space should be outside the untrusted window, so
    // the simple window should receive events that coordinate is these point.
    static const std::array<vec2, 5> trustedPoints{
            {{200, 100}, {100, 300}, {200, 300}, {100, 99.99}, {99.99, 100}}};
    for (const auto trustedPoint : trustedPoints) {
        const vec2 p = displayTransform.inverse().transform(trustedPoint);
        const PointF pointInDisplaySpace{p.x, p.y};
        mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
                                                     AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
                                                     {pointInDisplaySpace}));
        simpleAppWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT,
                                           AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
        mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_UP,
                                                     AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
                                                     {pointInDisplaySpace}));
        simpleAppWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT,
                                         AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
    }
    untrustedWindow->assertNoEvents();
}
// Run the precision tests for all rotations.
INSTANTIATE_TEST_SUITE_P(InputDispatcherDisplayOrientationTests,
                         InputDispatcherDisplayOrientationFixture,
Loading