From 57e2e1cd2e554e9b99dd440fc6ed1439e5a7e1a8 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 13 Mar 2020 22:54:36 +0800 Subject: [PATCH] Don't dispatch IME insets if the target is above IME The target should not get insets from IME if it is above IME. Fix: 151098513 Test: atest InsetsStateControllerTest Change-Id: I68f1defeb09aa1f303bf0f56f3e4766c7effd589 --- .../com/android/server/wm/DisplayContent.java | 12 ++++ .../com/android/server/wm/DisplayPolicy.java | 11 +--- .../server/wm/InsetsStateController.java | 32 ++++++++--- .../com/android/server/wm/WindowState.java | 7 ++- .../server/wm/InsetsStateControllerTest.java | 57 +++++++++++++++++++ 5 files changed, 101 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index aad242dbc338f..374e9b5216441 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -656,6 +656,9 @@ class DisplayContent extends WindowContainer mUpdateWindowsForAnimator = w -> { WindowStateAnimator winAnimator = w.mWinAnimator; final ActivityRecord activity = w.mActivityRecord; @@ -747,6 +750,12 @@ class DisplayContent extends WindowContainer implements WindowManagerP */ boolean mSeamlesslyRotated = false; + /** + * Indicates if this window is behind IME. Only windows behind IME can get insets from IME. + */ + boolean mBehindIme = false; + /** * Surface insets from the previous call to relayout(), used to track * if we are changing the Surface insets. diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index bfb126f7052ce..db7bce4c87530 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -19,10 +19,12 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; +import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; @@ -146,6 +148,61 @@ public class InsetsStateControllerTest extends WindowTestsBase { assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_NAVIGATION_BAR)); } + @Test + public void testStripForDispatch_belowIme() { + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); + + getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + + assertNotNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME)); + } + + @Test + public void testStripForDispatch_aboveIme() { + final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + + getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + + assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME)); + } + + @Test + public void testStripForDispatch_childWindow_altFocusable() { + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + + final WindowState child = createWindow(app, TYPE_APPLICATION, "child"); + child.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM; + + final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); + + // IME cannot be the IME target. + ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + + getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + + assertNull(getController().getInsetsForDispatch(child).peekSource(ITYPE_IME)); + } + + @Test + public void testStripForDispatch_childWindow_splitScreen() { + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + + final WindowState child = createWindow(app, TYPE_APPLICATION, "child"); + child.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + child.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + + final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); + + // IME cannot be the IME target. + ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + + getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + + assertNull(getController().getInsetsForDispatch(child).peekSource(ITYPE_IME)); + } + @Test public void testImeForDispatch() { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");