Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bb1f891 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixed window ordering issue with TYPE_VOICE_INTERACTION."

parents 03004291 5d7e7f13
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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;
+44 −0
Original line number Diff line number Diff line
@@ -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;

/**
@@ -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
@@ -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();
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -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");