Loading services/core/java/com/android/server/wm/WindowState.java +40 −7 Original line number Diff line number Diff line Loading @@ -3889,7 +3889,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } private boolean forAllWindowBottomToTop(ToBooleanFunction<WindowState> callback) { // We want to consumer the negative sublayer children first because they need to appear // We want to consume the negative sublayer children first because they need to appear // below the parent, then this window (the parent), and then the positive sublayer children // because they need to appear above the parent. int i = 0; Loading @@ -3897,7 +3897,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP WindowState child = mChildren.get(i); while (i < count && child.mSubLayer < 0) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, false /* traverseTopToBottom */)) { return true; } i++; Loading @@ -3912,7 +3912,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } while (i < count) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, false /* traverseTopToBottom */)) { return true; } i++; Loading @@ -3926,14 +3926,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } private boolean forAllWindowTopToBottom(ToBooleanFunction<WindowState> callback) { // We want to consumer the positive sublayer children first because they need to appear // We want to consume the positive sublayer children first because they need to appear // above the parent, then this window (the parent), and then the negative sublayer children // because they need to appear above the parent. int i = mChildren.size() - 1; WindowState child = mChildren.get(i); while (i >= 0 && child.mSubLayer >= 0) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, true /* traverseTopToBottom */)) { return true; } --i; Loading @@ -3948,7 +3948,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } while (i >= 0) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, true /* traverseTopToBottom */)) { return true; } --i; Loading Loading @@ -3991,10 +3991,43 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } WindowState getWindow(Predicate<WindowState> callback) { if (mChildren.isEmpty()) { return callback.test(this) ? this : null; } // We want to consume the positive sublayer children first because they need to appear // above the parent, then this window (the parent), and then the negative sublayer children // because they need to appear above the parent. int i = mChildren.size() - 1; WindowState child = mChildren.get(i); while (i >= 0 && child.mSubLayer >= 0) { if (callback.test(child)) { return child; } --i; if (i < 0) { break; } child = mChildren.get(i); } if (callback.test(this)) { return this; } return super.getWindow(callback); while (i >= 0) { if (callback.test(child)) { return child; } --i; if (i < 0) { break; } child = mChildren.get(i); } return null; } boolean isWindowAnimationSet() { Loading services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +106 −138 Original line number Diff line number Diff line Loading @@ -16,24 +16,25 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 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_VOICE_INTERACTION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; import android.content.res.Configuration; import android.hardware.display.DisplayManagerGlobal; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.Display; import android.view.DisplayInfo; import java.util.ArrayList; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * Tests for the {@link DisplayContent} class. Loading @@ -54,38 +55,17 @@ public class DisplayContentTests extends WindowTestsBase { exitingAppToken.mIsExiting = true; exitingAppToken.mTask.mStack.mExitingAppTokens.add(exitingAppToken); final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(exitingAppWindow, windows.get(1)); assertEquals(sChildAppWindowBelow, windows.get(2)); assertEquals(sAppWindow, windows.get(3)); assertEquals(sChildAppWindowAbove, windows.get(4)); assertEquals(sDockedDividerWindow, windows.get(5)); assertEquals(sStatusBarWindow, windows.get(6)); assertEquals(sNavBarWindow, windows.get(7)); assertEquals(sImeWindow, windows.get(8)); assertEquals(sImeDialogWindow, windows.get(9)); // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(9)); assertEquals(exitingAppWindow, windows.get(8)); assertEquals(sChildAppWindowBelow, windows.get(7)); assertEquals(sAppWindow, windows.get(6)); assertEquals(sChildAppWindowAbove, windows.get(5)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(3)); assertEquals(sNavBarWindow, windows.get(2)); assertEquals(sImeWindow, windows.get(1)); assertEquals(sImeDialogWindow, windows.get(0)); exitingAppWindow.removeImmediately(); assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, exitingAppWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sDockedDividerWindow, sStatusBarWindow, sNavBarWindow, sImeWindow, sImeDialogWindow)); } @Test Loading @@ -95,78 +75,49 @@ public class DisplayContentTests extends WindowTestsBase { sWm.mInputMethodTarget = imeAppTarget; final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(sChildAppWindowBelow, windows.get(1)); assertEquals(sAppWindow, windows.get(2)); assertEquals(sChildAppWindowAbove, windows.get(3)); assertEquals(imeAppTarget, windows.get(4)); assertEquals(sImeWindow, windows.get(5)); assertEquals(sImeDialogWindow, windows.get(6)); assertEquals(sDockedDividerWindow, windows.get(7)); assertEquals(sStatusBarWindow, windows.get(8)); assertEquals(sNavBarWindow, windows.get(9)); assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, imeAppTarget, sImeWindow, sImeDialogWindow, sDockedDividerWindow, sStatusBarWindow, sNavBarWindow)); } // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(9)); assertEquals(sChildAppWindowBelow, windows.get(8)); assertEquals(sAppWindow, windows.get(7)); assertEquals(sChildAppWindowAbove, windows.get(6)); assertEquals(imeAppTarget, windows.get(5)); assertEquals(sImeWindow, windows.get(4)); assertEquals(sImeDialogWindow, windows.get(3)); assertEquals(sDockedDividerWindow, windows.get(2)); assertEquals(sStatusBarWindow, windows.get(1)); assertEquals(sNavBarWindow, windows.get(0)); // Clean-up sWm.mInputMethodTarget = null; imeAppTarget.removeImmediately(); @Test public void testForAllWindows_WithChildWindowImeTarget() throws Exception { sWm.mInputMethodTarget = sChildAppWindowAbove; assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sImeWindow, sImeDialogWindow, sDockedDividerWindow, sStatusBarWindow, sNavBarWindow)); } @Test public void testForAllWindows_WithStatusBarImeTarget() throws Exception { sWm.mInputMethodTarget = sStatusBarWindow; final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(sChildAppWindowBelow, windows.get(1)); assertEquals(sAppWindow, windows.get(2)); assertEquals(sChildAppWindowAbove, windows.get(3)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(5)); assertEquals(sImeWindow, windows.get(6)); assertEquals(sImeDialogWindow, windows.get(7)); assertEquals(sNavBarWindow, windows.get(8)); // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(8)); assertEquals(sChildAppWindowBelow, windows.get(7)); assertEquals(sAppWindow, windows.get(6)); assertEquals(sChildAppWindowAbove, windows.get(5)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(3)); assertEquals(sImeWindow, windows.get(2)); assertEquals(sImeDialogWindow, windows.get(1)); assertEquals(sNavBarWindow, windows.get(0)); // Clean-up sWm.mInputMethodTarget = null; assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sDockedDividerWindow, sStatusBarWindow, sImeWindow, sImeDialogWindow, sNavBarWindow)); } @Test Loading @@ -176,38 +127,35 @@ public class DisplayContentTests extends WindowTestsBase { final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION, sDisplayContent, "voiceInteractionWindow"); final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(sChildAppWindowBelow, windows.get(1)); assertEquals(sAppWindow, windows.get(2)); assertEquals(sChildAppWindowAbove, windows.get(3)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(voiceInteractionWindow, windows.get(5)); assertEquals(sStatusBarWindow, windows.get(6)); assertEquals(sNavBarWindow, windows.get(7)); assertEquals(sImeWindow, windows.get(8)); assertEquals(sImeDialogWindow, windows.get(9)); assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sDockedDividerWindow, voiceInteractionWindow, sStatusBarWindow, sNavBarWindow, sImeWindow, sImeDialogWindow)); } // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(9)); assertEquals(sChildAppWindowBelow, windows.get(8)); assertEquals(sAppWindow, windows.get(7)); assertEquals(sChildAppWindowAbove, windows.get(6)); assertEquals(sDockedDividerWindow, windows.get(5)); assertEquals(voiceInteractionWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(3)); assertEquals(sNavBarWindow, windows.get(2)); assertEquals(sImeWindow, windows.get(1)); assertEquals(sImeDialogWindow, windows.get(0)); voiceInteractionWindow.removeImmediately(); @Test public void testComputeImeTarget() throws Exception { // Verify that an app window can be an ime target. final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin"); appWin.setHasSurface(true); assertTrue(appWin.canBeImeTarget()); WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); assertEquals(appWin, imeTarget); // Verify that an child window can be an ime target. final WindowState childWin = createWindow(appWin, TYPE_APPLICATION_ATTACHED_DIALOG, "childWin"); childWin.setHasSurface(true); assertTrue(childWin.canBeImeTarget()); imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); assertEquals(childWin, imeTarget); } /** Loading Loading @@ -284,4 +232,24 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi); assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); } private void assertForAllWindowsOrder(List<WindowState> expectedWindows) { final LinkedList<WindowState> actualWindows = new LinkedList(); // Test forward traversal. sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */); assertEquals(expectedWindows.size(), actualWindows.size()); for (WindowState w : expectedWindows) { assertEquals(w, actualWindows.pollFirst()); } assertTrue(actualWindows.isEmpty()); // Test backward traversal. sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */); assertEquals(expectedWindows.size(), actualWindows.size()); for (WindowState w : expectedWindows) { assertEquals(w, actualWindows.pollLast()); } assertTrue(actualWindows.isEmpty()); } } services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +37 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,17 @@ import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import java.util.LinkedList; 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_ABOVE_SUB_PANEL; 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_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -167,4 +174,34 @@ public class WindowStateTests extends WindowTestsBase { assertFalse(appWindow.canBeImeTarget()); assertFalse(imeWindow.canBeImeTarget()); } @Test public void testGetWindow() throws Exception { final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild"); final WindowState mediaOverlayChild = createWindow(root, TYPE_APPLICATION_MEDIA_OVERLAY, "mediaOverlayChild"); final WindowState attachedDialogChild = createWindow(root, TYPE_APPLICATION_ATTACHED_DIALOG, "attachedDialogChild"); final WindowState subPanelChild = createWindow(root, TYPE_APPLICATION_SUB_PANEL, "subPanelChild"); final WindowState aboveSubPanelChild = createWindow(root, TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild"); final LinkedList<WindowState> windows = new LinkedList(); root.getWindow(w -> { windows.addLast(w); return false; }); // getWindow should have returned candidate windows in z-order. assertEquals(aboveSubPanelChild, windows.pollFirst()); assertEquals(subPanelChild, windows.pollFirst()); assertEquals(attachedDialogChild, windows.pollFirst()); assertEquals(root, windows.pollFirst()); assertEquals(mediaOverlayChild, windows.pollFirst()); assertEquals(mediaChild, windows.pollFirst()); assertTrue(windows.isEmpty()); } } services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +13 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.EMPTY; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 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_OVERLAY; Loading @@ -60,6 +61,7 @@ import static org.mockito.Mockito.mock; import com.android.server.AttributeCache; import java.util.HashSet; import java.util.LinkedList; /** * Common base class for window manager unit test classes. Loading Loading @@ -120,6 +122,7 @@ class WindowTestsBase { sCommonWindows = new HashSet(); sWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow"); sImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "sImeWindow"); sWm.mInputMethodWindow = sImeWindow; sImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG, "sImeDialogWindow"); sStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "sStatusBarWindow"); sNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "sNavBarWindow"); Loading @@ -133,16 +136,25 @@ class WindowTestsBase { @After public void tearDown() throws Exception { final LinkedList<WindowState> nonCommonWindows = new LinkedList(); sWm.mRoot.forAllWindows(w -> { if (!sCommonWindows.contains(w)) { w.removeImmediately(); nonCommonWindows.addLast(w); } }, true /* traverseTopToBottom */); while (!nonCommonWindows.isEmpty()) { nonCommonWindows.pollLast().removeImmediately(); } sWm.mInputMethodTarget = null; } private static WindowState createCommonWindow(WindowState parent, int type, String name) { final WindowState win = createWindow(parent, type, name); sCommonWindows.add(win); // Prevent common windows from been IMe targets win.mAttrs.flags |= FLAG_NOT_FOCUSABLE; return win; } Loading Loading
services/core/java/com/android/server/wm/WindowState.java +40 −7 Original line number Diff line number Diff line Loading @@ -3889,7 +3889,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } private boolean forAllWindowBottomToTop(ToBooleanFunction<WindowState> callback) { // We want to consumer the negative sublayer children first because they need to appear // We want to consume the negative sublayer children first because they need to appear // below the parent, then this window (the parent), and then the positive sublayer children // because they need to appear above the parent. int i = 0; Loading @@ -3897,7 +3897,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP WindowState child = mChildren.get(i); while (i < count && child.mSubLayer < 0) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, false /* traverseTopToBottom */)) { return true; } i++; Loading @@ -3912,7 +3912,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } while (i < count) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, false /* traverseTopToBottom */)) { return true; } i++; Loading @@ -3926,14 +3926,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } private boolean forAllWindowTopToBottom(ToBooleanFunction<WindowState> callback) { // We want to consumer the positive sublayer children first because they need to appear // We want to consume the positive sublayer children first because they need to appear // above the parent, then this window (the parent), and then the negative sublayer children // because they need to appear above the parent. int i = mChildren.size() - 1; WindowState child = mChildren.get(i); while (i >= 0 && child.mSubLayer >= 0) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, true /* traverseTopToBottom */)) { return true; } --i; Loading @@ -3948,7 +3948,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } while (i >= 0) { if (callback.apply(child)) { if (child.applyInOrderWithImeWindows(callback, true /* traverseTopToBottom */)) { return true; } --i; Loading Loading @@ -3991,10 +3991,43 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } WindowState getWindow(Predicate<WindowState> callback) { if (mChildren.isEmpty()) { return callback.test(this) ? this : null; } // We want to consume the positive sublayer children first because they need to appear // above the parent, then this window (the parent), and then the negative sublayer children // because they need to appear above the parent. int i = mChildren.size() - 1; WindowState child = mChildren.get(i); while (i >= 0 && child.mSubLayer >= 0) { if (callback.test(child)) { return child; } --i; if (i < 0) { break; } child = mChildren.get(i); } if (callback.test(this)) { return this; } return super.getWindow(callback); while (i >= 0) { if (callback.test(child)) { return child; } --i; if (i < 0) { break; } child = mChildren.get(i); } return null; } boolean isWindowAnimationSet() { Loading
services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +106 −138 Original line number Diff line number Diff line Loading @@ -16,24 +16,25 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 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_VOICE_INTERACTION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; import android.content.res.Configuration; import android.hardware.display.DisplayManagerGlobal; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.Display; import android.view.DisplayInfo; import java.util.ArrayList; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * Tests for the {@link DisplayContent} class. Loading @@ -54,38 +55,17 @@ public class DisplayContentTests extends WindowTestsBase { exitingAppToken.mIsExiting = true; exitingAppToken.mTask.mStack.mExitingAppTokens.add(exitingAppToken); final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(exitingAppWindow, windows.get(1)); assertEquals(sChildAppWindowBelow, windows.get(2)); assertEquals(sAppWindow, windows.get(3)); assertEquals(sChildAppWindowAbove, windows.get(4)); assertEquals(sDockedDividerWindow, windows.get(5)); assertEquals(sStatusBarWindow, windows.get(6)); assertEquals(sNavBarWindow, windows.get(7)); assertEquals(sImeWindow, windows.get(8)); assertEquals(sImeDialogWindow, windows.get(9)); // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(9)); assertEquals(exitingAppWindow, windows.get(8)); assertEquals(sChildAppWindowBelow, windows.get(7)); assertEquals(sAppWindow, windows.get(6)); assertEquals(sChildAppWindowAbove, windows.get(5)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(3)); assertEquals(sNavBarWindow, windows.get(2)); assertEquals(sImeWindow, windows.get(1)); assertEquals(sImeDialogWindow, windows.get(0)); exitingAppWindow.removeImmediately(); assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, exitingAppWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sDockedDividerWindow, sStatusBarWindow, sNavBarWindow, sImeWindow, sImeDialogWindow)); } @Test Loading @@ -95,78 +75,49 @@ public class DisplayContentTests extends WindowTestsBase { sWm.mInputMethodTarget = imeAppTarget; final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(sChildAppWindowBelow, windows.get(1)); assertEquals(sAppWindow, windows.get(2)); assertEquals(sChildAppWindowAbove, windows.get(3)); assertEquals(imeAppTarget, windows.get(4)); assertEquals(sImeWindow, windows.get(5)); assertEquals(sImeDialogWindow, windows.get(6)); assertEquals(sDockedDividerWindow, windows.get(7)); assertEquals(sStatusBarWindow, windows.get(8)); assertEquals(sNavBarWindow, windows.get(9)); assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, imeAppTarget, sImeWindow, sImeDialogWindow, sDockedDividerWindow, sStatusBarWindow, sNavBarWindow)); } // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(9)); assertEquals(sChildAppWindowBelow, windows.get(8)); assertEquals(sAppWindow, windows.get(7)); assertEquals(sChildAppWindowAbove, windows.get(6)); assertEquals(imeAppTarget, windows.get(5)); assertEquals(sImeWindow, windows.get(4)); assertEquals(sImeDialogWindow, windows.get(3)); assertEquals(sDockedDividerWindow, windows.get(2)); assertEquals(sStatusBarWindow, windows.get(1)); assertEquals(sNavBarWindow, windows.get(0)); // Clean-up sWm.mInputMethodTarget = null; imeAppTarget.removeImmediately(); @Test public void testForAllWindows_WithChildWindowImeTarget() throws Exception { sWm.mInputMethodTarget = sChildAppWindowAbove; assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sImeWindow, sImeDialogWindow, sDockedDividerWindow, sStatusBarWindow, sNavBarWindow)); } @Test public void testForAllWindows_WithStatusBarImeTarget() throws Exception { sWm.mInputMethodTarget = sStatusBarWindow; final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(sChildAppWindowBelow, windows.get(1)); assertEquals(sAppWindow, windows.get(2)); assertEquals(sChildAppWindowAbove, windows.get(3)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(5)); assertEquals(sImeWindow, windows.get(6)); assertEquals(sImeDialogWindow, windows.get(7)); assertEquals(sNavBarWindow, windows.get(8)); // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(8)); assertEquals(sChildAppWindowBelow, windows.get(7)); assertEquals(sAppWindow, windows.get(6)); assertEquals(sChildAppWindowAbove, windows.get(5)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(3)); assertEquals(sImeWindow, windows.get(2)); assertEquals(sImeDialogWindow, windows.get(1)); assertEquals(sNavBarWindow, windows.get(0)); // Clean-up sWm.mInputMethodTarget = null; assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sDockedDividerWindow, sStatusBarWindow, sImeWindow, sImeDialogWindow, sNavBarWindow)); } @Test Loading @@ -176,38 +127,35 @@ public class DisplayContentTests extends WindowTestsBase { final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION, sDisplayContent, "voiceInteractionWindow"); final ArrayList<WindowState> windows = new ArrayList(); // Test forward traversal. sDisplayContent.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(0)); assertEquals(sChildAppWindowBelow, windows.get(1)); assertEquals(sAppWindow, windows.get(2)); assertEquals(sChildAppWindowAbove, windows.get(3)); assertEquals(sDockedDividerWindow, windows.get(4)); assertEquals(voiceInteractionWindow, windows.get(5)); assertEquals(sStatusBarWindow, windows.get(6)); assertEquals(sNavBarWindow, windows.get(7)); assertEquals(sImeWindow, windows.get(8)); assertEquals(sImeDialogWindow, windows.get(9)); assertForAllWindowsOrder(Arrays.asList( sWallpaperWindow, sChildAppWindowBelow, sAppWindow, sChildAppWindowAbove, sDockedDividerWindow, voiceInteractionWindow, sStatusBarWindow, sNavBarWindow, sImeWindow, sImeDialogWindow)); } // Test backward traversal. windows.clear(); sDisplayContent.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */); assertEquals(sWallpaperWindow, windows.get(9)); assertEquals(sChildAppWindowBelow, windows.get(8)); assertEquals(sAppWindow, windows.get(7)); assertEquals(sChildAppWindowAbove, windows.get(6)); assertEquals(sDockedDividerWindow, windows.get(5)); assertEquals(voiceInteractionWindow, windows.get(4)); assertEquals(sStatusBarWindow, windows.get(3)); assertEquals(sNavBarWindow, windows.get(2)); assertEquals(sImeWindow, windows.get(1)); assertEquals(sImeDialogWindow, windows.get(0)); voiceInteractionWindow.removeImmediately(); @Test public void testComputeImeTarget() throws Exception { // Verify that an app window can be an ime target. final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin"); appWin.setHasSurface(true); assertTrue(appWin.canBeImeTarget()); WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); assertEquals(appWin, imeTarget); // Verify that an child window can be an ime target. final WindowState childWin = createWindow(appWin, TYPE_APPLICATION_ATTACHED_DIALOG, "childWin"); childWin.setHasSurface(true); assertTrue(childWin.canBeImeTarget()); imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */); assertEquals(childWin, imeTarget); } /** Loading Loading @@ -284,4 +232,24 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi); assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); } private void assertForAllWindowsOrder(List<WindowState> expectedWindows) { final LinkedList<WindowState> actualWindows = new LinkedList(); // Test forward traversal. sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */); assertEquals(expectedWindows.size(), actualWindows.size()); for (WindowState w : expectedWindows) { assertEquals(w, actualWindows.pollFirst()); } assertTrue(actualWindows.isEmpty()); // Test backward traversal. sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */); assertEquals(expectedWindows.size(), actualWindows.size()); for (WindowState w : expectedWindows) { assertEquals(w, actualWindows.pollLast()); } assertTrue(actualWindows.isEmpty()); } }
services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +37 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,17 @@ import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import java.util.LinkedList; 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_ABOVE_SUB_PANEL; 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_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -167,4 +174,34 @@ public class WindowStateTests extends WindowTestsBase { assertFalse(appWindow.canBeImeTarget()); assertFalse(imeWindow.canBeImeTarget()); } @Test public void testGetWindow() throws Exception { final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild"); final WindowState mediaOverlayChild = createWindow(root, TYPE_APPLICATION_MEDIA_OVERLAY, "mediaOverlayChild"); final WindowState attachedDialogChild = createWindow(root, TYPE_APPLICATION_ATTACHED_DIALOG, "attachedDialogChild"); final WindowState subPanelChild = createWindow(root, TYPE_APPLICATION_SUB_PANEL, "subPanelChild"); final WindowState aboveSubPanelChild = createWindow(root, TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild"); final LinkedList<WindowState> windows = new LinkedList(); root.getWindow(w -> { windows.addLast(w); return false; }); // getWindow should have returned candidate windows in z-order. assertEquals(aboveSubPanelChild, windows.pollFirst()); assertEquals(subPanelChild, windows.pollFirst()); assertEquals(attachedDialogChild, windows.pollFirst()); assertEquals(root, windows.pollFirst()); assertEquals(mediaOverlayChild, windows.pollFirst()); assertEquals(mediaChild, windows.pollFirst()); assertTrue(windows.isEmpty()); } }
services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +13 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.EMPTY; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 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_OVERLAY; Loading @@ -60,6 +61,7 @@ import static org.mockito.Mockito.mock; import com.android.server.AttributeCache; import java.util.HashSet; import java.util.LinkedList; /** * Common base class for window manager unit test classes. Loading Loading @@ -120,6 +122,7 @@ class WindowTestsBase { sCommonWindows = new HashSet(); sWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow"); sImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "sImeWindow"); sWm.mInputMethodWindow = sImeWindow; sImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG, "sImeDialogWindow"); sStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "sStatusBarWindow"); sNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "sNavBarWindow"); Loading @@ -133,16 +136,25 @@ class WindowTestsBase { @After public void tearDown() throws Exception { final LinkedList<WindowState> nonCommonWindows = new LinkedList(); sWm.mRoot.forAllWindows(w -> { if (!sCommonWindows.contains(w)) { w.removeImmediately(); nonCommonWindows.addLast(w); } }, true /* traverseTopToBottom */); while (!nonCommonWindows.isEmpty()) { nonCommonWindows.pollLast().removeImmediately(); } sWm.mInputMethodTarget = null; } private static WindowState createCommonWindow(WindowState parent, int type, String name) { final WindowState win = createWindow(parent, type, name); sCommonWindows.add(win); // Prevent common windows from been IMe targets win.mAttrs.flags |= FLAG_NOT_FOCUSABLE; return win; } Loading