GestureNav: Fix broken exclusion rect calculation for modal windows am: b106379310 am: eb6ad762fc

am: 60ed8ce91e

Change-Id: I483fd8d92423abfb6a5585a9e64ea75ed906dbfb
This commit is contained in:
Adrian Roos
2019-07-05 09:18:06 -07:00
committed by android-build-merger
3 changed files with 45 additions and 4 deletions

View File

@@ -5162,7 +5162,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()
@@ -5170,12 +5170,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()) {

View File

@@ -3030,6 +3030,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()) {

View File

@@ -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) {