diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 319fd18faca5d..2a68a194b369f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3556,10 +3556,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A WindowState getImeTargetBelowWindow(WindowState w) { final int index = mChildren.indexOf(w); if (index > 0) { - final WindowState target = mChildren.get(index - 1); - if (target.canBeImeTarget()) { - return target; - } + return mChildren.get(index - 1) + .getWindow(WindowState::canBeImeTarget); } return null; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index fae1257fcb924..708abe28c8064 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2385,23 +2385,23 @@ class WindowState extends WindowContainer implements WindowManagerP return false; } - if (PixelFormat.formatHasAlpha(mAttrs.format)) { + if (mAttrs.type == TYPE_APPLICATION_STARTING) { + // Ignore mayUseInputMethod for starting window for now. + // TODO(b/159911356): Remove this special casing (originally added in commit e75d872). + } else if (PixelFormat.formatHasAlpha(mAttrs.format)) { // Support legacy use cases where transparent windows can still be ime target with // FLAG_NOT_FOCUSABLE and ALT_FOCUSABLE_IM set. // Certain apps listen for IME insets using transparent windows and ADJUST_NOTHING to // manually synchronize app content to IME animation b/144619551. // TODO(b/145812508): remove this once new focus management is complete b/141738570 final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); - final int type = mAttrs.type; // Can only be an IME target if both FLAG_NOT_FOCUSABLE and FLAG_ALT_FOCUSABLE_IM are // set or both are cleared...and not a starting window. - if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM) - && type != TYPE_APPLICATION_STARTING) { + if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)) { return false; } - } else if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags) - || mAttrs.type == TYPE_APPLICATION_STARTING) { + } else if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags)) { // Can be an IME target only if: // 1. FLAG_NOT_FOCUSABLE is not set // 2. FLAG_ALT_FOCUSABLE_IM is not set diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 105af4fce394a..30af1d34f5585 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -43,6 +43,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; @@ -273,6 +274,38 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(childWin, imeTarget); } + @Test + public void testComputeImeTarget_startingWindow() { + ActivityRecord activity = createActivityRecord(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + + final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, activity, + "startingWin"); + startingWin.setHasSurface(true); + assertTrue(startingWin.canBeImeTarget()); + + WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */); + assertEquals(startingWin, imeTarget); + startingWin.mHidden = false; + + // Verify that an app window launching behind the starting window becomes the target + final WindowState appWin = createWindow(null, TYPE_BASE_APPLICATION, activity, "appWin"); + appWin.setHasSurface(true); + assertTrue(appWin.canBeImeTarget()); + + imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */); + assertEquals(appWin, imeTarget); + appWin.mHidden = false; + + // Verify that an child window can be an ime target even behind a launching app window + final WindowState childWin = createWindow(appWin, + TYPE_APPLICATION_ATTACHED_DIALOG, "childWin"); + childWin.setHasSurface(true); + assertTrue(childWin.canBeImeTarget()); + imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */); + assertEquals(childWin, imeTarget); + } + /** * This tests stack movement between displays and proper stack's, task's and app token's display * container references updates.