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

Commit f19cbe20 authored by Bryce Lee's avatar Bryce Lee
Browse files

Restrict DisplayContent creation.

This changelist limits DisplayContent the display
container/controller creation. All other callpoints now can only
retrieve existing DisplayContents. This removes the chances of
arbitrary calls generating a DisplayContent without the related
ActivityDisplay on the ActivityManager side.

Since display creation is now driven on the ActivityManager side,
the ActivityManagerService must be initialized and associated with
the WindowManagerService before the WindowManagerService can be fully
initialized. This is reflected in changes to SystemServer.

Fixes: 72228411
Test: go/wm-smoke-auto
Change-Id: I8dddb5fc109be4363de5ba87faff9d9885009042
parent bc48bd8f
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -657,6 +657,26 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        return false;
    }

    void remove() {
        final boolean destroyContentOnRemoval = shouldDestroyContentOnRemove();
        while (getChildCount() > 0) {
            final ActivityStack stack = getChildAt(0);
            if (destroyContentOnRemoval) {
                mSupervisor.moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY,
                        false /* onTop */);
                stack.finishAllActivitiesLocked(true /* immediately */);
            } else {
                // Moving all tasks to fullscreen stack, because it's guaranteed to be
                // a valid launch stack for all activities. This way the task history from
                // external display will be preserved on primary after move.
                mSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
            }
        }

        mWindowContainerController.removeContainer();
        mWindowContainerController = null;
    }

    /** Update and get all UIDs that are present on the display and have access to it. */
    IntArray getPresentUIDs() {
        mDisplayAccessUIDs.clear();
@@ -666,7 +686,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        return mDisplayAccessUIDs;
    }

    boolean shouldDestroyContentOnRemove() {
    private boolean shouldDestroyContentOnRemove() {
        return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
    }

+2 −15
Original line number Diff line number Diff line
@@ -4087,25 +4087,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            if (activityDisplay == null) {
                return;
            }
            final boolean destroyContentOnRemoval
                    = activityDisplay.shouldDestroyContentOnRemove();
            while (activityDisplay.getChildCount() > 0) {
                final ActivityStack stack = activityDisplay.getChildAt(0);
                if (destroyContentOnRemoval) {
                    moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY, false /* onTop */);
                    stack.finishAllActivitiesLocked(true /* immediately */);
                } else {
                    // Moving all tasks to fullscreen stack, because it's guaranteed to be
                    // a valid launch stack for all activities. This way the task history from
                    // external display will be preserved on primary after move.
                    moveTasksToFullscreenStackLocked(stack, true /* onTop */);
                }
            }

            activityDisplay.remove();

            releaseSleepTokens(activityDisplay);

            mActivityDisplays.remove(displayId);
            mWindowManager.onDisplayRemoved(displayId);
        }
    }

+4 −2
Original line number Diff line number Diff line
@@ -725,8 +725,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     *                            wallpaper windows in the window list.
     */
    DisplayContent(Display display, WindowManagerService service,
            WallpaperController wallpaperController) {
            WallpaperController wallpaperController, DisplayWindowController controller) {
        super(service);
        setController(controller);
        if (service.mRoot.getDisplayContent(display.getDisplayId()) != null) {
            throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
                    + " already exists=" + service.mRoot.getDisplayContent(display.getDisplayId())
@@ -1941,6 +1942,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        } finally {
            mRemovingDisplay = false;
        }

        mService.onDisplayRemoved(mDisplayId);
    }

    /** Returns true if a removal action is still being deferred. */
@@ -1950,7 +1953,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

        if (!stillDeferringRemoval && mDeferredRemoval) {
            removeImmediately();
            mService.onDisplayRemoved(mDisplayId);
            return false;
        }
        return true;
+25 −7
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.server.wm;

import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.content.res.Configuration;
import android.os.Binder;
import android.util.Slog;
import android.view.Display;

/**
 * Controller for the display container. This is created by activity manager to link activity
@@ -36,9 +39,16 @@ public class DisplayWindowController
        mDisplayId = displayId;

        synchronized (mWindowMap) {
            // TODO: Convert to setContainer() from DisplayContent once everything is hooked up.
            // Currently we are not setup to register for config changes.
            mContainer = mRoot.getDisplayContentOrCreate(displayId);
            final Display display = mService.mDisplayManager.getDisplay(displayId);
            if (display != null) {
                final long callingIdentity = Binder.clearCallingIdentity();
                try {
                    mRoot.createDisplayContent(display, this /* controller */);
                } finally {
                    Binder.restoreCallingIdentity(callingIdentity);
                }
            }

            if (mContainer == null) {
                throw new IllegalArgumentException("Trying to add displayId=" + displayId);
            }
@@ -47,14 +57,22 @@ public class DisplayWindowController

    @Override
    public void removeContainer() {
        // TODO: Pipe through from ActivityDisplay to remove the display
        throw new UnsupportedOperationException("To be implemented");
        synchronized (mWindowMap) {
            if(mContainer == null) {
                if (DEBUG_DISPLAY) Slog.i(TAG_WM, "removeDisplay: could not find displayId="
                        + mDisplayId);
                return;
            }
            mContainer.removeIfPossible();
            super.removeContainer();
        }
    }

    @Override
    public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
        // TODO: Pipe through from ActivityDisplay to update the configuration for the display
        throw new UnsupportedOperationException("To be implemented");
        // TODO: The container receives override configuration changes through other means. enabling
        // callbacks through the controller causes layout issues. Investigate consolidating
        // override configuration propagation to just here.
    }

    /**
+3 −27
Original line number Diff line number Diff line
@@ -193,30 +193,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
        }
    }

    /**
     * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
     * there is a Display for the displayId.
     *
     * @param displayId The display the caller is interested in.
     * @return The DisplayContent associated with displayId or null if there is no Display for it.
     */
    DisplayContent getDisplayContentOrCreate(int displayId) {
        DisplayContent dc = getDisplayContent(displayId);

        if (dc == null) {
            final Display display = mService.mDisplayManager.getDisplay(displayId);
            if (display != null) {
                final long callingIdentity = Binder.clearCallingIdentity();
                try {
                    dc = createDisplayContent(display);
                } finally {
                    Binder.restoreCallingIdentity(callingIdentity);
                }
            }
        }
        return dc;
    }

    DisplayContent getDisplayContent(int displayId) {
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final DisplayContent current = mChildren.get(i);
@@ -227,9 +203,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
        return null;
    }

    private DisplayContent createDisplayContent(final Display display) {
        final DisplayContent dc = new DisplayContent(display, mService,
                mWallpaperController);
    DisplayContent createDisplayContent(final Display display, DisplayWindowController controller) {
        final DisplayContent dc =
                new DisplayContent(display, mService, mWallpaperController, controller);
        final int displayId = display.getDisplayId();

        if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
Loading