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

Commit 3a931694 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Order non-app window containers.

- Add non-app window tokens to the display child container based on
their base layer so the highest based layer is z-ordered on-top.
- Separated DisplayContent.mNonAppWindowContainers into
mAboveAppWindowContainer and mBelowAppWindowContainer where the former
contains non-app windows that should be z-ordered on-top of all app
windows and the later contains non-app windows that should be
z-ordered below app windows.
- Change wallpaper base layer to 1 so that it is always below all other
window types.
- Add Ime related windows/tokens to DisplayContent.mImeWindowContainers
so that we can track them together
- Use alternative binder token when adding window TYPE_INPUT_METHOD_DIALOG
so that it can properly be associated as an IME token in WM vs. with
system_server or sys-ui token.

Test: Existing tests pass.
Bug: 30060889
Change-Id: Ib53e09af12545868c3741d83aaccb7311c872b41
parent 8402d511
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@
package com.android.server;

import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import com.android.internal.content.PackageMonitor;
@@ -113,6 +115,7 @@ import android.view.InputChannel;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerInternal;
import android.view.inputmethod.EditorInfo;
@@ -468,6 +471,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

    private AlertDialog.Builder mDialogBuilder;
    private AlertDialog mSwitchingDialog;
    private IBinder mSwitchingDialogToken = new Binder();
    private View mSwitchingDialogTitleView;
    private Toast mSubtypeSwitchedByShortCutToast;
    private InputMethodInfo[] mIms;
@@ -3288,11 +3292,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

            mSwitchingDialog = mDialogBuilder.create();
            mSwitchingDialog.setCanceledOnTouchOutside(true);
            mSwitchingDialog.getWindow().setType(
                    WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
            mSwitchingDialog.getWindow().getAttributes().privateFlags |=
                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
            mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method");
            final Window w = mSwitchingDialog.getWindow();
            final WindowManager.LayoutParams attrs = w.getAttributes();
            w.setType(TYPE_INPUT_METHOD_DIALOG);
            // Use an alternate token for the dialog for that window manager can group the token
            // with other IME windows based on type vs. grouping based on whichever token happens
            // to get selected by the system later on.
            attrs.token = mSwitchingDialogToken;
            attrs.privateFlags |= PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
            attrs.setTitle("Select input method");
            w.setAttributes(attrs);
            updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition);
            mSwitchingDialog.show();
        }
+3 −3
Original line number Diff line number Diff line
@@ -2549,11 +2549,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return 2;
        }
        switch (type) {
        case TYPE_PRESENTATION:
        case TYPE_PRIVATE_PRESENTATION:
            return 2;
        case TYPE_WALLPAPER:
            // wallpaper is at the bottom, though the window manager may move it.
            return 1;
        case TYPE_PRESENTATION:
        case TYPE_PRIVATE_PRESENTATION:
            return 2;
        case TYPE_DOCK_DIVIDER:
            return 2;
+69 −15
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
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_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
@@ -137,9 +139,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * Utility class for keeping track of the WindowStates and other pertinent contents of a
@@ -154,14 +153,24 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    /** Unique identifier of this stack. */
    private final int mDisplayId;

    // The display only has 2 child window containers. mTaskStackContainers which contains all
    // window containers that are related to apps (Activities) and mNonAppWindowContainers which
    // contains all window containers not related to apps (e.g. Status bar).
    /** The containers below are the only child containers the display can have. */
    // Contains all window containers that are related to apps (Activities)
    private final TaskStackContainers mTaskStackContainers = new TaskStackContainers();
    private final NonAppWindowContainers mNonAppWindowContainers = new NonAppWindowContainers();

    /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element
     * from mDisplayWindows; */
    // Contains all non-app window containers that should be displayed above the app containers
    // (e.g. Status bar)
    private final NonAppWindowContainers mAboveAppWindowsContainers =
            new NonAppWindowContainers("mAboveAppWindowsContainers");
    // Contains all non-app window containers that should be displayed below the app containers
    // (e.g. Wallpaper).
    private final NonAppWindowContainers mBelowAppWindowsContainers =
            new NonAppWindowContainers("mBelowAppWindowsContainers");
    // Contains all IME window containers. Note that the z-ordering of the IME windows will depend
    // on the IME target. We mainly have this container grouping so we can keep track of all the IME
    // window containers together and move them in-sync if/when needed.
    private final NonAppWindowContainers mImeWindowsContainers =
            new NonAppWindowContainers("mImeWindowsContainers");

    // Z-ordered (bottom-most first) list of all Window objects.
    private final WindowList mWindows = new WindowList();

    // Mapping from a token IBinder to a WindowToken object on this display.
@@ -266,8 +275,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        mDimLayerController = new DimLayerController(this);

        // These are the only direct children we should ever have and they are permanent.
        super.addChild(mBelowAppWindowsContainers, null);
        super.addChild(mTaskStackContainers, null);
        super.addChild(mNonAppWindowContainers, null);
        super.addChild(mAboveAppWindowsContainers, null);
        super.addChild(mImeWindowsContainers, null);
    }

    int getDisplayId() {
@@ -301,14 +312,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (token.asAppWindowToken() == null) {
            // Add non-app token to container hierarchy on the display. App tokens are added through
            // the parent container managing them (e.g. Tasks).
            mNonAppWindowContainers.addChild(token, null);
            switch (token.windowType) {
                case TYPE_WALLPAPER:
                    mBelowAppWindowsContainers.addChild(token);
                    break;
                case TYPE_INPUT_METHOD:
                case TYPE_INPUT_METHOD_DIALOG:
                    mImeWindowsContainers.addChild(token);
                    break;
                default:
                    mAboveAppWindowsContainers.addChild(token);
                    break;
            }
        }
    }

    WindowToken removeWindowToken(IBinder binder) {
        final WindowToken token = mTokenMap.remove(binder);
        if (token != null && token.asAppWindowToken() == null) {
            mNonAppWindowContainers.removeChild(token);
            switch (token.windowType) {
                case TYPE_WALLPAPER:
                    mBelowAppWindowsContainers.removeChild(token);
                    break;
                case TYPE_INPUT_METHOD:
                case TYPE_INPUT_METHOD_DIALOG:
                    mImeWindowsContainers.removeChild(token);
                    break;
                default:
                    mAboveAppWindowsContainers.removeChild(token);
                    break;
            }
        }
        return token;
    }
@@ -3076,7 +3109,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     * Window container class that contains all containers on this display relating to Apps.
     * I.e Activities.
     */
    private class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
    private final class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {

        void attachStack(TaskStack stack, boolean onTop) {
            if (stack.mStackId == HOME_STACK_ID) {
@@ -3158,7 +3191,28 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     * Window container class that contains all containers on this display that are not related to
     * Apps. E.g. status bar.
     */
    private static class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
    private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
        /**
         * Compares two child window tokens returns -1 if the first is lesser than the second in
         * terms of z-order and 1 otherwise.
         */
        final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
                // Tokens with higher base layer are z-ordered on-top.
                mService.mPolicy.windowTypeToLayerLw(token1.windowType)
                < mService.mPolicy.windowTypeToLayerLw(token2.windowType) ? -1 : 1;

        private final String mName;
        NonAppWindowContainers(String name) {
            mName = name;
        }

        void addChild(WindowToken token) {
            addChild(token, mWindowComparator);
        }

        @Override
        String getName() {
            return mName;
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -1219,7 +1219,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                    }
                }
                token = new WindowToken(this, attrs.token, -1, false, displayContent);
                token = new WindowToken(this, attrs.token, type, false, displayContent);
            } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                atoken = token.asAppWindowToken();
                if (atoken == null) {
@@ -1287,7 +1287,7 @@ public class WindowManagerService extends IWindowManager.Stub
                // It is not valid to use an app token with other system types; we will
                // instead make a new token for it (as if null had been passed in for the token).
                attrs.token = null;
                token = new WindowToken(this, null, -1, false, displayContent);
                token = new WindowToken(this, null, type, false, displayContent);
            }

            WindowState win = new WindowState(this, session, client, token, parentWindow,