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

Commit 0d46519b authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Louis Chang
Browse files

Reuse stack as task for single task stacks (90/n)

Stacks and tasks are now the same object instance, so for cases were we
have a 1to1 relationship between the stack and task, just go ahead and
use one stack/task object instead of having the extra level.
- Helps us tryout the task hierarchy at a different depth than 2
to see what bugs needs to be fixed.
- Makes it easier to switch "tiles" into the hierarchy.

Bug: 80414790
Test: Existing tests pass.
Change-Id: I9796a149f5ca689b7000819085d4ed8e156b618c
parent 9e5b4507
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1163,10 +1163,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // An activity is considered to be in multi-window mode if its task isn't fullscreen.
        final boolean inMultiWindowMode = inMultiWindowMode();
        if (inMultiWindowMode != mLastReportedMultiWindowMode) {
            if (!inMultiWindowMode && mLastReportedPictureInPictureMode) {
                updatePictureInPictureMode(null, false);
            } else {
                mLastReportedMultiWindowMode = inMultiWindowMode;
                scheduleMultiWindowModeChanged(getConfiguration());
            }
        }
    }

    private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
        try {
+67 −56
Original line number Diff line number Diff line
@@ -658,8 +658,8 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
    }

    @Override
    public void resolveOverrideConfiguration(Configuration newParentConfig) {
        super.resolveOverrideConfiguration(newParentConfig);
    public void resolveTileOverrideConfiguration(Configuration newParentConfig) {
        super.resolveTileOverrideConfiguration(newParentConfig);
        if (mTile != null) {
            // If this is a virtual child of a tile, simulate the parent-child relationship
            mTile.updateResolvedConfig(getResolvedOverrideConfiguration());
@@ -1118,20 +1118,15 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
        return r.getTask().mTaskId != taskId && r.appToken != notTop && r.canBeTopRunning();
    }

    ActivityRecord isInStackLocked(IBinder token) {
        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
        return isInStackLocked(r);
    }

    ActivityRecord isInStackLocked(ActivityRecord r) {
        if (r == null) {
            return null;
        }
        final Task task = r.getTask();
        final ActivityStack stack = r.getRootTask();
        if (stack != null && task.mChildren.contains(r) && mChildren.contains(task)) {
            if (stack != this) Slog.w(TAG,
                    "Illegal state! task does not point to stack it is in.");
        final Task task = r.getRootTask();
        if (task != null && r.isDescendantOf(task)) {
            if (task != this) Slog.w(TAG, "Illegal state! task does not point to stack it is in. "
                    + "stack=" + this + " task=" + task + " r=" + r
                    + " callers=" + Debug.getCallers(15, "\n"));
            return r;
        }
        return null;
@@ -1207,7 +1202,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
        }

        getDisplay().positionStackAtBottom(this, reason);
        if (task != null) {
        if (task != null && task != this) {
            positionChildAtBottom(task);
        }

@@ -1251,12 +1246,12 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
        mCurrentUser = userId;

        super.switchUser(userId);
        forAllTasks((t) -> {
            if (t.showToCurrentUser()) {
        forAllLeafTasks((t) -> {
            if (t.showToCurrentUser() && t != this) {
                mChildren.remove(t);
                mChildren.add(t);
            }
        }, true /* traverseTopToBottom */, this);
        }, true /* traverseTopToBottom */);
    }

    void minimalResumeActivityLocked(ActivityRecord r) {
@@ -2450,16 +2445,16 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
            boolean newTask, boolean keepCurTransition, ActivityOptions options) {
        Task rTask = r.getTask();
        final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
        final boolean hasTask = hasChild(rTask);
        final boolean isOrhasTask = rTask == this || hasChild(rTask);
        // mLaunchTaskBehind tasks get placed at the back of the task stack.
        if (!r.mLaunchTaskBehind && allowMoveToFront && (!hasTask || newTask)) {
        if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            positionChildAtTop(rTask);
        }
        Task task = null;
        if (!newTask && hasTask) {
        if (!newTask && isOrhasTask) {
            final ActivityRecord occludingActivity = getActivity(
                    (ar) -> !ar.finishing && ar.occludesParent(), true, rTask);
            if (occludingActivity != null) {
@@ -2717,7 +2712,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
    void finishVoiceTask(IVoiceInteractionSession session) {
        final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::finishIfVoiceTask,
                PooledLambda.__(Task.class), session.asBinder());
        forAllTasks(c, true /* traverseTopToBottom */, this);
        forAllLeafTasks(c, true /* traverseTopToBottom */);
        c.recycle();
    }

@@ -2818,8 +2813,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
            return false;
        }
        final Task task = srec.getTask();

        if (!mChildren.contains(task) || !task.hasChild(srec)) {
        if (!srec.isDescendantOf(this)) {
            return false;
        }

@@ -2932,20 +2926,20 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
        getDisplay().mDisplayContent.prepareAppTransition(transit, false);
    }

    final void moveTaskToFrontLocked(Task tr, boolean noAnimation, ActivityOptions options,
    final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options,
            AppTimeTracker timeTracker, String reason) {
        moveTaskToFrontLocked(tr, noAnimation, options, timeTracker, !DEFER_RESUME, reason);
        moveTaskToFront(tr, noAnimation, options, timeTracker, !DEFER_RESUME, reason);
    }

    final void moveTaskToFrontLocked(Task tr, boolean noAnimation, ActivityOptions options,
    final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options,
            AppTimeTracker timeTracker, boolean deferResume, String reason) {
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);

        final ActivityStack topStack = getDisplay().getTopStack();
        final ActivityRecord topActivity = topStack != null ? topStack.getTopNonFinishingActivity() : null;
        final int numTasks = getChildCount();
        final int index = mChildren.indexOf(tr);
        if (numTasks == 0 || index < 0)  {
        final ActivityRecord topActivity = topStack != null
                ? topStack.getTopNonFinishingActivity() : null;

        if (tr != this && !tr.isDescendantOf(this)) {
            // nothing to do!
            if (noAnimation) {
                ActivityOptions.abort(options);
@@ -3113,7 +3107,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
            final PooledConsumer c = PooledLambda.obtainConsumer(
                    ActivityStack::processTaskResizeBounds, PooledLambda.__(Task.class),
                    taskBounds, tempTaskInsetBounds);
            forAllTasks(c, true /* traverseTopToBottom */, this);
            forAllLeafTasks(c, true /* traverseTopToBottom */);
            c.recycle();

            setBounds(bounds);
@@ -3150,7 +3144,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {

        final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskBounds,
                PooledLambda.__(Task.class), bounds);
        forAllTasks(c, true /* traverseTopToBottom */, this);
        forAllLeafTasks(c, true /* traverseTopToBottom */);
        c.recycle();
    }

@@ -3166,7 +3160,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {

        final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskDisplayedBounds,
                PooledLambda.__(Task.class), bounds);
        forAllTasks(c, true /* traverseTopToBottom */, this);
        forAllLeafTasks(c, true /* traverseTopToBottom */);
        c.recycle();
    }

@@ -3262,7 +3256,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
            return false;
        }
        final String prefix = "    ";
        forAllTasks((task) -> {
        forAllLeafTasks((task) -> {
            if (needSep) {
                pw.println("");
            }
@@ -3280,7 +3274,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
                    false /* traverseTopToBottom */);
            dumpHistoryList(fd, pw, activities, prefix, "Hist", true, !dumpAll, dumpClient,
                    dumpPackage, false, null, task);
        }, true /* traverseTopToBottom */, this);
        }, true /* traverseTopToBottom */);
        return true;
    }

@@ -3331,19 +3325,33 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
        }
    }

    Task createTask(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
        return createTask(taskId, info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
    Task reuseOrCreateTask(ActivityInfo info, Intent intent, boolean toTop) {
        return reuseOrCreateTask(info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
                toTop, null /*activity*/, null /*source*/, null /*options*/);
    }

    Task createTask(int taskId, ActivityInfo info, Intent intent,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            boolean toTop, ActivityRecord activity, ActivityRecord source,
            ActivityOptions options) {
        final Task task = Task.create(
    // TODO: Can be removed once we change callpoints creating stacks to be creating tasks.
    /** Either returns this current task to be re-used or creates a new child task. */
    Task reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession,
            IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity,
            ActivityRecord source, ActivityOptions options) {

        Task task;
        if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) {
            // This stack will only contain one task, so just return itself since all stacks ara now
            // tasks and all tasks are now stacks.
            task = reuseAsLeafTask(voiceSession, voiceInteractor, info, activity);
        } else {
            // Create child task since this stack can contain multiple tasks.
            final int taskId = activity != null
                    ? mStackSupervisor.getNextTaskIdForUser(activity.mUserId)
                    : mStackSupervisor.getNextTaskIdForUser();
            task = Task.create(
                    mAtmService, taskId, info, intent, voiceSession, voiceInteractor, this);

            // add the task to stack first, mTaskPositioner might need the stack association
            addChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
        }

        int displayId = getDisplayId();
        if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
        final boolean isLockscreenShown = mAtmService.mStackSupervisor.getKeyguardController()
@@ -3353,6 +3361,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
                && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
            task.setBounds(getRequestedOverrideBounds());
        }

        return task;
    }

@@ -3559,10 +3568,6 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
                    "Can't exit pinned mode if it's not pinned already.");
        }

        if (mChildren.size() != 1) {
            throw new RuntimeException("There should be only one task in a pinned stack.");
        }

        // give pinned stack a chance to save current bounds, this should happen before reparent.
        final ActivityRecord top = topRunningNonOverlayTaskActivity();
        if (top != null && top.isVisible()) {
@@ -3592,12 +3597,12 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
        final PooledConsumer c = PooledLambda.obtainConsumer(
                ActivityStackSupervisor::updatePictureInPictureMode, mStackSupervisor,
                PooledLambda.__(Task.class), targetStackBounds, forceUpdate);
        forAllTasks(c, true /* traverseTopToBottom */, this);
        forAllLeafTasks(c, true /* traverseTopToBottom */);
        c.recycle();
    }

    void prepareFreezingTaskBounds() {
        forAllTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */, this);
        forAllLeafTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */);
    }

    /**
@@ -3629,7 +3634,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
            final PooledConsumer c = PooledLambda.obtainConsumer(Task::alignToAdjustedBounds,
                    PooledLambda.__(Task.class), adjusted ? mAdjustedBounds : getRawBounds(),
                    insetBounds, alignBottom);
            forAllTasks(c, true /* traverseTopToBottom */, this);
            forAllLeafTasks(c, true /* traverseTopToBottom */);
            c.recycle();
        }

