Loading core/java/android/view/WindowManager.java +19 −9 Original line number Diff line number Diff line Loading @@ -1454,11 +1454,22 @@ public interface WindowManager extends ViewManager { @Deprecated 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: when set, inverts the input method focusability of the window. * * The effect of setting this flag depends on whether {@link #FLAG_NOT_FOCUSABLE} is set: * <p> * If {@link #FLAG_NOT_FOCUSABLE} is <em>not</em> set, i.e. when the window is focusable, * setting this flag prevents this window from becoming the target of the input method. * Consequently, it will <em>not</em> be able to interact with the input method, * and will be layered above the input method (unless there is another input method * target above it). * * <p> * If {@link #FLAG_NOT_FOCUSABLE} <em>is</em> set, setting this flag requests for the window * to be the input method target even though the window is <em>not</em> focusable. * Consequently, it will be layered below the input method. * Note: Windows that set {@link #FLAG_NOT_FOCUSABLE} cannot interact with the input method, * regardless of this flag. */ public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; Loading Loading @@ -2142,13 +2153,12 @@ public interface WindowManager extends ViewManager { * focus. In particular, this checks the * {@link #FLAG_NOT_FOCUSABLE} and {@link #FLAG_ALT_FOCUSABLE_IM} * flags and returns true if the combination of the two corresponds * to a window that needs to be behind the input method so that the * user can type into it. * to a window that can use the input method. * * @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 {@code true} if a window with the given flags would be able to * use the input method, {@code false} if not. */ public static boolean mayUseInputMethod(int flags) { return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE Loading services/core/java/com/android/server/wm/WindowState.java +9 −12 Original line number Diff line number Diff line Loading @@ -2394,12 +2394,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP 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 } else { // TODO(b/145812508): Clean this up in S, may depend on b/141738570 // The current logic lets windows become the "ime target" even though they are // not-focusable and can thus never actually start input. // Ideally, this would reject windows where mayUseInputMethod() == false, but this // also impacts Z-ordering of and delivery of IME insets to child windows, which means // that simply disallowing non-focusable windows would break apps. // See b/159438771, b/144619551. final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); // Can only be an IME target if both FLAG_NOT_FOCUSABLE and FLAG_ALT_FOCUSABLE_IM are Loading @@ -2407,12 +2410,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)) { return false; } } 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 // 3. not a starting window. return false; } if (DEBUG_INPUT_METHOD) { Loading services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +3 −15 Original line number Diff line number Diff line Loading @@ -67,7 +67,6 @@ import static org.mockito.Mockito.when; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; Loading Loading @@ -229,21 +228,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()); // 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; // 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()); // Verify PINNED windows can't be IME target. int initialMode = appWindow.mActivityRecord.getWindowingMode(); Loading Loading
core/java/android/view/WindowManager.java +19 −9 Original line number Diff line number Diff line Loading @@ -1454,11 +1454,22 @@ public interface WindowManager extends ViewManager { @Deprecated 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: when set, inverts the input method focusability of the window. * * The effect of setting this flag depends on whether {@link #FLAG_NOT_FOCUSABLE} is set: * <p> * If {@link #FLAG_NOT_FOCUSABLE} is <em>not</em> set, i.e. when the window is focusable, * setting this flag prevents this window from becoming the target of the input method. * Consequently, it will <em>not</em> be able to interact with the input method, * and will be layered above the input method (unless there is another input method * target above it). * * <p> * If {@link #FLAG_NOT_FOCUSABLE} <em>is</em> set, setting this flag requests for the window * to be the input method target even though the window is <em>not</em> focusable. * Consequently, it will be layered below the input method. * Note: Windows that set {@link #FLAG_NOT_FOCUSABLE} cannot interact with the input method, * regardless of this flag. */ public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; Loading Loading @@ -2142,13 +2153,12 @@ public interface WindowManager extends ViewManager { * focus. In particular, this checks the * {@link #FLAG_NOT_FOCUSABLE} and {@link #FLAG_ALT_FOCUSABLE_IM} * flags and returns true if the combination of the two corresponds * to a window that needs to be behind the input method so that the * user can type into it. * to a window that can use the input method. * * @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 {@code true} if a window with the given flags would be able to * use the input method, {@code false} if not. */ public static boolean mayUseInputMethod(int flags) { return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE Loading
services/core/java/com/android/server/wm/WindowState.java +9 −12 Original line number Diff line number Diff line Loading @@ -2394,12 +2394,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP 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 } else { // TODO(b/145812508): Clean this up in S, may depend on b/141738570 // The current logic lets windows become the "ime target" even though they are // not-focusable and can thus never actually start input. // Ideally, this would reject windows where mayUseInputMethod() == false, but this // also impacts Z-ordering of and delivery of IME insets to child windows, which means // that simply disallowing non-focusable windows would break apps. // See b/159438771, b/144619551. final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); // Can only be an IME target if both FLAG_NOT_FOCUSABLE and FLAG_ALT_FOCUSABLE_IM are Loading @@ -2407,12 +2410,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)) { return false; } } 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 // 3. not a starting window. return false; } if (DEBUG_INPUT_METHOD) { Loading
services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +3 −15 Original line number Diff line number Diff line Loading @@ -67,7 +67,6 @@ import static org.mockito.Mockito.when; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; Loading Loading @@ -229,21 +228,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()); // 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; // 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()); // Verify PINNED windows can't be IME target. int initialMode = appWindow.mActivityRecord.getWindowingMode(); Loading