Add ImeTargetVisibilityPolicy#isReadyComputeImeParent

Wrap some complex reparent ime parent logic from
DisplayContent to ImeTargetVisibilityPolicy.

We only move the logic into a static method, there
shouldn't have behavior changes.

Bug: 258048231
Test: presubmit
Change-Id: I344333a3d0eedf780cd47152e0f4c20022cb5fed
This commit is contained in:
Wilson Wu
2023-01-13 17:53:44 +08:00
parent e124ea5351
commit 787b003d7b
2 changed files with 38 additions and 19 deletions

View File

@@ -59,7 +59,6 @@ import static android.view.WindowInsets.Type.systemBars;
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_LOCAL;
import static android.view.WindowManager.LayoutParams;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -4633,24 +4632,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
@VisibleForTesting
SurfaceControl computeImeParent() {
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())) {
// Do not change parent if the window hasn't requested IME.
return null;
}
if (!ImeTargetVisibilityPolicy.isReadyToComputeImeParent(mImeLayeringTarget,
mImeInputTarget)) {
return null;
}
// 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

View File

@@ -17,7 +17,10 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import android.os.IBinder;
import android.view.WindowManager;
/**
* A class for {@link com.android.server.inputmethod.InputMethodManagerService} to
@@ -42,4 +45,36 @@ public abstract class ImeTargetVisibilityPolicy {
* @return {@code true} if success, {@code false} otherwise.
*/
public abstract boolean updateImeParent(IBinder imeTarget, int displayId);
/**
* Called when {@link DisplayContent#computeImeParent()} to check if it's valid to keep
* computing the ime parent.
*
* @return {@code true} to keep computing the ime parent, {@code false} to defer this operation
*/
public static boolean isReadyToComputeImeParent(WindowState imeLayeringTarget,
InputTarget imeInputTarget) {
if (imeLayeringTarget == null) {
return false;
}
// 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 =
WindowManager.LayoutParams.mayUseInputMethod(imeLayeringTarget.mAttrs.flags)
|| imeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
// Do not change parent if the window hasn't requested IME.
var inputAndLayeringTargetsDisagree = (imeInputTarget == null
|| imeLayeringTarget.mActivityRecord != imeInputTarget.getActivityRecord());
var inputTargetStale = imeLayeringTargetMayUseIme && inputAndLayeringTargetsDisagree;
return !inputTargetStale;
}
}