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

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

Merge "Fix InvalidDisplayException on display removal for visible background users" into main

parents 5268d622 87327dd2
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
@@ -57,6 +58,7 @@ import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.LaunchParamsController.LaunchParams;

import java.io.PrintWriter;
@@ -1761,10 +1763,10 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
     * @return last reparented root task, or {@code null} if the root tasks had to be destroyed.
     */
    Task remove() {
        final TaskDisplayArea toDisplayArea = getReparentToTaskDisplayArea(getFocusedRootTask());
        mPreferredTopFocusableRootTask = null;
        // TODO(b/153090332): Allow setting content removal mode per task display area
        final boolean destroyContentOnRemoval = mDisplayContent.shouldDestroyContentOnRemove();
        final TaskDisplayArea toDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
        Task lastReparentedRootTask = null;

        // Root tasks could be reparented from the removed display area to other display area. After
@@ -1830,6 +1832,41 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
        return lastReparentedRootTask;
    }

    /**
     * Returns the {@link TaskDisplayArea} to which root tasks should be reparented.
     *
     * <p>In the automotive multi-user multi-display environment where background users have
     * UI access on their assigned displays (a.k.a. visible background users), it's not allowed to
     * launch an activity on an unassigned display. If an activity is attempted to launch on an
     * unassigned display, it throws an exception.
     * <p>This method determines the appropriate {@link TaskDisplayArea} for reparenting root tasks
     * when a display is removed, in order to avoid the exception. If the root task is null,
     * the visible background user is not supported or the user associated with the root task is
     * not a visible background user, it returns the default {@link TaskDisplayArea} of the default
     * display. Otherwise, it returns the default {@link TaskDisplayArea} of the main display
     * assigned to the user.
     *
     * @param rootTask The root task whose {@link TaskDisplayArea} needs to be determined.
     * @return The {@link TaskDisplayArea} where the root tasks should be reparented to.
     */
    private TaskDisplayArea getReparentToTaskDisplayArea(Task rootTask) {
        final TaskDisplayArea defaultTaskDisplayArea =
                mRootWindowContainer.getDefaultTaskDisplayArea();
        if (rootTask == null) {
            return defaultTaskDisplayArea;
        }
        UserManagerInternal userManagerInternal = mAtmService.mWindowManager.mUmInternal;
        if (!userManagerInternal.isVisibleBackgroundFullUser(rootTask.mUserId)) {
            return defaultTaskDisplayArea;
        }
        int toDisplayId = userManagerInternal.getMainDisplayAssignedToUser(rootTask.mUserId);
        if (toDisplayId == INVALID_DISPLAY) {
            return defaultTaskDisplayArea;
        }
        DisplayContent dc = mRootWindowContainer.getDisplayContent(toDisplayId);
        return dc != null ? dc.getDefaultTaskDisplayArea() : defaultTaskDisplayArea;
    }

    /** Whether this task display area can request orientation. */
    boolean canSpecifyOrientation(@ScreenOrientation int orientation) {
        // Only allow to specify orientation if this TDA is the last focused one on this logical