diff options
| author | 2016-12-07 12:22:08 -0800 | |
|---|---|---|
| committer | 2016-12-07 12:22:08 -0800 | |
| commit | 805d9ecc476134ffafc85a07b05e94a14b1d398c (patch) | |
| tree | cac1fc4975b42939b5d3765d655a0c2d9a7d4600 | |
| parent | 929a81b81dc5ebdedf0fb4ba0aaa0ba544829304 (diff) | |
Don't allow IME windows to be IME targets
IME targets are required to be below the IME windows and that wouldn't
be possible if the IME window is its own target which leads to issues
elsewhere in the code where that is expected to be the case.
Change-Id: I34a723ff4ce2519cd80e0eea0eaea04712b6cf8f
Fixes: 33336368
Test: bit FrameworksServicesTests:com.android.server.wm.WindowStateTests
3 files changed, 76 insertions, 50 deletions
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 4b8c4bb1635f..5eab7950a529 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1925,9 +1925,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean canBeImeTarget() { - final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM); + if (mIsImWindow) { + // IME windows can't be IME targets. IME targets are required to be below the IME + // windows and that wouldn't be possible if the IME window is its own target...silly. + return false; + } + + 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/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java index 3f47d5cfc2d3..69bfc8fa471b 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java @@ -16,23 +16,18 @@ package com.android.server.wm; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import android.content.Context; -import android.os.Binder; import android.platform.test.annotations.Presubmit; -import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import android.view.IWindow; -import android.view.WindowManager; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; +import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -41,30 +36,19 @@ import static org.junit.Assert.assertTrue; /** * Tests for the {@link WindowState} class. * - * runtest frameworks-services -c com.android.server.wm.WindowStateTests + * Build/Install/Run: + * bit FrameworksServicesTests:com.android.server.wm.WindowStateTests */ @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) public class WindowStateTests extends WindowTestsBase { - private WindowToken mWindowToken; - - @Before - public void setUp() throws Exception { - super.setUp(); - mWindowToken = new WindowToken(sWm, new Binder(), 0, false, - sWm.getDefaultDisplayContentLocked()); - } - @Test public void testIsParentWindowHidden() throws Exception { - final WindowState parentWindow = - createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow"); - final WindowState child1 = - createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1"); - final WindowState child2 = - createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2"); + final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow"); + final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1"); + final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2"); assertFalse(parentWindow.mHidden); assertFalse(parentWindow.isParentWindowHidden()); @@ -79,14 +63,10 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testIsChildWindow() throws Exception { - final WindowState parentWindow = - createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow"); - final WindowState child1 = - createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1"); - final WindowState child2 = - createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2"); - final WindowState randomWindow = - createWindow(null, TYPE_APPLICATION, mWindowToken, "randomWindow"); + final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow"); + final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1"); + final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2"); + final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow"); assertFalse(parentWindow.isChildWindow()); assertTrue(child1.isChildWindow()); @@ -96,13 +76,12 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testHasChild() throws Exception { - final WindowState win1 = createWindow(null, TYPE_APPLICATION, mWindowToken, "win1"); - final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, mWindowToken, "win11"); - final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, mWindowToken, "win12"); - final WindowState win2 = createWindow(null, TYPE_APPLICATION, mWindowToken, "win2"); - final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, mWindowToken, "win21"); - final WindowState randomWindow = - createWindow(null, TYPE_APPLICATION, mWindowToken, "randomWindow"); + final WindowState win1 = createWindow(null, TYPE_APPLICATION, "win1"); + final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, "win11"); + final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, "win12"); + final WindowState win2 = createWindow(null, TYPE_APPLICATION, "win2"); + final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, "win21"); + final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow"); assertTrue(win1.hasChild(win11)); assertTrue(win1.hasChild(win12)); @@ -118,12 +97,9 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testGetParentWindow() throws Exception { - final WindowState parentWindow = - createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow"); - final WindowState child1 = - createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1"); - final WindowState child2 = - createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2"); + final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow"); + final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1"); + final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2"); assertNull(parentWindow.getParentWindow()); assertEquals(parentWindow, child1.getParentWindow()); @@ -132,9 +108,9 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testGetTopParentWindow() throws Exception { - final WindowState root = createWindow(null, TYPE_APPLICATION, mWindowToken, "root"); - final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, mWindowToken, "child1"); - final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, mWindowToken, "child2"); + final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); + final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1"); + final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2"); assertEquals(root, root.getTopParentWindow()); assertEquals(root, child1.getTopParentWindow()); @@ -144,10 +120,46 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testIsOnScreen_hiddenByPolicy() { - final WindowState window = createWindow(null, TYPE_APPLICATION, mWindowToken, "window"); + final WindowState window = createWindow(null, TYPE_APPLICATION, "window"); window.setHasSurface(true); assertTrue(window.isOnScreen()); window.hideLw(false /* doAnimation */); assertFalse(window.isOnScreen()); } + + @Test + public void testCanBeImeTarget() throws Exception { + 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. + appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + + // Make windows visible + appWindow.setHasSurface(true); + imeWindow.setHasSurface(true); + + // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets + assertFalse(appWindow.canBeImeTarget()); + assertFalse(imeWindow.canBeImeTarget()); + + // Add IME target flags + 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()); + assertFalse(imeWindow.canBeImeTarget()); + + // Make windows invisible + appWindow.hideLw(false /* doAnimation */); + imeWindow.hideLw(false /* doAnimation */); + + // Invisible window can't be IME targets even if they have the right flags. + assertFalse(appWindow.canBeImeTarget()); + assertFalse(imeWindow.canBeImeTarget()); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java index 3a69537ba72e..ab6968b6c149 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java @@ -113,6 +113,12 @@ public class WindowTestsBase { return token; } + WindowState createWindow(WindowState parent, int type, String name) { + return (parent == null) + ? createWindow(parent, type, sDisplayContent, name) + : createWindow(parent, type, parent.mToken, name); + } + WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) { final WindowToken token = createWindowToken(dc, type); return createWindow(parent, type, token, name); |