diff options
3 files changed, 32 insertions, 27 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index c62e69cc5ed1..7a817b6d4dc4 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1181,7 +1181,8 @@ public interface WindowManager extends ViewManager { * a soft input method, so it will be Z-ordered and positioned * independently of any active input method (typically this means it * gets Z-ordered on top of the input method, so it can use the full - * screen for its content and cover the input method if needed.) */ + * screen for its content and cover the input method if needed. You + * can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */ public static final int FLAG_NOT_FOCUSABLE = 0x00000008; /** Window flag: this window can never receive touch events. */ @@ -1287,11 +1288,14 @@ public interface WindowManager extends ViewManager { * set for you by Window as described in {@link Window#setFlags}.*/ public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000; - /** Window flag: When set, input method can't interact with the focusable window - * and can be placed to use more space and cover the input method. - * Note: When combined with {@link #FLAG_NOT_FOCUSABLE}, this flag has no - * effect since input method cannot interact with windows having {@link #FLAG_NOT_FOCUSABLE} - * flag set. + /** Window flag: invert the state of {@link #FLAG_NOT_FOCUSABLE} with + * respect to how this window interacts with the current method. That + * is, if FLAG_NOT_FOCUSABLE is set and this flag is set, then the + * window will behave as if it needs to interact with the input method + * and thus be placed behind/away from it; if FLAG_NOT_FOCUSABLE is + * not set and this flag is set, then the window will behave as if it + * doesn't need to interact with the input method and can be placed + * to use more space and cover the input method. */ public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; @@ -1989,12 +1993,16 @@ public interface WindowManager extends ViewManager { * * @param flags The current window manager flags. * - * @return Returns {@code true} if such a window should be behind/interact - * with an input method, (@code false} if not. + * @return Returns true if such a window should be behind/interact + * with an input method, false if not. */ public static boolean mayUseInputMethod(int flags) { - return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE - && (flags & FLAG_ALT_FOCUSABLE_IM) != FLAG_ALT_FOCUSABLE_IM; + switch (flags&(FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) { + case 0: + case FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM: + return true; + } + return false; } /** diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 8cc0736b7537..dcf4b38db8ab 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -35,6 +35,7 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; +import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; @@ -2162,12 +2163,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } - // Can be an IME target only if: - // 1. FLAG_NOT_FOCUSABLE is not set - // 2. FLAG_ALT_FOCUSABLE_IM is not set - // 3. not a starting window. - if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags) - || mAttrs.type == TYPE_APPLICATION_STARTING) { + 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) { return false; } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index eed5ef52c8e1..72baedb5ed66 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -222,7 +222,8 @@ public class WindowStateTests extends WindowTestsBase { final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow"); - // Setting FLAG_NOT_FOCUSABLE prevents the window from being an IME target. + // Setting FLAG_NOT_FOCUSABLE without FLAG_ALT_FOCUSABLE_IM prevents the window from being + // an IME target. appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; @@ -230,7 +231,7 @@ public class WindowStateTests extends WindowTestsBase { appWindow.setHasSurface(true); imeWindow.setHasSurface(true); - // Windows with FLAG_NOT_FOCUSABLE can't be IME targets + // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets assertFalse(appWindow.canBeImeTarget()); assertFalse(imeWindow.canBeImeTarget()); @@ -238,16 +239,10 @@ public class WindowStateTests extends WindowTestsBase { appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); - // Visible app window with flags FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM can't be IME - // target while an IME window can never be an IME target regardless of its visibility - // or flags. - assertFalse(appWindow.canBeImeTarget()); - assertFalse(imeWindow.canBeImeTarget()); - - appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM; - assertFalse(appWindow.canBeImeTarget()); - appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; + // Visible app window with flags can be IME target while an IME window can never be an IME + // target regardless of its visibility or flags. assertTrue(appWindow.canBeImeTarget()); + assertFalse(imeWindow.canBeImeTarget()); // Make windows invisible appWindow.hideLw(false /* doAnimation */); |