Merge "Fix IME layering issue by non-focusable IME target overlay" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-04-28 16:23:02 +00:00
committed by Android (Google) Code Review
2 changed files with 35 additions and 4 deletions

View File

@@ -60,6 +60,7 @@ import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.LayoutParams;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -4346,11 +4347,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/ */
@VisibleForTesting @VisibleForTesting
SurfaceControl computeImeParent() { SurfaceControl computeImeParent() {
if (mImeLayeringTarget != null && mImeInputTarget != null if (mImeLayeringTarget != null) {
// Ensure changing the IME parent when the layering target that may use IME has
// became to the input target for preventing IME flickers.
// Note that:
// 1) For the imeLayeringTarget that may not use IME but requires IME on top
// of it (e.g. an overlay window with NOT_FOCUSABLE|ALT_FOCUSABLE_IM flags), we allow
// it to re-parent the IME on top the display to keep the legacy behavior.
// 2) Even though the starting window won't use IME, the associated activity
// behind the starting window may request the input. If so, then we should still hold
// the IME parent change until the activity started the input.
boolean imeLayeringTargetMayUseIme =
LayoutParams.mayUseInputMethod(mImeLayeringTarget.mAttrs.flags)
|| mImeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
if (imeLayeringTargetMayUseIme && mImeInputTarget != null
&& mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) { && mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
// Do not change parent if the window hasn't requested IME. // Do not change parent if the window hasn't requested IME.
return null; return null;
} }
}
// Attach it to app if the target is part of an app and such app is covering the entire // Attach it to app if the target is part of an app and such app is covering the entire
// screen. If it's not covering the entire screen the IME might extend beyond the apps // screen. If it's not covering the entire screen the IME might extend beyond the apps
// bounds. // bounds.

View File

@@ -41,8 +41,10 @@ import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90; import static android.view.Surface.ROTATION_90;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -1167,6 +1169,20 @@ public class DisplayContentTests extends WindowTestsBase {
assertNull(mDisplayContent.computeImeParent()); assertNull(mDisplayContent.computeImeParent());
} }
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testComputeImeParent_updateParentWhenTargetNotUseIme() throws Exception {
WindowState overlay = createWindow(null, TYPE_APPLICATION_OVERLAY, "overlay");
overlay.setBounds(100, 100, 200, 200);
overlay.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM;
WindowState app = createWindow(null, TYPE_BASE_APPLICATION, "app");
mDisplayContent.setImeLayeringTarget(overlay);
mDisplayContent.setImeInputTarget(app);
assertFalse(mDisplayContent.shouldImeAttachedToApp());
assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(),
mDisplayContent.computeImeParent());
}
@Test @Test
public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception { public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception {
final DisplayContent dc = createNewDisplay(); final DisplayContent dc = createNewDisplay();