Loading core/java/android/view/WindowManager.java +9 −16 Original line number Diff line number Diff line Loading @@ -1313,14 +1313,11 @@ 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: 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. /** 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. */ public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; Loading Loading @@ -1998,16 +1995,12 @@ public interface WindowManager extends ViewManager { * * @param flags The current window manager flags. * * @return Returns true if such a window should be behind/interact * with an input method, false if not. * @return Returns {@code true} if such a window should be behind/interact * with an input method, {@code false} if not. */ public static boolean mayUseInputMethod(int flags) { switch (flags&(FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) { case 0: case FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM: return true; } return false; return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE && (flags & FLAG_ALT_FOCUSABLE_IM) != FLAG_ALT_FOCUSABLE_IM; } /** Loading services/core/java/com/android/server/wm/WindowState.java +21 −7 Original line number Diff line number Diff line Loading @@ -2149,15 +2149,29 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } 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. // 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; } } else if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags) || mAttrs.type == TYPE_APPLICATION_STARTING) { // 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. return false; } if (DEBUG_INPUT_METHOD) { Slog.i(TAG_WM, "isVisibleOrAdding " + this + ": " + isVisibleOrAdding()); Loading services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +17 −6 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import static org.mockito.Mockito.when; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.Size; Loading Loading @@ -222,8 +223,7 @@ 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 without FLAG_ALT_FOCUSABLE_IM prevents the window from being // an IME target. // Setting FLAG_NOT_FOCUSABLE prevents the window from being an IME target. appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; Loading @@ -231,7 +231,7 @@ public class WindowStateTests extends WindowTestsBase { appWindow.setHasSurface(true); imeWindow.setHasSurface(true); // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets // Windows with FLAG_NOT_FOCUSABLE can't be IME targets assertFalse(appWindow.canBeImeTarget()); assertFalse(imeWindow.canBeImeTarget()); Loading @@ -239,11 +239,22 @@ 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 can be IME target while an IME window can never be an IME // target regardless of its visibility or flags. assertTrue(appWindow.canBeImeTarget()); // 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()); // b/145812508: special legacy use-case for transparent/translucent windows. appWindow.mAttrs.format = PixelFormat.TRANSPARENT; assertTrue(appWindow.canBeImeTarget()); appWindow.mAttrs.format = PixelFormat.OPAQUE; appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM; assertFalse(appWindow.canBeImeTarget()); appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; assertTrue(appWindow.canBeImeTarget()); // Make windows invisible appWindow.hideLw(false /* doAnimation */); imeWindow.hideLw(false /* doAnimation */); Loading Loading
core/java/android/view/WindowManager.java +9 −16 Original line number Diff line number Diff line Loading @@ -1313,14 +1313,11 @@ 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: 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. /** 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. */ public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; Loading Loading @@ -1998,16 +1995,12 @@ public interface WindowManager extends ViewManager { * * @param flags The current window manager flags. * * @return Returns true if such a window should be behind/interact * with an input method, false if not. * @return Returns {@code true} if such a window should be behind/interact * with an input method, {@code false} if not. */ public static boolean mayUseInputMethod(int flags) { switch (flags&(FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) { case 0: case FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM: return true; } return false; return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE && (flags & FLAG_ALT_FOCUSABLE_IM) != FLAG_ALT_FOCUSABLE_IM; } /** Loading
services/core/java/com/android/server/wm/WindowState.java +21 −7 Original line number Diff line number Diff line Loading @@ -2149,15 +2149,29 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } 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. // 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; } } else if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags) || mAttrs.type == TYPE_APPLICATION_STARTING) { // 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. return false; } if (DEBUG_INPUT_METHOD) { Slog.i(TAG_WM, "isVisibleOrAdding " + this + ": " + isVisibleOrAdding()); Loading
services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +17 −6 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import static org.mockito.Mockito.when; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.Size; Loading Loading @@ -222,8 +223,7 @@ 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 without FLAG_ALT_FOCUSABLE_IM prevents the window from being // an IME target. // Setting FLAG_NOT_FOCUSABLE prevents the window from being an IME target. appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; Loading @@ -231,7 +231,7 @@ public class WindowStateTests extends WindowTestsBase { appWindow.setHasSurface(true); imeWindow.setHasSurface(true); // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets // Windows with FLAG_NOT_FOCUSABLE can't be IME targets assertFalse(appWindow.canBeImeTarget()); assertFalse(imeWindow.canBeImeTarget()); Loading @@ -239,11 +239,22 @@ 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 can be IME target while an IME window can never be an IME // target regardless of its visibility or flags. assertTrue(appWindow.canBeImeTarget()); // 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()); // b/145812508: special legacy use-case for transparent/translucent windows. appWindow.mAttrs.format = PixelFormat.TRANSPARENT; assertTrue(appWindow.canBeImeTarget()); appWindow.mAttrs.format = PixelFormat.OPAQUE; appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM; assertFalse(appWindow.canBeImeTarget()); appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; assertTrue(appWindow.canBeImeTarget()); // Make windows invisible appWindow.hideLw(false /* doAnimation */); imeWindow.hideLw(false /* doAnimation */); Loading