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

Commit 18b51c91 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Reuse common transition method used by both legacy and shell

To reduce scattered duplicated code of "isAnimating+inTransition"
when the places have the same condition to check either legacy or
shell transition.

The major fix is in WindowToken, which avoids clearing fixed
rotation too early when FixedRotationTransitionListener receives
onAppTransitionFinished for an activity which is still in transition.
E.g. launch landscape app from portrait home, and then swipe up
before the launch animation is finished. The closing animation should
still show the app in landscape.

Bug: 223397413
Bug: 212570341
Test: atest TransitionTests#testAppTransitionWithRotationChange

Change-Id: Ib954b390137ea11ccc45748b62e7b7d6812dceb7
parent bba05dfe
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -7971,8 +7971,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    boolean isInTransition() {
        return mTransitionController.inTransition(this) // Shell transitions.
                || isAnimating(PARENTS | TRANSITION); // Legacy transitions.
        return inTransitionSelfOrParent();
    }

    /**
+1 −7
Original line number Diff line number Diff line
@@ -74,13 +74,9 @@ import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE
import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
import static com.android.server.wm.Task.TAG_CLEANUP;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainer.POSITION_TOP;

import android.Manifest;
@@ -1925,9 +1921,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        ArrayList<ActivityRecord> readyToStopActivities = null;
        for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
            final ActivityRecord s = mStoppingActivities.get(i);
            final boolean animating = s.isAnimating(TRANSITION | PARENTS,
                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
                    || s.inTransition();
            final boolean animating = s.isInTransition();
            ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
                    + "finishing=%s", s, s.nowVisible, animating, s.finishing);
            if (!animating || mService.mShuttingDown) {
+3 −4
Original line number Diff line number Diff line
@@ -1782,7 +1782,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * rotation transform to it and indicate that the display may be rotated after it is launched.
     */
    void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Rotation int rotation) {
        final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
        final ActivityRecord prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
        if (prevRotatedLaunchingApp == r
                && r.getWindowConfiguration().getRotation() == rotation) {
            // The given launching app and target rotation are the same as the existing ones.
@@ -1791,8 +1791,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        if (prevRotatedLaunchingApp != null
                && prevRotatedLaunchingApp.getWindowConfiguration().getRotation() == rotation
                // It is animating so we can expect there will have a transition callback.
                && (prevRotatedLaunchingApp.isAnimating(TRANSITION | PARENTS)
                        || mTransitionController.inTransition(prevRotatedLaunchingApp))) {
                && (prevRotatedLaunchingApp.isInTransition())) {
            // It may be the case that multiple activities launch consecutively. Because their
            // rotation are the same, the transformed state can be shared to avoid duplicating
            // the heavy operations. This also benefits that the states of multiple activities
@@ -6468,7 +6467,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    // Different tasks won't be in one activity transition animation.
                    return;
                }
                if (task.isAppTransitioning()) {
                if (task.getActivity(ActivityRecord::isInTransition) != null) {
                    return;
                    // Continue to update orientation because the transition of the top rotated
                    // launching activity is done.
+1 −1
Original line number Diff line number Diff line
@@ -2496,7 +2496,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        if (!hasChild()) {
            return false;
        }
        return isExitAnimationRunningSelfOrChild() || inTransition();
        return isExitAnimationRunningSelfOrChild();
    }

    @Override
+16 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -1158,6 +1159,19 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        return getActivity(app -> app.isAnimating(PARENTS | TRANSITION)) != null;
    }

    /**
     * Returns {@code true} if self or the parent container of the window is in transition, e.g.
     * the app or recents transition. This method is only used when legacy and shell transition
     * have the same condition to check the animation state.
     */
    boolean inTransitionSelfOrParent() {
        if (!mTransitionController.isShellTransitionsEnabled()) {
            return isAnimating(PARENTS | TRANSITION,
                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
        }
        return inTransition();
    }

    /**
     * @return Whether our own container running an animation at the moment.
     */
@@ -1180,7 +1194,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        if (!mTransitionController.isShellTransitionsEnabled()) {
            return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES);
        }
        if (mTransitionController.isCollecting(this)) {
        // Only check leaf containers because inTransition() includes parent.
        if (mChildren.isEmpty() && inTransition()) {
            return true;
        }

Loading