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

Commit 5f709f90 authored by Lingyu Feng's avatar Lingyu Feng
Browse files

Update shouldShowSystemDecors on Display.canHostTasks changes

When the "Mirror Built-in Display" switch is toggles,
Display.canHostTasks changes, and WM is notified via onDisplayChanged().

In this CL, DisplayWindowSettings.mShouldShowSystemDecors is updated
based on the value of Display.canHostTasks:

If true, system decorations is started in the display;
If false, all tasks on the display are removed or reparented to the
defualt display.

Bug: 352461502
Bug: 374240163
Flag: com.android.server.display.feature.flags.enable_display_content_mode_management
Test: manually (adb shell settings put secure mirror_built_in_display {1|0})
Test: DisplayContentTests

Change-Id: I8dfb0f7e96386d285fd7e40d76602dab95c98187
parent c05c4e0e
Loading
Loading
Loading
Loading
+43 −6
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_SCREEN_ON;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_TRANSACTIONS;
import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -3277,6 +3278,32 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return new Point(w, h);
    }

    void onDisplayInfoChangeApplied() {
        if (!enableDisplayContentModeManagement()) {
            Slog.e(TAG, "ShouldShowSystemDecors shouldn't be updated when the flag is off.");
        }

        final boolean shouldShow;
        if (isDefaultDisplay) {
            shouldShow = true;
        } else if (isPrivate()) {
            shouldShow = false;
        } else {
            shouldShow = mDisplay.canHostTasks();
        }

        if (shouldShow == mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(this)) {
            return;
        }
        mWmService.mDisplayWindowSettings.setShouldShowSystemDecorsLocked(this, shouldShow);

        if (shouldShow) {
            mRootWindowContainer.startSystemDecorations(this, "onDisplayInfoChangeApplied");
        } else {
            clearAllTasksOnDisplay(null);
        }
    }

    DisplayCutout loadDisplayCutout(int displayWidth, int displayHeight) {
        if (mDisplayPolicy == null || mInitialDisplayCutout == null) {
            return null;
@@ -6511,10 +6538,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return mRemoving;
    }

    void remove() {
        mRemoving = true;
    private void clearAllTasksOnDisplay(@Nullable Runnable clearTasksCallback) {
        Task lastReparentedRootTask;

        mRootWindowContainer.mTaskSupervisor.beginDeferResume();
        try {
            lastReparentedRootTask = reduceOnAllTaskDisplayAreas((taskDisplayArea, rootTask) -> {
@@ -6527,10 +6552,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        } finally {
            mRootWindowContainer.mTaskSupervisor.endDeferResume();
        }
        mRemoved = true;

        if (mContentRecorder != null) {
            mContentRecorder.stopRecording();
        if (clearTasksCallback != null) {
            clearTasksCallback.run();
        }

        // Only update focus/visibility for the last one because there may be many root tasks are
@@ -6538,6 +6562,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        if (lastReparentedRootTask != null) {
            lastReparentedRootTask.resumeNextFocusAfterReparent();
        }
    }

    void remove() {
        mRemoving = true;

        clearAllTasksOnDisplay(() -> {
            mRemoved = true;

            if (mContentRecorder != null) {
                mContentRecorder.stopRecording();
            }
        });

        releaseSelfIfNeeded();
        mDisplayPolicy.release();

+28 −9
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_STATES;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_SURFACE_ALLOC;
import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -151,6 +152,7 @@ import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.UserState;
import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.pm.UserManagerInternal;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.policy.WindowManagerPolicy;
@@ -1438,6 +1440,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                    : getDefaultTaskDisplayArea();
        }

        // When display content mode management flag is enabled, the task display area is marked as
        // removed when switching from extended display to mirroring display. We need to restart the
        // task display area before starting the home.
        if (enableDisplayContentModeManagement() && taskDisplayArea.isRemoved()) {
            taskDisplayArea.restart();
        }

        Intent homeIntent = null;
        ActivityInfo aInfo = null;
        if (taskDisplayArea == getDefaultTaskDisplayArea()
@@ -2850,20 +2859,24 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            if (display == null) {
                return;
            }
            // Do not start home before booting, or it may accidentally finish booting before it
            // starts. Instead, we expect home activities to be launched when the system is ready
            // (ActivityManagerService#systemReady).
            if (mService.isBooted() || mService.isBooting()) {
                startSystemDecorations(display);
            }

            startSystemDecorations(display, "displayAdded");

            // Drop any cached DisplayInfos associated with this display id - the values are now
            // out of date given this display added event.
            mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
        }
    }

    private void startSystemDecorations(final DisplayContent displayContent) {
        startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
    void startSystemDecorations(final DisplayContent displayContent, String reason) {
        // Do not start home before booting, or it may accidentally finish booting before it
        // starts. Instead, we expect home activities to be launched when the system is ready
        // (ActivityManagerService#systemReady).
        if (!mService.isBooted() && !mService.isBooting()) {
            return;
        }

        startHomeOnDisplay(mCurrentUser, reason, displayContent.getDisplayId());
        displayContent.getDisplayPolicy().notifyDisplayReady();
    }

@@ -2890,7 +2903,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        synchronized (mService.mGlobalLock) {
            final DisplayContent displayContent = getDisplayContent(displayId);
            if (displayContent != null) {
                displayContent.requestDisplayUpdate(() -> clearDisplayInfoCaches(displayId));
                displayContent.requestDisplayUpdate(
                        () -> {
                            clearDisplayInfoCaches(displayId);
                            if (enableDisplayContentModeManagement()) {
                                displayContent.onDisplayInfoChangeApplied();
                            }
                        });
            } else {
                clearDisplayInfoCaches(displayId);
            }
+5 −0
Original line number Diff line number Diff line
@@ -1887,6 +1887,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
        return lastReparentedRootTask;
    }

    // TODO(b/385263090): Remove this method
    void restart() {
        mRemoved = false;
    }

    /**
     * Returns the {@link TaskDisplayArea} to which root tasks should be reparented.
     *
+38 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.window.flags.Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE;
import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT;

import static com.google.common.truth.Truth.assertThat;

@@ -2847,6 +2848,43 @@ public class DisplayContentTests extends WindowTestsBase {
        assertFalse(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
    }

    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
    @Test
    public void testSetShouldShowSystemDecorations_defaultDisplay() {
        DisplayContent dc = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);

        dc.onDisplayInfoChangeApplied();
        assertTrue(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
    }

    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
    @Test
    public void testSetShouldShowSystemDecorations_privateDisplay() {
        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
        displayInfo.flags = FLAG_PRIVATE;
        final DisplayContent dc = createNewDisplay(displayInfo);

        dc.onDisplayInfoChangeApplied();
        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
    }

    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
    @Test
    public void testSetShouldShowSystemDecorations_nonDefaultNonPrivateDisplay() {
        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
        displayInfo.displayId = DEFAULT_DISPLAY + 1;
        final DisplayContent dc = createNewDisplay(displayInfo);

        spyOn(dc.mDisplay);
        doReturn(false).when(dc.mDisplay).canHostTasks();
        dc.onDisplayInfoChangeApplied();
        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));

        doReturn(true).when(dc.mDisplay).canHostTasks();
        dc.onDisplayInfoChangeApplied();
        assertTrue(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
    }

    private void removeRootTaskTests(Runnable runnable) {
        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
        final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,