@@ -3902,6 +3907,12 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
            return;
        }

        if (child == this) {
            // TODO: Fix call-points
            moveToFront("positionChildAtTop");
            return;
        }

        positionChildAt(POSITION_TOP, child, true /* includingParents */);
        child.updateTaskMovement(true);

@@ -4316,19 +4327,19 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
     * to the list of to be drawn windows the service is waiting for.
     */
    void beginImeAdjustAnimation() {
        forAllTasks((t) -> {
        forAllLeafTasks((t) -> {
            if (t.hasContentToDisplay()) {
                t.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
                t.setWaitingForDrawnIfResizingChanged();
            }
        }, true /* traverseTopToBottom */, this);
        }, true /* traverseTopToBottom */);
    }

    /** Resets the resizing state of all windows. */
    void endImeAdjustAnimation() {
        forAllTasks((t) -> {
        forAllLeafTasks((t) -> {
            t.setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
        }, true /* traverseTopToBottom */, this);
        }, true /* traverseTopToBottom */);
    }

    private int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
@@ -4730,7 +4741,7 @@ class ActivityStack extends Task implements BoundsAnimationTarget {
    /** Called immediately prior to resizing the tasks at the end of the pinned stack animation. */
    void onPipAnimationEndResize() {
        mBoundsAnimating = false;
        forAllTasks(Task::clearPreserveNonFloatingState, false /* traverseTopToBottom */, this);
        forAllLeafTasks(Task::clearPreserveNonFloatingState, false /* traverseTopToBottom */);
        mWmService.requestTraversal();
    }

+27 −5
Original line number Diff line number Diff line
@@ -419,14 +419,29 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
            mTopTask = fromStack.getTopMostTask();

            final PooledConsumer c = PooledLambda.obtainConsumer(
                    MoveTaskToFullscreenHelper::processTask, this, PooledLambda.__(Task.class));
            fromStack.forAllTasks(c, false /* traverseTopToBottom */, fromStack);
                    MoveTaskToFullscreenHelper::processLeafTask, this, PooledLambda.__(Task.class));
            fromStack.forAllLeafTasks(c, false /* traverseTopToBottom */);
            c.recycle();
            mToDisplay = null;
            mTopTask = null;
        }

        private void processTask(Task task) {
        private void processLeafTask(Task task) {
            // This is a one level task that we don't need to create stack for reparenting to.
            if (task.isRootTask() && DisplayContent.alwaysCreateStack(WINDOWING_MODE_FULLSCREEN,
                    task.getActivityType())) {
                final ActivityStack stack = (ActivityStack) task;
                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
                if (mToDisplay.getDisplayId() != stack.getDisplayId()) {
                    mToDisplay.moveStackToDisplay(stack, mOnTop);
                } else if (mOnTop) {
                    mToDisplay.positionStackAtTop(stack, false /* includingParents */);
                } else {
                    mToDisplay.positionStackAtBottom(stack);
                }
                return;
            }

            final ActivityStack toStack = mToDisplay.getOrCreateStack(
                    null, mTmpOptions, task, task.getActivityType(), mOnTop);

@@ -1443,7 +1458,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
        }

        final ActivityRecord r = task.getTopNonFinishingActivity();
        currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
        currentStack.moveTaskToFront(task, false /* noAnimation */, options,
                r == null ? null : r.appTimeTracker, reason);

        if (DEBUG_STACK) Slog.d(TAG_STACK,
@@ -1742,7 +1757,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
        } else {
            final PooledConsumer c = PooledLambda.obtainConsumer(
                    ActivityStackSupervisor::processRemoveTask, this, PooledLambda.__(Task.class));
            stack.forAllTasks(c, true /* traverseTopToBottom */, stack);
            stack.forAllLeafTasks(c, true /* traverseTopToBottom */);
            c.recycle();
        }
    }
