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

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

Merge "Add windows to window tokens in expected z-order"

parents 7d7037cf 07bcab78
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -676,6 +676,34 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
        mPendingRelaunchCount = 0;
    }

    /**
     * Returns true if the new child window we are adding to this token is considered greater than
     * the existing child window in this token in terms of z-order.
     */
    @Override
    protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
            WindowState existingWindow) {
        final int type1 = newWindow.mAttrs.type;
        final int type2 = existingWindow.mAttrs.type;

        // Base application windows should be z-ordered BELOW all other windows in the app token.
        if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
            return false;
        } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
            return true;
        }

        // Starting windows should be z-ordered ABOVE all other windows in the app token.
        if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
            return true;
        } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
            return false;
        }

        // Otherwise the new window is greater than the existing window.
        return true;
    }

    @Override
    void addWindow(WindowState w) {
        super.addWindow(w);
+6 −16
Original line number Diff line number Diff line
@@ -1085,12 +1085,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        return null;
    }

    int addAppWindowToWindowList(final WindowState win) {
    void addAppWindowToWindowList(final WindowState win) {
        final IWindow client = win.mClient;

        WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
        if (!tokenWindowList.isEmpty()) {
            return addAppWindowExisting(win, tokenWindowList);
            addAppWindowExisting(win, tokenWindowList);
            return;
        }

        // No windows from this token on this display
@@ -1128,7 +1129,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                }
            }
            addWindowToListBefore(win, pos);
            return 0;
            return;
        }

        // Continue looking down until we find the first token that has windows on this display.
@@ -1154,7 +1155,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                }
            }
            addWindowToListAfter(win, pos);
            return 0;
            return;
        }

        // Just search for the start of this layer.
@@ -1175,7 +1176,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                + mWindows.size());
        mWindows.add(i + 1, win);
        mService.mWindowsChanged = true;
        return 0;
    }

    /** Adds this non-app window to the window list. */
@@ -1778,23 +1778,20 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        return mLayoutNeeded;
    }

    private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
    private void addAppWindowExisting(WindowState win, WindowList tokenWindowList) {

        int tokenWindowsPos;
        // If this application has existing windows, we simply place the new window on top of
        // them... but keep the starting window on top.
        if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
            // Base windows go behind everything else.
            final WindowState lowestWindow = tokenWindowList.get(0);
            addWindowToListBefore(win, lowestWindow);
            tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
        } else {
            final AppWindowToken atoken = win.mAppToken;
            final int windowListPos = tokenWindowList.size();
            final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
            if (atoken != null && lastWindow == atoken.startingWindow) {
                addWindowToListBefore(win, lastWindow);
                tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
            } else {
                int newIdx = findIdxBasedOnAppTokens(win);
                // There is a window above this one associated with the same apptoken note that the
@@ -1804,16 +1801,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                        "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
                                + mWindows.size());
                mWindows.add(newIdx + 1, win);
                if (newIdx < 0) {
                    // No window from token found on win's display.
                    tokenWindowsPos = 0;
                } else {
                    tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
                }
                mService.mWindowsChanged = true;
            }
        }
        return tokenWindowsPos;
    }

    /** Places the first input window after the second input window in the window list. */
+37 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.util.Slog;
import android.view.DisplayInfo;

import java.io.PrintWriter;
import java.util.Comparator;

import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
@@ -82,6 +83,26 @@ class WindowToken extends WindowContainer<WindowState> {
    // The display this token is on.
    private DisplayContent mDisplayContent;

    /**
     * Compares two child window of this token and returns -1 if the first is lesser than the
     * second in terms of z-order and 1 otherwise.
     */
    private final Comparator<WindowState> mWindowComparator =
            (WindowState newWindow, WindowState existingWindow) -> {
        final WindowToken token = WindowToken.this;
        if (newWindow.mToken != token) {
            throw new IllegalArgumentException("newWindow=" + newWindow
                    + " is not a child of token=" + token);
        }

        if (existingWindow.mToken != token) {
            throw new IllegalArgumentException("existingWindow=" + existingWindow
                    + " is not a child of token=" + token);
        }

        return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1;
    };

    WindowToken(WindowManagerService service, IBinder _token, int type, boolean _explicit,
            DisplayContent dc) {
        mService = service;
@@ -168,19 +189,31 @@ class WindowToken extends WindowContainer<WindowState> {
        return -1;
    }

    /**
     * Returns true if the new window is considered greater than the existing window in terms of
     * z-order.
     */
    protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
            WindowState existingWindow) {
        // By default the first window isn't greater than the second to preserve existing logic of
        // how new windows are added to the token
        return false;
    }

    void addWindow(final WindowState win) {
        if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
        if (DEBUG_FOCUS) Slog.d(TAG_WM,
                "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));

        if (!win.isChildWindow()) {
            int tokenWindowsPos = 0;
            if (asAppWindowToken() != null) {
                tokenWindowsPos = mDisplayContent.addAppWindowToWindowList(win);
                mDisplayContent.addAppWindowToWindowList(win);
            } else {
                mDisplayContent.addNonAppWindowToWindowList(win);
            }

            if (!mChildren.contains(win)) {
                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
                addChild(win, tokenWindowsPos);
                addChild(win, mWindowComparator);
            }
        } else {
            mDisplayContent.addChildWindowToWindowList(win);
+43 −3
Original line number Diff line number Diff line
@@ -29,17 +29,19 @@ import android.view.IWindow;
import android.view.WindowManager;

import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

/**
 * Tests for the {@link WindowState} class.
 *
 * Build: mmma -j32 frameworks/base/services/tests/servicestests
 * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
 * Run: adb shell am instrument -w -e class com.android.server.wm.AppWindowTokenTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
 * Build/Install/Run:
 *  bit FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests
 */
@SmallTest
@Presubmit
@@ -55,6 +57,36 @@ public class AppWindowTokenTests {
        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
    }

    @Test
    public void testAddWindow_Order() throws Exception {
        final TestAppWindowToken token = new TestAppWindowToken();

        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);

        token.addWindow(win1);
        token.addWindow(startingWin);
        token.addWindow(baseWin);
        token.addWindow(win4);

        // Should not contain the windows that were added above.
        assertEquals(4, token.getWindowsCount());
        assertTrue(token.hasWindow(win1));
        assertTrue(token.hasWindow(startingWin));
        assertTrue(token.hasWindow(baseWin));
        assertTrue(token.hasWindow(win4));

        // The starting window should be on-top of all other windows.
        assertEquals(startingWin, token.getLastChild());

        // The base application window should be below all other windows.
        assertEquals(baseWin, token.getFirstChild());
    }

    @Test
    public void testFindMainWindow() throws Exception {
        final TestAppWindowToken token = new TestAppWindowToken();
@@ -93,5 +125,13 @@ public class AppWindowTokenTests {
        boolean hasWindow(WindowState w) {
            return mChildren.contains(w);
        }

        WindowState getFirstChild() {
            return mChildren.getFirst();
        }

        WindowState getLastChild() {
            return mChildren.getLast();
        }
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -41,9 +41,8 @@ import static org.mockito.Mockito.mock;
/**
 * Tests for the {@link WindowState} class.
 *
 * Build: mmma -j32 frameworks/base/services/tests/servicestests
 * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
 * Run: adb shell am instrument -w -e class com.android.server.wm.WindowTokenTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
 * Build/Install/Run:
 *  bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests
 */
@SmallTest
@Presubmit