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

Commit 7466610e authored by Winson Chung's avatar Winson Chung
Browse files

Resize task to fullscreen when moving from pinned stack.

- This was a regression in the original change to move the tasks to the
  fullscreen stack when the pinned stack was removed.  The task kept its
  old bounds, which causes the next animation into the PiP to not run
  since the stack bounds are taken from task bounds (which are the old
  pinned stack bounds)

Bug: 35326108
Test: run-test CtsServicesHostTestCases
Change-Id: I234910107cf62cc23b2d663161d250b9d59b3934
parent c20082bd
Loading
Loading
Loading
Loading
+49 −21
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
import static com.android.server.wm.AppTransition.TRANSIT_NONE;
@@ -144,6 +146,8 @@ import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import static java.lang.Integer.MAX_VALUE;
import android.Manifest;
import android.Manifest.permission;
import android.annotation.NonNull;
@@ -9803,14 +9807,19 @@ public class ActivityManagerService extends IActivityManager.Stub
                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
                    stackId = FREEFORM_WORKSPACE_STACK_ID;
                }
                // Reparent the task to the right stack if necessary
                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
                if (stackId != task.getStackId()) {
                    mStackSupervisor.moveTaskToStackUncheckedLocked(task, stackId, ON_TOP,
                            !FORCE_FOCUS, "resizeTask");
                    // Defer resume until the task is resized below
                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
                            DEFER_RESUME, "resizeTask");
                    preserveWindow = false;
                }
                task.resize(bounds, resizeMode, preserveWindow, false /* deferResume */);
                // After reparenting (which only resizes the task to the stack bounds), resize the
                // task to the actual bounds provided
                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
@@ -10189,14 +10198,16 @@ public class ActivityManagerService extends IActivityManager.Stub
                    throw new IllegalArgumentException(
                            "exitFreeformMode: No activity record matching token=" + token);
                }
                final ActivityStack stack = r.getStackLocked(token);
                final ActivityStack stack = r.getStack();
                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
                    throw new IllegalStateException(
                            "exitFreeformMode: You can only go fullscreen from freeform.");
                }
                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
                r.task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT,
                        ANIMATE, !DEFER_RESUME, "exitFreeformMode");
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
@@ -10213,15 +10224,22 @@ public class ActivityManagerService extends IActivityManager.Stub
        synchronized (this) {
            long ident = Binder.clearCallingIdentity();
            try {
                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
                if (task == null) {
                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
                    return;
                }
                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
                        + " to stackId=" + stackId + " toTop=" + toTop);
                if (stackId == DOCKED_STACK_ID) {
                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
                            null /* initialBounds */);
                }
                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
                if (result && stackId == DOCKED_STACK_ID) {
                final boolean successful = task.reparent(stackId, toTop,
                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
                if (successful && stackId == DOCKED_STACK_ID) {
                    // If task moved to docked stack - show recents if needed.
                    mWindowManager.showRecentApps(false /* fromHome */);
                }
@@ -10253,22 +10271,23 @@ public class ActivityManagerService extends IActivityManager.Stub
                // TODO: App transition
                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
                // Defer the resume so resume/pausing while moving stacks is dangerous.
                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
                        ANIMATE, true /* deferResume */);
                // Defer the resume until we move all the docked tasks to the fullscreen stack below
                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
                final int size = tasks.size();
                for (int i = 0; i < size; i++) {
                    final int id = tasks.get(i).taskId;
                    if (id == topTask.taskId) {
                        continue;
                    }
                    mStackSupervisor.moveTaskToStackLocked(id,
                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
                    // Defer the resume until after all the tasks have been moved
                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
                }
                // Because we deferred the resume, to avoid conflicts with stack switches while
                // Because we deferred the resume to avoid conflicts with stack switches while
                // resuming, we need to do it after all the tasks are moved.
                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
@@ -10301,12 +10320,20 @@ public class ActivityManagerService extends IActivityManager.Stub
        synchronized (this) {
            long ident = Binder.clearCallingIdentity();
            try {
                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
                if (task == null) {
                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
                    return false;
                }
                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
                        + " to createMode=" + createMode + " toTop=" + toTop);
                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
                        animate, DEFER_RESUME);
                // Defer resuming until we move the home stack to the front below
                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
                        REPARENT_KEEP_STACK_AT_FRONT, animate, DEFER_RESUME,
                        "moveTaskToDockedStack");
                if (moved) {
                    if (moveHomeStackFront) {
                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
@@ -10440,7 +10467,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    stack.positionChildAt(task, position);
                } else {
                    // Reparent to new stack.
                    task.reparent(stackId, position, "positionTaskInStack");
                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
                }
            } finally {
                Binder.restoreCallingIdentity(ident);
+9 −0
Original line number Diff line number Diff line
@@ -797,6 +797,15 @@ final class ActivityRecord implements AppWindowContainerListener {
                    + " is already the parent of r=" + this);
        }

        // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
        //       the stacks in strange states. For now, we should use Task.reparent() to ensure that
        //       the stack is left in an OK state.
        if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
            throw new IllegalArgumentException(reason + ": task=" + newTask
                    + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
                    + " r=" + this + " (" + prevTask.getStackId() + ")");
        }

        // Must reparent first in window manager
        mWindowContainerController.reparent(newTask.getWindowContainerController(), position);

