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

Commit 3155d334 authored by Winson Chung's avatar Winson Chung Committed by android-build-merger
Browse files

Merge "Generalize the recents animation to work with non-home activity." into pi-dev am: 1b5a0deb

am: d5b18482

Change-Id: Icd2c2c89cd589e6a87b3d96974f91140bd3e5b7e
parents 108ebd0c d5b18482
Loading
Loading
Loading
Loading
+26 −33
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.am;

import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -44,7 +43,6 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.IntArray;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -702,57 +700,52 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
    }

    /**
     * @return the stack currently above the home stack.  Can be null if there is no home stack, or
     *         the home stack is already on top.
     * @return the stack currently above the {@param stack}.  Can be null if the {@param stack} is
     *         already top-most.
     */
    ActivityStack getStackAboveHome() {
        if (mHomeStack == null) {
            // Skip if there is no home stack
            return null;
        }

        final int stackIndex = mStacks.indexOf(mHomeStack) + 1;
    ActivityStack getStackAbove(ActivityStack stack) {
        final int stackIndex = mStacks.indexOf(stack) + 1;
        return (stackIndex < mStacks.size()) ? mStacks.get(stackIndex) : null;
    }

    /**
     * Adjusts the home stack behind the last visible stack in the display if necessary. Generally
     * used in conjunction with {@link #moveHomeStackBehindStack}.
     * Adjusts the {@param stack} behind the last visible stack in the display if necessary.
     * Generally used in conjunction with {@link #moveStackBehindStack}.
     */
    void moveHomeStackBehindBottomMostVisibleStack() {
        if (mHomeStack == null || mHomeStack.shouldBeVisible(null)) {
            // Skip if there is no home stack, or if it is already visible
    void moveStackBehindBottomMostVisibleStack(ActivityStack stack) {
        if (stack.shouldBeVisible(null)) {
            // Skip if the stack is already visible
            return;
        }

        // Move the home stack to the bottom to not affect the following visibility checks
        positionChildAtBottom(mHomeStack);
        // Move the stack to the bottom to not affect the following visibility checks
        positionChildAtBottom(stack);

        // Find the next position where the homes stack should be placed
        // Find the next position where the stack should be placed
        final int numStacks = mStacks.size();
        for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
            final ActivityStack stack = mStacks.get(stackNdx);
            if (stack == mHomeStack) {
            final ActivityStack s = mStacks.get(stackNdx);
            if (s == stack) {
                continue;
            }
            final int winMode = stack.getWindowingMode();
            final int winMode = s.getWindowingMode();
            final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN ||
                    winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
            if (stack.shouldBeVisible(null) && isValidWindowingMode) {
                // Move the home stack to behind this stack
                positionChildAt(mHomeStack, Math.max(0, stackNdx - 1));
            if (s.shouldBeVisible(null) && isValidWindowingMode) {
                // Move the provided stack to behind this stack
                positionChildAt(stack, Math.max(0, stackNdx - 1));
                break;
            }
        }
    }

    /**
     * Moves the home stack behind the given {@param stack} if possible. If {@param stack} is not
     * currently in the display, then then the home stack is moved to the back. Generally used in
     * conjunction with {@link #moveHomeStackBehindBottomMostVisibleStack}.
     * Moves the {@param stack} behind the given {@param behindStack} if possible. If
     * {@param behindStack} is not currently in the display, then then the stack is moved to the
     * back. Generally used in conjunction with {@link #moveStackBehindBottomMostVisibleStack}.
     */
    void moveHomeStackBehindStack(ActivityStack behindStack) {
        if (behindStack == null || behindStack == mHomeStack) {
    void moveStackBehindStack(ActivityStack stack, ActivityStack behindStack) {
        if (behindStack == null || behindStack == stack) {
            return;
        }

@@ -760,11 +753,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        // list, so we need to adjust the insertion index to account for the removed index
        // TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the
        //       position internally
        final int homeStackIndex = mStacks.indexOf(mHomeStack);
        final int stackIndex = mStacks.indexOf(stack);
        final int behindStackIndex = mStacks.indexOf(behindStack);
        final int insertIndex = homeStackIndex <= behindStackIndex
        final int insertIndex = stackIndex <= behindStackIndex
                ? behindStackIndex - 1 : behindStackIndex;
        positionChildAt(mHomeStack, Math.max(0, insertIndex));
        positionChildAt(stack, Math.max(0, insertIndex));
    }

    boolean isSleeping() {
+5 −4
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -205,8 +206,8 @@ import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -5249,8 +5250,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        try {
            synchronized (this) {
                mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition
                        ? REORDER_MOVE_HOME_TO_ORIGINAL_POSITION
                        : REORDER_KEEP_HOME_IN_PLACE);
                        ? REORDER_MOVE_TO_ORIGINAL_POSITION
                        : REORDER_KEEP_IN_PLACE);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
+71 −55
Original line number Diff line number Diff line
@@ -18,19 +18,20 @@ package com.android.server.am;

import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.WindowManager.TRANSIT_NONE;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_TOP;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;

import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Handler;
import android.os.RemoteException;
import android.os.Trace;
import android.util.Slog;
@@ -51,16 +52,20 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
    private final ActivityStartController mActivityStartController;
    private final WindowManagerService mWindowManager;
    private final UserController mUserController;
    private final ActivityDisplay mDefaultDisplay;
    private final int mCallingPid;

    // The stack to restore the home stack behind when the animation is finished
    private ActivityStack mRestoreHomeBehindStack;
    private int mTargetActivityType;

    // The stack to restore the target stack behind when the animation is finished
    private ActivityStack mRestoreTargetBehindStack;

    RecentsAnimation(ActivityManagerService am, ActivityStackSupervisor stackSupervisor,
            ActivityStartController activityStartController, WindowManagerService wm,
            UserController userController, int callingPid) {
        mService = am;
        mStackSupervisor = stackSupervisor;
        mDefaultDisplay = stackSupervisor.getDefaultDisplay();
        mActivityStartController = activityStartController;
        mWindowManager = wm;
        mUserController = userController;
@@ -76,23 +81,31 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
            return;
        }

        // If the existing home activity is already on top, then cancel
        ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
        final boolean hasExistingHomeActivity = homeActivity != null;
        if (hasExistingHomeActivity) {
            final ActivityDisplay display = homeActivity.getDisplay();
            mRestoreHomeBehindStack = display.getStackAboveHome();
            if (mRestoreHomeBehindStack == null) {
        // If the activity is associated with the recents stack, then try and get that first
        mTargetActivityType = intent.getComponent() != null
                && recentsComponent.equals(intent.getComponent())
                        ? ACTIVITY_TYPE_RECENTS
                        : ACTIVITY_TYPE_HOME;
        final ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                mTargetActivityType);
        ActivityRecord targetActivity = targetStack != null
                ? targetStack.getTopActivity()
                : null;
        final boolean hasExistingActivity = targetActivity != null;
        if (hasExistingActivity) {
            final ActivityDisplay display = targetActivity.getDisplay();
            mRestoreTargetBehindStack = display.getStackAbove(targetStack);
            if (mRestoreTargetBehindStack == null) {
                notifyAnimationCancelBeforeStart(recentsAnimationRunner);
                return;
            }
        }

        // Send launch hint if we are actually launching home. If it's already visible (shouldn't
        // happen in general) we don't need to send it.
        if (homeActivity == null || !homeActivity.visible) {
        // Send launch hint if we are actually launching the target. If it's already visible
        // (shouldn't happen in general) we don't need to send it.
        if (targetActivity == null || !targetActivity.visible) {
            mStackSupervisor.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */,
                    homeActivity);
                    targetActivity);
        }

        mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
@@ -102,48 +115,49 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
        mWindowManager.deferSurfaceLayout();
        try {
            final ActivityDisplay display;
            if (hasExistingHomeActivity) {
                // Move the home activity into place for the animation if it is not already top most
                display = homeActivity.getDisplay();
                display.moveHomeStackBehindBottomMostVisibleStack();
            if (hasExistingActivity) {
                // Move the recents activity into place for the animation if it is not top most
                display = targetActivity.getDisplay();
                display.moveStackBehindBottomMostVisibleStack(targetStack);
            } else {
                // No home activity
                final ActivityOptions opts = ActivityOptions.makeBasic();
                opts.setLaunchActivityType(ACTIVITY_TYPE_HOME);
                opts.setAvoidMoveToFront();
                // No recents activity
                ActivityOptions options = ActivityOptions.makeBasic();
                options.setLaunchActivityType(mTargetActivityType);
                options.setAvoidMoveToFront();
                intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);

                mActivityStartController
                        .obtainStarter(intent, "startRecentsActivity_noHomeActivity")
                        .obtainStarter(intent, "startRecentsActivity_noTargetActivity")
                        .setCallingUid(recentsUid)
                        .setCallingPackage(recentsComponent.getPackageName())
                        .setActivityOptions(SafeActivityOptions.fromBundle(opts.toBundle()))
                        .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
                        .setMayWait(mUserController.getCurrentUserId())
                        .execute();
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);

                homeActivity = mStackSupervisor.getHomeActivity();
                display = homeActivity.getDisplay();
                targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                        mTargetActivityType).getTopActivity();
                display = targetActivity.getDisplay();

                // TODO: Maybe wait for app to draw in this particular case?
            }

            // Mark the home activity as launch-behind to bump its visibility for the
            // Mark the target activity as launch-behind to bump its visibility for the
            // duration of the gesture that is driven by the recents component
            homeActivity.mLaunchTaskBehind = true;
            targetActivity.mLaunchTaskBehind = true;

            // Fetch all the surface controls and pass them to the client to get the animation
            // started
            mWindowManager.cancelRecentsAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
            mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this,
                    display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
            mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
            mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
                    this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());

            // If we updated the launch-behind state, update the visibility of the activities after
            // we fetch the visible tasks to be controlled by the animation
            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);

            mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT,
                    homeActivity);
                    targetActivity);
        } finally {
            mWindowManager.continueSurfaceLayout();
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
@@ -155,9 +169,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
        synchronized (mService) {
            if (mWindowManager.getRecentsAnimationController() == null) return;

            // Just to be sure end the launch hint in case home was never launched. However, if
            // we're keeping home and making it visible, we can leave it on.
            if (reorderMode != REORDER_KEEP_HOME_IN_PLACE) {
            // Just to be sure end the launch hint in case the target activity was never launched.
            // However, if we're keeping the activity and making it visible, we can leave it on.
            if (reorderMode != REORDER_KEEP_IN_PLACE) {
                mStackSupervisor.sendPowerHintForLaunchEndIfNeeded();
            }

@@ -170,26 +184,27 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
                try {
                    mWindowManager.cleanupRecentsAnimation(reorderMode);

                    final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
                    if (homeActivity == null) {
                    final ActivityStack targetStack = mDefaultDisplay.getStack(
                            WINDOWING_MODE_UNDEFINED, mTargetActivityType);
                    final ActivityRecord targetActivity = targetStack.getTopActivity();
                    if (targetActivity == null) {
                        return;
                    }

                    // Restore the launched-behind state
                    homeActivity.mLaunchTaskBehind = false;

                    if (reorderMode == REORDER_MOVE_HOME_TO_TOP) {
                        // Bring the home stack to the front
                        final ActivityStack homeStack = homeActivity.getStack();
                        mStackSupervisor.mNoAnimActivities.add(homeActivity);
                        homeStack.moveToFront("RecentsAnimation.onAnimationFinished()");
                    } else if (reorderMode == REORDER_MOVE_HOME_TO_ORIGINAL_POSITION){
                        // Restore the home stack to its previous position
                        final ActivityDisplay display = homeActivity.getDisplay();
                        display.moveHomeStackBehindStack(mRestoreHomeBehindStack);
                    targetActivity.mLaunchTaskBehind = false;

                    if (reorderMode == REORDER_MOVE_TO_TOP) {
                        // Bring the target stack to the front
                        mStackSupervisor.mNoAnimActivities.add(targetActivity);
                        targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
                    } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){
                        // Restore the target stack to its previous position
                        final ActivityDisplay display = targetActivity.getDisplay();
                        display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack);
                    } else {
                        // Keep home stack in place, nothing changes, so ignore the transition logic
                        // below
                        // Keep target stack in place, nothing changes, so ignore the transition
                        // logic below
                        return;
                    }

@@ -202,8 +217,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
                    mWindowManager.executeAppTransition();

                    // After reordering the stacks, reset the minimized state. At this point, either
                    // home is now top-most and we will stay minimized (if in split-screen), or we
                    // will have returned to the app, and the minimized state should be reset
                    // the target activity is now top-most and we will stay minimized (if in
                    // split-screen), or we will have returned to the app, and the minimized state
                    // should be reset
                    mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */);
                } finally {
                    mWindowManager.continueSurfaceLayout();
+43 −40

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;

import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
@@ -620,7 +620,7 @@ class WallpaperController {
            // If there was a recents animation in progress, cancel that animation
            if (mService.getRecentsAnimationController() != null) {
                mService.getRecentsAnimationController().cancelAnimation(
                        REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
                        REORDER_MOVE_TO_ORIGINAL_POSITION);
            }
            return true;
        }
Loading