@@ -2755,6 +2770,10 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
                deferUpdateRecentsHomeStackBounds();
                // TODO(multi-display): currently recents animation only support default display.
                mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
                // TODO(task-hierarchy): Remove when tiles are in hierarchy.
                // Unset launching windowing mode to prevent creating split-screen-primary stack
                // in RWC#anyTaskForId() below.
                activityOptions.setLaunchWindowingMode(WINDOWING_MODE_UNDEFINED);
            }

            task = mRootWindowContainer.anyTaskForId(taskId,
@@ -2764,6 +2783,9 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
                mWindowManager.executeAppTransition();
                throw new IllegalArgumentException(
                        "startActivityFromRecents: Task " + taskId + " not found.");
            } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                    && task.getWindowingMode() != windowingMode) {
                mService.moveTaskToSplitScreenPrimaryTile(task, true /* toTop */);
            }

            if (windowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+2 −3
Original line number Diff line number Diff line
@@ -2366,7 +2366,7 @@ class ActivityStarter {
                    // task on top there.
                    // Defer resuming the top activity while moving task to top, since the
                    // current task-top activity may not be the activity that should be resumed.
                    mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
                    mTargetStack.moveTaskToFront(intentTask, mNoAnimation, mOptions,
                            mStartActivity.appTimeTracker, DEFER_RESUME,
                            "bringingFoundTaskToFront");
                    mMovedToFront = !isSplitScreenTopStack;
@@ -2396,8 +2396,7 @@ class ActivityStarter {

    private void setNewTask(Task taskToAffiliate) {
        final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
        final Task task = mTargetStack.createTask(
                mSupervisor.getNextTaskIdForUser(mStartActivity.mUserId),
        final Task task = mTargetStack.reuseOrCreateTask(
                mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
+12 −4
Original line number Diff line number Diff line
@@ -2760,9 +2760,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
                    + " non-standard task " + taskId + " to split-screen windowing mode");
        }
        if (!task.supportsSplitScreenWindowingMode()) {
            return false;
        }

        final int prevMode = task.getWindowingMode();
        final ActivityStack stack = task.getStack();
        moveTaskToSplitScreenPrimaryTile(task, toTop);
        return prevMode != task.getWindowingMode();
    }

    void moveTaskToSplitScreenPrimaryTile(Task task, boolean toTop) {
        ActivityStack stack = task.getStack();
        TaskTile tile = null;
        for (int i = stack.getDisplay().getStackCount() - 1; i >= 0; --i) {
            tile = stack.getDisplay().getStackAt(i).asTile();
@@ -2776,7 +2784,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        WindowContainerTransaction wct = new WindowContainerTransaction();
        wct.reparent(stack.mRemoteToken, tile.mRemoteToken, toTop);
        mTaskOrganizerController.applyContainerTransaction(wct, null);
        return prevMode != task.getWindowingMode();
    }

    /**
@@ -3247,8 +3254,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                }

                final ActivityStack stack = r.getRootTask();
                final Task task = stack.createTask(
                        mStackSupervisor.getNextTaskIdForUser(r.mUserId), ainfo, intent, !ON_TOP);
                final Task task = stack.getDisplay().createStack(stack.getWindowingMode(),
                        stack.getActivityType(), !ON_TOP, ainfo, intent);

                if (!mRecentTasks.addToBottom(task)) {
                    // The app has too many tasks already and we can't add any more
                    stack.removeChild(task, "addAppTask");
Loading