+0 −39
Original line number Diff line number Diff line
@@ -5075,45 +5075,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        moveToFront(reason);
    }

    /**
     * Moves the input activity from its current stack to this one.
     * NOTE: The current task of the activity isn't moved to this stack. Instead a new task is
     * created on this stack which the activity is added to.
     * */
    void moveActivityToStack(ActivityRecord r) {
        final ActivityStack prevStack = r.getStack();
        if (prevStack.mStackId == mStackId) {
            // You are already in the right stack silly...
            return;
        }

        final boolean wasFocused = mStackSupervisor.isFocusedStack(prevStack)
                && (mStackSupervisor.topRunningActivityLocked() == r);
        final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);
        final boolean wasPaused = prevStack.mPausingActivity == r;

        // Create a new task for the activity to be parented in
        final TaskRecord task = createTaskRecord(
                mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
                r.info, r.intent, null, null, true, r.mActivityType);
        // This is a new task, so reparenting it to position 0 will move it to the top
        r.reparent(task, 0 /* position */, "moveActivityToStack");

        // Notify the task actiivties if it was moved to/from a pinned stack
        mStackSupervisor.scheduleReportPictureInPictureModeChangedIfNeeded(task, prevStack);

        // Resume the activity if necessary after it has moved
        moveToFrontAndResumeStateIfNeeded(r, wasFocused, wasResumed, wasPaused,
                "moveActivityToStack");
        if (wasResumed) {
            prevStack.mResumedActivity = null;
        }
        if (wasPaused) {
            prevStack.mPausingActivity = null;
            prevStack.removeTimeoutsForActivityLocked(r);
        }
    }

    public int getStackId() {
        return mStackId;
    }
+74 −168

File changed.

Preview size limit exceeded, changes collapsed.

+13 −8
Original line number Diff line number Diff line
@@ -76,11 +76,16 @@ import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;

import static java.lang.Integer.MAX_VALUE;

import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -1461,9 +1466,9 @@ class ActivityStarter {
                        if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
                            // If we want to launch adjacent and mTargetStack is not the computed
                            // launch stack - move task to top of computed stack.
                            mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,
                                    launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide",
                                    ANIMATE);
                            intentActivity.task.reparent(launchStack.mStackId, ON_TOP,
                                    REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
                                    "launchToSide");
                        } else {
                            // TODO: This should be reevaluated in MW v2.
                            // We choose to move task to front instead of launching it adjacent
@@ -1678,8 +1683,8 @@ class ActivityStarter {
        if (mTargetStack == null) {
            mTargetStack = sourceStack;
        } else if (mTargetStack != sourceStack) {
            mSupervisor.moveTaskToStackLocked(sourceTask.taskId, mTargetStack.mStackId,
                    ON_TOP, FORCE_FOCUS, "launchToSide", !ANIMATE);
            sourceTask.reparent(mTargetStack.mStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
                    !ANIMATE, DEFER_RESUME, "launchToSide");
        }

        final TaskRecord topTask = mTargetStack.topTask();
@@ -1745,9 +1750,9 @@ class ActivityStarter {
            mInTask.updateOverrideConfiguration(mLaunchBounds);
            int stackId = mInTask.getLaunchStackId();
            if (stackId != mInTask.getStackId()) {
                final ActivityStack stack = mSupervisor.moveTaskToStackUncheckedLocked(mInTask,
                        stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront");
                stackId = stack.mStackId;
                mInTask.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
                        DEFER_RESUME, "inTaskToFront");
                stackId = mInTask.getStackId();
            }
            if (StackId.resizeStackWithLaunchBounds(stackId)) {
                mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Loading