summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/WindowManager.java28
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java17
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 */);