Loading services/core/java/com/android/server/wm/DisplayContent.java +2 −4 Original line number Diff line number Diff line Loading @@ -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() Loading @@ -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()) { Loading services/core/java/com/android/server/wm/WindowState.java +19 −0 Original line number Diff line number Diff line Loading @@ -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()) { Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +24 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +2 −4 Original line number Diff line number Diff line Loading @@ -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() Loading @@ -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()) { Loading
services/core/java/com/android/server/wm/WindowState.java +19 −0 Original line number Diff line number Diff line Loading @@ -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()) { Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +24 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading