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

Commit a9350fe4 authored by Louis Chang's avatar Louis Chang
Browse files

Displays that have focused apps can also be top focused

There was no focus window during activity switches.
- While starting an activity, the previous top activity was paused and set
  the AppWindowToken.hiddenRequested to true (while #setVisibility)
- While finishing current top activity, the focused window was updated a
  bit early, which was before the next top activity resumed.

In both two cases, the focused window was set to null for a small amount of
time. So, we tried to look up the focus in other displays and resulted
the extra onWindowFocusChanged() calls for activities on other displays.

Bug: 131374329
Test: DisplayContentTests
Change-Id: Ia77bf697c237696cad7b42ca6b38157eff497b23
parent 6d856d33
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -78,6 +78,8 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_W
import static com.android.server.wm.DisplayContentProto.ABOVE_APP_WINDOWS;
import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
import static com.android.server.wm.DisplayContentProto.BELOW_APP_WINDOWS;
import static com.android.server.wm.DisplayContentProto.CHANGING_APPS;
import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
import static com.android.server.wm.DisplayContentProto.DOCKED_STACK_DIVIDER_CONTROLLER;
@@ -85,14 +87,12 @@ import static com.android.server.wm.DisplayContentProto.DPI;
import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
import static com.android.server.wm.DisplayContentProto.ID;
import static com.android.server.wm.DisplayContentProto.IME_WINDOWS;
import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
import static com.android.server.wm.DisplayContentProto.PINNED_STACK_CONTROLLER;
import static com.android.server.wm.DisplayContentProto.ROTATION;
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
import static com.android.server.wm.DisplayContentProto.STACKS;
import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
import static com.android.server.wm.DisplayContentProto.CHANGING_APPS;
import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
@@ -2945,9 +2945,16 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        forAllWindows(mScheduleToastTimeout, false /* traverseTopToBottom */);
    }

    WindowState findFocusedWindowIfNeeded() {
        return (mWmService.mPerDisplayFocusEnabled
                || mWmService.mRoot.mTopFocusedAppByProcess.isEmpty()) ? findFocusedWindow() : null;
    /**
     * Looking for the focused window on this display if the top focused display hasn't been
     * found yet (topFocusedDisplayId is INVALID_DISPLAY) or per-display focused was allowed.
     *
     * @param topFocusedDisplayId Id of the top focused display.
     * @return The focused window or null if there isn't any or no need to seek.
     */
    WindowState findFocusedWindowIfNeeded(int topFocusedDisplayId) {
        return (mWmService.mPerDisplayFocusEnabled || topFocusedDisplayId == INVALID_DISPLAY)
                ? findFocusedWindow() : null;
    }

    WindowState findFocusedWindow() {
@@ -2971,10 +2978,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     *             {@link WindowManagerService#UPDATE_FOCUS_WILL_PLACE_SURFACES},
     *             {@link WindowManagerService#UPDATE_FOCUS_REMOVING_FOCUS}
     * @param updateInputWindows Whether to sync the window information to the input module.
     * @param topFocusedDisplayId Display id of current top focused display.
     * @return {@code true} if the focused window has changed.
     */
    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
        WindowState newFocus = findFocusedWindowIfNeeded();
    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
            int topFocusedDisplayId) {
        WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
        if (mCurrentFocus == newFocus) {
            return false;
        }
@@ -2994,7 +3003,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (imWindowChanged) {
            mWmService.mWindowsChanged = true;
            setLayoutNeeded();
            newFocus = findFocusedWindowIfNeeded();
            newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
        }
        if (mCurrentFocus != newFocus) {
            mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
+6 −1
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        int topFocusedDisplayId = INVALID_DISPLAY;
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final DisplayContent dc = mChildren.get(i);
            changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows);
            changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
            final WindowState newFocus = dc.mCurrentFocus;
            if (newFocus != null) {
                final int pidOfNewFocus = newFocus.mSession.mPid;
@@ -180,6 +180,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                if (topFocusedDisplayId == INVALID_DISPLAY) {
                    topFocusedDisplayId = dc.getDisplayId();
                }
            } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) {
                // The top-most display that has a focused app should still be the top focused
                // display even when the app window is not ready yet (process not attached or
                // window not added yet).
                topFocusedDisplayId = dc.getDisplayId();
            }
        }
        if (topFocusedDisplayId == INVALID_DISPLAY) {
+8 −0
Original line number Diff line number Diff line
@@ -380,6 +380,14 @@ public class DisplayContentTests extends WindowTestsBase {
        assertTrue(window1.isFocused());
        assertEquals(perDisplayFocusEnabled && targetSdk >= Q, window2.isFocused());
        assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);

        // Make sure top focused display not changed if there is a focused app.
        window1.mAppToken.hiddenRequested = true;
        window1.getDisplayContent().setFocusedApp(window1.mAppToken);
        updateFocusedWindow();
        assertTrue(!window1.isFocused());
        assertEquals(window1.getDisplayId(),
                mWm.mRoot.getTopFocusedDisplayContent().getDisplayId());
    }

    /**