Loading services/core/java/com/android/server/wm/DisplayContent.java +39 −0 Original line number Diff line number Diff line Loading @@ -2622,6 +2622,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * Apps. E.g. status bar. */ private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> { final LinkedList<WindowState> mTmpWindows = new LinkedList(); private final ToBooleanFunction<WindowState> mCollectWindowsInOrder = w -> { int addIndex = mTmpWindows.size(); for (int i = mTmpWindows.size() - 1; i >= 0; --i) { final WindowState current = mTmpWindows.get(i); if (w.mBaseLayer > current.mBaseLayer) { break; } addIndex = i; } mTmpWindows.add(addIndex, w); return false; }; /** * Compares two child window tokens returns -1 if the first is lesser than the second in * terms of z-order and 1 otherwise. Loading Loading @@ -2652,6 +2668,29 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo addChild(token, mWindowComparator); } @Override boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) { // Hack to work around WindowToken containing windows of various types there by causing // the windows not to be returned in visual order if there is another token with a // window that should be z-order in-between the windows of the first token. This is an // issue due to the various window types sys-ui adds with its token. // TODO: Have a separate token for each type of window sys-ui wants to add. Would // require some changes to sys-ui on the token it uses for window creation vs. just // using the default token of its process. mTmpWindows.clear(); super.forAllWindows(mCollectWindowsInOrder, false /* traverseTopToBottom */); while(!mTmpWindows.isEmpty()) { final WindowState current = traverseTopToBottom ? mTmpWindows.pollLast() : mTmpWindows.pollFirst(); if (callback.apply(current)) { return true; } } return false; } @Override int getOrientation() { final WindowManagerPolicy policy = mService.mPolicy; Loading services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +44 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.support.test.runner.AndroidJUnit4; import java.util.ArrayList; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static org.junit.Assert.assertEquals; /** Loading Loading @@ -77,6 +78,8 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(sNavBarWindow, windows.get(2)); assertEquals(sImeWindow, windows.get(1)); assertEquals(sImeDialogWindow, windows.get(0)); exitingAppWindow.removeImmediately(); } @Test Loading Loading @@ -121,4 +124,45 @@ public class DisplayContentTests extends WindowTestsBase { sWm.mInputMethodTarget = null; imeAppTarget.removeImmediately(); } @Test public void testForAllWindows_WithInBetweenWindowToken() throws Exception { // This window is set-up to be z-ordered between some windows that go in the same token like // the nav bar and status bar. 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)); // 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(); } } services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +3 −2 Original line number Diff line number Diff line Loading @@ -82,10 +82,11 @@ public class WindowTestsBase { sImeDialogWindow = createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow"); sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow"); final WindowToken statusBarToken = sStatusBarWindow.mToken; sNavBarWindow = createWindow(null, TYPE_NAVIGATION_BAR, sStatusBarWindow.mToken, "sNavBarWindow"); createWindow(null, TYPE_NAVIGATION_BAR, statusBarToken, "sNavBarWindow"); sDockedDividerWindow = createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow"); createWindow(null, TYPE_DOCK_DIVIDER, statusBarToken, "sDockedDividerWindow"); sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow"); sChildAppWindowAbove = createWindow(sAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove"); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +39 −0 Original line number Diff line number Diff line Loading @@ -2622,6 +2622,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * Apps. E.g. status bar. */ private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> { final LinkedList<WindowState> mTmpWindows = new LinkedList(); private final ToBooleanFunction<WindowState> mCollectWindowsInOrder = w -> { int addIndex = mTmpWindows.size(); for (int i = mTmpWindows.size() - 1; i >= 0; --i) { final WindowState current = mTmpWindows.get(i); if (w.mBaseLayer > current.mBaseLayer) { break; } addIndex = i; } mTmpWindows.add(addIndex, w); return false; }; /** * Compares two child window tokens returns -1 if the first is lesser than the second in * terms of z-order and 1 otherwise. Loading Loading @@ -2652,6 +2668,29 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo addChild(token, mWindowComparator); } @Override boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) { // Hack to work around WindowToken containing windows of various types there by causing // the windows not to be returned in visual order if there is another token with a // window that should be z-order in-between the windows of the first token. This is an // issue due to the various window types sys-ui adds with its token. // TODO: Have a separate token for each type of window sys-ui wants to add. Would // require some changes to sys-ui on the token it uses for window creation vs. just // using the default token of its process. mTmpWindows.clear(); super.forAllWindows(mCollectWindowsInOrder, false /* traverseTopToBottom */); while(!mTmpWindows.isEmpty()) { final WindowState current = traverseTopToBottom ? mTmpWindows.pollLast() : mTmpWindows.pollFirst(); if (callback.apply(current)) { return true; } } return false; } @Override int getOrientation() { final WindowManagerPolicy policy = mService.mPolicy; Loading
services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +44 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.support.test.runner.AndroidJUnit4; import java.util.ArrayList; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static org.junit.Assert.assertEquals; /** Loading Loading @@ -77,6 +78,8 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(sNavBarWindow, windows.get(2)); assertEquals(sImeWindow, windows.get(1)); assertEquals(sImeDialogWindow, windows.get(0)); exitingAppWindow.removeImmediately(); } @Test Loading Loading @@ -121,4 +124,45 @@ public class DisplayContentTests extends WindowTestsBase { sWm.mInputMethodTarget = null; imeAppTarget.removeImmediately(); } @Test public void testForAllWindows_WithInBetweenWindowToken() throws Exception { // This window is set-up to be z-ordered between some windows that go in the same token like // the nav bar and status bar. 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)); // 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(); } }
services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +3 −2 Original line number Diff line number Diff line Loading @@ -82,10 +82,11 @@ public class WindowTestsBase { sImeDialogWindow = createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow"); sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow"); final WindowToken statusBarToken = sStatusBarWindow.mToken; sNavBarWindow = createWindow(null, TYPE_NAVIGATION_BAR, sStatusBarWindow.mToken, "sNavBarWindow"); createWindow(null, TYPE_NAVIGATION_BAR, statusBarToken, "sNavBarWindow"); sDockedDividerWindow = createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow"); createWindow(null, TYPE_DOCK_DIVIDER, statusBarToken, "sDockedDividerWindow"); sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow"); sChildAppWindowAbove = createWindow(sAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindowAbove"); Loading