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

Commit eb6ad762 authored by Adrian Roos's avatar Adrian Roos Committed by android-build-merger
Browse files

GestureNav: Fix broken exclusion rect calculation for modal windows

am: b1063793

Change-Id: I648cecc7d0fc7e24692c6eee0f27db072bdf8bbd
parents 63f2e002 b1063793
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -5172,7 +5172,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        final int[] remainingLeftRight =
                {mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};

        // Traverse all windows bottom up to assemble the gesture exclusion rects.
        // Traverse all windows top down to assemble the gesture exclusion rects.
        // For each window, we only take the rects that fall within its touchable region.
        forAllWindows(w -> {
            if (w.cantReceiveTouchInput() || !w.isVisible()
@@ -5180,12 +5180,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                    || unhandled.isEmpty()) {
                return;
            }
            final boolean modal =
                    (w.mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;

            // Get the touchable region of the window, and intersect with where the screen is still
            // touchable, i.e. touchable regions on top are not covering it yet.
            w.getTouchableRegion(touchableRegion);
            w.getEffectiveTouchableRegion(touchableRegion);
            touchableRegion.op(unhandled, Op.INTERSECT);

            if (w.isImplicitlyExcludingAllSystemGestures()) {
+19 −0
Original line number Diff line number Diff line
@@ -3023,6 +3023,25 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        subtractTouchExcludeRegionIfNeeded(outRegion);
    }

    /**
     * Get the effective touchable region in global coordinates.
     *
     * In contrast to {@link #getTouchableRegion}, this takes into account
     * {@link WindowManager.LayoutParams#FLAG_NOT_TOUCH_MODAL touch modality.}
     */
    void getEffectiveTouchableRegion(Region outRegion) {
        final boolean modal = (mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
        final DisplayContent dc = getDisplayContent();

        if (modal && dc != null) {
            outRegion.set(dc.getBounds());
            cropRegionToStackBoundsIfNeeded(outRegion);
            subtractTouchExcludeRegionIfNeeded(outRegion);
        } else {
            getTouchableRegion(outRegion);
        }
    }

    private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
        final Task task = getTask();
        if (task == null || !task.cropWindowsToStackBounds()) {
+24 −0
Original line number Diff line number Diff line
@@ -793,6 +793,30 @@ public class DisplayContentTests extends WindowTestsBase {
        assertEquals(expected, dc.calculateSystemGestureExclusion());
    }

    @Test
    public void testCalculateSystemGestureExclusion_modal() throws Exception {
        final DisplayContent dc = createNewDisplay();
        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "base");
        win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
        win.setSystemGestureExclusion(Collections.singletonList(new Rect(0, 0, 1000, 1000)));

        final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "modal");
        win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
        win2.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
        win2.getAttrs().width = 10;
        win2.getAttrs().height = 10;
        win2.setSystemGestureExclusion(Collections.emptyList());

        dc.setLayoutNeeded();
        dc.performLayout(true /* initial */, false /* updateImeWindows */);

        win.setHasSurface(true);
        win2.setHasSurface(true);

        final Region expected = Region.obtain();
        assertEquals(expected, dc.calculateSystemGestureExclusion());
    }

    @Test
    public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
        synchronized (mWm.mGlobalLock) {