summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/WindowLayersController.java47
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java34
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java62
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java149
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java79
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java90
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java89
9 files changed, 339 insertions, 230 deletions
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index c06e5cc6d7ad..32373f901be3 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -23,6 +23,7 @@ import java.util.ArrayDeque;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -63,17 +64,19 @@ class WindowLayersController {
private int mCurBaseLayer;
private int mCurLayer;
private boolean mAnyLayerChanged;
+ private int mHighestLayerInImeTargetBaseLayer;
+ private WindowState mImeTarget;
final void assignWindowLayers(DisplayContent dc) {
if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based",
new RuntimeException("here").fillInStackTrace());
- clear();
+ reset();
dc.forAllWindows((w) -> {
boolean layerChanged = false;
int oldLayer = w.mLayer;
- if (w.mBaseLayer == mCurBaseLayer || w.mIsImWindow) {
+ if (w.mBaseLayer == mCurBaseLayer) {
mCurLayer += WINDOW_LAYER_MULTIPLIER;
} else {
mCurBaseLayer = mCurLayer = w.mBaseLayer;
@@ -92,6 +95,11 @@ class WindowLayersController {
mHighestApplicationLayer = Math.max(mHighestApplicationLayer,
w.mWinAnimator.mAnimLayer);
}
+ if (mImeTarget != null && w.mBaseLayer == mImeTarget.mBaseLayer) {
+ mHighestLayerInImeTargetBaseLayer = Math.max(mHighestLayerInImeTargetBaseLayer,
+ w.mWinAnimator.mAnimLayer);
+ }
+
collectSpecialWindows(w);
if (layerChanged) {
@@ -103,7 +111,7 @@ class WindowLayersController {
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && mAnyLayerChanged
- && dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
+ && dc.getDisplayId() == DEFAULT_DISPLAY) {
mService.mAccessibilityController.onWindowLayersChangedLocked();
}
@@ -120,7 +128,7 @@ class WindowLayersController {
}, false /* traverseTopToBottom */);
}
- private void clear() {
+ private void reset() {
mHighestApplicationLayer = 0;
mPinnedWindows.clear();
mInputMethodWindows.clear();
@@ -132,6 +140,9 @@ class WindowLayersController {
mCurBaseLayer = 0;
mCurLayer = 0;
mAnyLayerChanged = false;
+
+ mImeTarget = mService.mInputMethodTarget;
+ mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
}
private void collectSpecialWindows(WindowState w) {
@@ -174,22 +185,10 @@ class WindowLayersController {
layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
- boolean onTopLauncherVisible = !mOnTopLauncherWindows.isEmpty();
while (!mOnTopLauncherWindows.isEmpty()) {
layer = assignAndIncreaseLayerIfNeeded(mOnTopLauncherWindows.remove(), layer);
}
- // Make sure IME windows are showing above the dock divider and on-top launcher windows.
- if ((mDockDivider != null && mDockDivider.isVisibleLw()) || onTopLauncherVisible) {
- while (!mInputMethodWindows.isEmpty()) {
- final WindowState w = mInputMethodWindows.remove();
- // Only ever move IME windows up, else we brake IME for windows above the divider.
- if (layer > w.mLayer) {
- layer = assignAndIncreaseLayerIfNeeded(w, layer);
- }
- }
- }
-
// We know that we will be animating a relaunching window in the near future, which will
// receive a z-order increase. We want the replaced window to immediately receive the same
// treatment, e.g. to be above the dock divider.
@@ -200,12 +199,26 @@ class WindowLayersController {
while (!mPinnedWindows.isEmpty()) {
layer = assignAndIncreaseLayerIfNeeded(mPinnedWindows.remove(), layer);
}
+
+ // Make sure IME is the highest window in the base layer of it's target.
+ if (mImeTarget != null) {
+ if (mImeTarget.mAppToken == null) {
+ // For non-app ime targets adjust the layer we start from to match what we found
+ // when assigning layers. Otherwise, just use the highest app layer we have some far.
+ layer = mHighestLayerInImeTargetBaseLayer + WINDOW_LAYER_MULTIPLIER;
+ }
+
+ while (!mInputMethodWindows.isEmpty()) {
+ layer = assignAndIncreaseLayerIfNeeded(mInputMethodWindows.remove(), layer);
+ }
+ }
+
}
private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) {
if (win != null) {
assignAnimLayer(win, layer);
- // Make sure we leave space inbetween normal windows for dims and such.
+ // Make sure we leave space in-between normal windows for dims and such.
layer += WINDOW_LAYER_MULTIPLIER;
}
return layer;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c11003dd972b..661df9cd60ad 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1905,9 +1905,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
int getAnimLayerAdjustment() {
- final boolean isImeType =
- mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
- if (isImeType && mService.mInputMethodTarget != null) {
+ if (mIsImWindow && mService.mInputMethodTarget != null) {
final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken;
if (appToken != null) {
return appToken.mAppAnimator.animLayerAdjustment;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 402bcfb863f0..a2eebc336970 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -176,21 +176,6 @@ class WindowToken extends WindowContainer<WindowState> {
}
/**
- * Recursive search through a WindowList and all of its windows' children.
- * @param target The window to search for.
- * @return The index of win in windows or of the window that is an ancestor of win.
- */
- int getWindowIndex(WindowState target) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowState w = mChildren.get(i);
- if (w == target || w.hasChild(target)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
* Returns true if the new window is considered greater than the existing window in terms of
* z-order.
*/
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 772b2a2c4737..207939fc9dd9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -45,16 +45,7 @@ import static org.junit.Assert.assertTrue;
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class AppWindowTokenTests {
-
- private static WindowManagerService sWm = null;
- private final IWindow mIWindow = new TestIWindow();
-
- @Before
- public void setUp() throws Exception {
- final Context context = InstrumentationRegistry.getTargetContext();
- sWm = TestWindowManagerPolicy.getWindowManagerService(context);
- }
+public class AppWindowTokenTests extends WindowTestsBase {
@Test
public void testAddWindow_Order() throws Exception {
@@ -62,10 +53,11 @@ public class AppWindowTokenTests {
assertEquals(0, token.getWindowsCount());
- final WindowState win1 = createWindow(null, TYPE_APPLICATION, token);
- final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token);
- final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token);
- final WindowState win4 = createWindow(null, TYPE_APPLICATION, token);
+ final WindowState win1 = createWindow(null, TYPE_APPLICATION, token, "win1");
+ final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token,
+ "startingWin");
+ final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token, "baseWin");
+ final WindowState win4 = createWindow(null, TYPE_APPLICATION, token, "win4");
token.addWindow(win1);
token.addWindow(startingWin);
@@ -92,24 +84,18 @@ public class AppWindowTokenTests {
assertNull(token.findMainWindow());
- final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token);
- final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
+ final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token, "window1");
+ final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+ final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
token.addWindow(window1);
assertEquals(window1, token.findMainWindow());
window1.mAnimatingExit = true;
assertEquals(window1, token.findMainWindow());
- final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token);
+ final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token, "window2");
token.addWindow(window2);
assertEquals(window2, token.findMainWindow());
}
- private WindowState createWindow(WindowState parent, int type, WindowToken token) {
- final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
- return new WindowState(sWm, null, mIWindow, token, parent, 0, 0, attrs, 0, 0);
- }
-
/* Used so we can gain access to some protected members of the {@link AppWindowToken} class */
private class TestAppWindowToken extends AppWindowToken {
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 225dc5d2d66a..0801a883177d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,28 +16,15 @@
package com.android.server.wm;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.IBinder;
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.Display;
-import android.view.IWindow;
-import android.view.WindowManager;
import java.util.ArrayList;
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.AppOpsManager.OP_NONE;
-import static android.content.res.Configuration.EMPTY;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -47,7 +34,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
/**
* Tests for the {@link DisplayContent} class.
@@ -58,21 +44,7 @@ import static org.mockito.Mockito.mock;
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class DisplayContentTests {
-
- private static WindowManagerService sWm = null;
- private final IWindow mIWindow = new TestIWindow();
- private final Session mMockSession = mock(Session.class);
- private Display mDisplay;
- private int mNextStackId = FIRST_DYNAMIC_STACK_ID;
- private int mNextTaskId = 0;
-
- @Before
- public void setUp() throws Exception {
- final Context context = InstrumentationRegistry.getTargetContext();
- sWm = TestWindowManagerPolicy.getWindowManagerService(context);
- mDisplay = context.getDisplay();
- }
+public class DisplayContentTests extends WindowTestsBase {
@Test
public void testForAllWindows() throws Exception {
@@ -124,36 +96,4 @@ public class DisplayContentTests {
assertEquals(imeWindow, windows.get(1));
assertEquals(imeDialogWindow, windows.get(0));
}
-
- private WindowToken createWindowToken(DisplayContent dc, int type) {
- if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
- return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
- }
-
- final int stackId = mNextStackId++;
- dc.addStackToDisplay(stackId, true);
- final TaskStack stack = sWm.mStackIdToStack.get(stackId);
- final Task task = new Task(mNextTaskId++, stack, 0, sWm, null, EMPTY, false);
- stack.addTask(task, true);
- final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
- task.addAppToken(0, token, 0, false);
- return token;
- }
-
- private WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
- final WindowToken token = createWindowToken(dc, type);
- return createWindow(parent, type, token, name);
- }
-
- private WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
- final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
- attrs.setTitle(name);
-
- final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
- 0, attrs, 0, 0);
- // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
- // adding it to the token...
- token.addWindow(w);
- return w;
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
new file mode 100644
index 000000000000..5a035d636443
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+/**
+ * Tests for the {@link WindowLayersController} class.
+ *
+ * Build/Install/Run:
+ * bit FrameworksServicesTests:com.android.server.wm.WindowLayersControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowLayersControllerTests extends WindowTestsBase {
+
+ private static boolean sOneTimeSetupDone = false;
+ private static WindowLayersController sLayersController;
+ private static DisplayContent sDisplayContent;
+ private static WindowState sImeWindow;
+ private static WindowState sImeDialogWindow;
+ private static WindowState sStatusBarWindow;
+ private static WindowState sDockedDividerWindow;
+ private static WindowState sNavBarWindow;
+ private static WindowState sAppWindow;
+ private static WindowState sChildAppWindow;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ if (sOneTimeSetupDone) {
+ return;
+ }
+ sOneTimeSetupDone = true;
+ sLayersController = new WindowLayersController(sWm);
+ sDisplayContent =
+ new DisplayContent(mDisplay, sWm, sLayersController, new WallpaperController(sWm));
+ final WindowState wallpaperWindow =
+ createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow");
+ sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow");
+ sImeDialogWindow =
+ createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
+ sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
+ sNavBarWindow =
+ createWindow(null, TYPE_NAVIGATION_BAR, sStatusBarWindow.mToken, "sNavBarWindow");
+ sDockedDividerWindow =
+ createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
+ sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
+ sChildAppWindow = createWindow(sAppWindow,
+ TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindow");
+ }
+
+ @Test
+ public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
+ sWm.mInputMethodTarget = null;
+ sLayersController.assignWindowLayers(sDisplayContent);
+
+ // The Ime has an higher base layer than app windows and lower base layer than system
+ // windows, so it should be above app windows and below system windows if there isn't an IME
+ // target.
+ assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+ assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+ assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+
+ // And, IME dialogs should always have an higher layer than the IME.
+ assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+ }
+
+ @Test
+ public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
+ final WindowState imeAppTarget =
+ createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+ sWm.mInputMethodTarget = imeAppTarget;
+ sLayersController.assignWindowLayers(sDisplayContent);
+
+ // Ime should be above all app windows and below system windows if it is targeting an app
+ // window.
+ assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
+ assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+ assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+ assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+
+ // And, IME dialogs should always have an higher layer than the IME.
+ assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+ }
+
+ @Test
+ public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
+ final WindowState imeSystemOverlayTarget =
+ createWindow(null, TYPE_SYSTEM_OVERLAY, sDisplayContent, "imeSystemOverlayTarget");
+
+ sWm.mInputMethodTarget = imeSystemOverlayTarget;
+ sLayersController.assignWindowLayers(sDisplayContent);
+
+ // The IME target base layer is higher than all window except for the nav bar window, so the
+ // IME should be above all windows except for the nav bar.
+ assertWindowLayerGreaterThan(sImeWindow, imeSystemOverlayTarget);
+ assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+ assertWindowLayerGreaterThan(sImeWindow, sStatusBarWindow);
+ assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+
+ // And, IME dialogs should always have an higher layer than the IME.
+ assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+ }
+
+ private void assertWindowLayerGreaterThan(WindowState first, WindowState second)
+ throws Exception {
+ assertGreaterThan(first.mWinAnimator.mAnimLayer, second.mWinAnimator.mAnimLayer);
+ }
+
+}
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 4499275e8f46..50e5a2220ee3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -46,25 +46,25 @@ import static org.junit.Assert.assertTrue;
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class WindowStateTests {
+public class WindowStateTests extends WindowTestsBase {
- private static WindowManagerService sWm = null;
private WindowToken mWindowToken;
- private final IWindow mIWindow = new TestIWindow();
@Before
public void setUp() throws Exception {
- final Context context = InstrumentationRegistry.getTargetContext();
- sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+ 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);
- final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
- final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
+ 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");
assertFalse(parentWindow.mHidden);
assertFalse(parentWindow.isParentWindowHidden());
@@ -79,10 +79,14 @@ public class WindowStateTests {
@Test
public void testIsChildWindow() throws Exception {
- final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
- final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
- final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
- final WindowState randomWindow = createWindow(null, TYPE_APPLICATION);
+ 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");
assertFalse(parentWindow.isChildWindow());
assertTrue(child1.isChildWindow());
@@ -92,12 +96,13 @@ public class WindowStateTests {
@Test
public void testHasChild() throws Exception {
- final WindowState win1 = createWindow(null, TYPE_APPLICATION);
- final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW);
- final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW);
- final WindowState win2 = createWindow(null, TYPE_APPLICATION);
- final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW);
- final WindowState randomWindow = createWindow(null, TYPE_APPLICATION);
+ 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");
assertTrue(win1.hasChild(win11));
assertTrue(win1.hasChild(win12));
@@ -113,23 +118,28 @@ public class WindowStateTests {
@Test
public void testGetBottomChild() throws Exception {
- final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
+ final WindowState parentWindow =
+ createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
assertNull(parentWindow.getBottomChild());
- final WindowState child1 = createWindow(parentWindow, TYPE_APPLICATION_PANEL);
+ final WindowState child1 =
+ createWindow(parentWindow, TYPE_APPLICATION_PANEL, mWindowToken, "child1");
assertEquals(child1, parentWindow.getBottomChild());
- final WindowState child2 = createWindow(parentWindow, TYPE_APPLICATION_PANEL);
+ final WindowState child2 =
+ createWindow(parentWindow, TYPE_APPLICATION_PANEL, mWindowToken, "child2");
// Since child1 and child2 are at the same layer, then child2 is expect to be added on top
// on child1
assertEquals(child1, parentWindow.getBottomChild());
- final WindowState child3 = createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY);
+ final WindowState child3 =
+ createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY, mWindowToken, "child3");
// Since child3 is a negative layer, we would expect it to be added below current children
// with positive layers.
assertEquals(child3, parentWindow.getBottomChild());
- final WindowState child4 = createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY);
+ final WindowState child4 =
+ createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY, mWindowToken, "child4");
// We would also expect additional negative layers to be added below existing negative
// layers.
assertEquals(child4, parentWindow.getBottomChild());
@@ -137,9 +147,12 @@ public class WindowStateTests {
@Test
public void testGetParentWindow() throws Exception {
- final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
- final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
- final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
+ 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");
assertNull(parentWindow.getParentWindow());
assertEquals(parentWindow, child1.getParentWindow());
@@ -148,9 +161,9 @@ public class WindowStateTests {
@Test
public void testGetTopParentWindow() throws Exception {
- final WindowState root = createWindow(null, TYPE_APPLICATION);
- final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW);
- final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW);
+ 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");
assertEquals(root, root.getTopParentWindow());
assertEquals(root, child1.getTopParentWindow());
@@ -160,16 +173,10 @@ public class WindowStateTests {
@Test
public void testIsOnScreen_hiddenByPolicy() {
- final WindowState window = createWindow(null, TYPE_APPLICATION);
+ final WindowState window = createWindow(null, TYPE_APPLICATION, mWindowToken, "window");
window.setHasSurface(true);
assertTrue(window.isOnScreen());
window.hideLw(false /* doAnimation */);
assertFalse(window.isOnScreen());
}
-
- private WindowState createWindow(WindowState parent, int type) {
- final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
- return new WindowState(sWm, null, mIWindow, mWindowToken, parent, 0, 0, attrs, 0, 0);
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
new file mode 100644
index 000000000000..9681bd2f5947
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Assert;
+import org.junit.Before;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.support.test.InstrumentationRegistry;
+import android.view.Display;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
+import static android.app.AppOpsManager.OP_NONE;
+import static android.content.res.Configuration.EMPTY;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Common base class for window manager unit test classes.
+ */
+public class WindowTestsBase {
+ static WindowManagerService sWm = null;
+ private final IWindow mIWindow = new TestIWindow();
+ private final Session mMockSession = mock(Session.class);
+ Display mDisplay;
+ private static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
+ private static int sNextTaskId = 0;
+
+ @Before
+ public void setUp() throws Exception {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+ mDisplay = context.getDisplay();
+ }
+
+ /** Asserts that the first entry is greater than the second entry. */
+ void assertGreaterThan(int first, int second) throws Exception {
+ Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
+ }
+
+ WindowToken createWindowToken(DisplayContent dc, int type) {
+ if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
+ return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
+ }
+
+ final int stackId = sNextStackId++;
+ dc.addStackToDisplay(stackId, true);
+ final TaskStack stack = sWm.mStackIdToStack.get(stackId);
+ final Task task = new Task(sNextTaskId++, stack, 0, sWm, null, EMPTY, false);
+ stack.addTask(task, true);
+ final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
+ task.addAppToken(0, token, 0, false);
+ return token;
+ }
+
+ WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
+ final WindowToken token = createWindowToken(dc, type);
+ return createWindow(parent, type, token, name);
+ }
+
+ WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
+ final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
+ attrs.setTitle(name);
+
+ final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
+ 0, attrs, 0, 0);
+ // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
+ // adding it to the token...
+ token.addWindow(w);
+ return w;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index d12d672ab5cc..d6bfa177e440 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -47,17 +47,7 @@ import static org.mockito.Mockito.mock;
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class WindowTokenTests {
-
- private WindowManagerService mWm = null;
- private final IWindow mIWindow = new TestIWindow();
- private final Session mMockSession = mock(Session.class);
-
- @Before
- public void setUp() throws Exception {
- final Context context = InstrumentationRegistry.getTargetContext();
- mWm = TestWindowManagerPolicy.getWindowManagerService(context);
- }
+public class WindowTokenTests extends WindowTestsBase {
@Test
public void testAddWindow() throws Exception {
@@ -65,11 +55,11 @@ public class WindowTokenTests {
assertEquals(0, token.getWindowsCount());
- final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
- final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
- final WindowState window3 = createWindow(null, TYPE_APPLICATION, token);
+ final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+ final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+ final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+ final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+ final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
token.addWindow(window1);
// NOTE: Child windows will not be added to the token as window containers can only
@@ -91,12 +81,12 @@ public class WindowTokenTests {
@Test
public void testChildRemoval() throws Exception {
final TestWindowToken token = new TestWindowToken();
- final DisplayContent dc = mWm.getDefaultDisplayContentLocked();
+ final DisplayContent dc = sWm.getDefaultDisplayContentLocked();
assertEquals(token, dc.getWindowToken(token.token));
- final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
- final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
+ final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+ final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
token.addWindow(window1);
token.addWindow(window2);
@@ -113,11 +103,11 @@ public class WindowTokenTests {
@Test
public void testAdjustAnimLayer() throws Exception {
final TestWindowToken token = new TestWindowToken();
- final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
- final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
- final WindowState window3 = createWindow(null, TYPE_APPLICATION, token);
+ final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+ final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+ final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+ final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+ final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
token.addWindow(window1);
token.addWindow(window2);
@@ -136,60 +126,11 @@ public class WindowTokenTests {
assertEquals(window3StartLayer + adj, highestLayer);
}
- @Test
- public void testGetTopWindow() throws Exception {
- final TestWindowToken token = new TestWindowToken();
-
- assertNull(token.getTopWindow());
-
- final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
- token.addWindow(window1);
- assertEquals(window1, token.getTopWindow());
- final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
- assertEquals(window12, token.getTopWindow());
-
- final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
- token.addWindow(window2);
- // Since new windows are added to the bottom of the token, we would still expect the
- // previous one to the top.
- assertEquals(window12, token.getTopWindow());
- }
-
- @Test
- public void testGetWindowIndex() throws Exception {
- final TestWindowToken token = new TestWindowToken();
-
- final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
- assertEquals(-1, token.getWindowIndex(window1));
- token.addWindow(window1);
- assertEquals(0, token.getWindowIndex(window1));
- final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
- final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
- // Child windows should report the same index as their parents.
- assertEquals(0, token.getWindowIndex(window11));
- assertEquals(0, token.getWindowIndex(window12));
-
- final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
- assertEquals(-1, token.getWindowIndex(window2));
- token.addWindow(window2);
- // Since new windows are added to the bottom of the token, we would expect the added window
- // to be at index 0.
- assertEquals(0, token.getWindowIndex(window2));
- assertEquals(1, token.getWindowIndex(window1));
- }
-
- private WindowState createWindow(WindowState parent, int type, WindowToken token) {
- final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
- return new WindowState(mWm, mMockSession, mIWindow, token, parent, OP_NONE, 0, attrs, 0, 0);
- }
-
/* Used so we can gain access to some protected members of the {@link WindowToken} class */
private class TestWindowToken extends WindowToken {
TestWindowToken() {
- super(mWm, mock(IBinder.class), 0, false, mWm.getDefaultDisplayContentLocked());
+ super(sWm, mock(IBinder.class), 0, false, sWm.getDefaultDisplayContentLocked());
}
int getWindowsCount() {