diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index e2b707234b11a..d78b3070771d5 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7979,8 +7979,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } boolean isInTransition() { - return mTransitionController.inTransition(this) // Shell transitions. - || isAnimating(PARENTS | TRANSITION); // Legacy transitions. + return inTransitionSelfOrParent(); } /** diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index bd2ce95a814f3..863faa190692c 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -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 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) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 7eeda3f9a695f..2ea6ce53caa29 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -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. diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index d77e9b397ef9c..391077636654c 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2496,7 +2496,7 @@ class TaskFragment extends WindowContainer { if (!hasChild()) { return false; } - return isExitAnimationRunningSelfOrChild() || inTransition(); + return isExitAnimationRunningSelfOrChild(); } @Override diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index b579a9d825683..51adb162e329e 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -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 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 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; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 70499603801cc..02f95348dc790 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -4965,18 +4965,6 @@ class WindowState extends WindowContainer implements WindowManagerP return isAnimating(CHILDREN, ANIMATION_TYPE_WINDOW_ANIMATION); } - /** - * @return {@code true} if self or the parent container of the window is in transition. - * (e.g. The app or recents transition) - */ - boolean inTransitionSelfOrParent() { - if (!mTransitionController.isShellTransitionsEnabled()) { - return isAnimating(PARENTS | TRANSITION, - ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS); - } - return mTransitionController.inTransition(this); - } - private boolean shouldFinishAnimatingExit() { // Exit animation might be applied soon. if (inTransition()) { diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 6c82a791bb6fb..ab72e49f1e4f3 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -24,8 +24,6 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT; -import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; -import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.WINDOW_TOKEN; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -501,7 +499,7 @@ class WindowToken extends WindowContainer { for (int i = mFixedRotationTransformState.mAssociatedTokens.size() - 1; i >= 0; i--) { final ActivityRecord r = mFixedRotationTransformState.mAssociatedTokens.get(i).asActivityRecord(); - if (r != null && r.isAnimating(TRANSITION | PARENTS)) { + if (r != null && r.isInTransition()) { return true; } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 8f5da44212800..a19b19ec6af90 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1617,14 +1617,14 @@ public class DisplayContentTests extends WindowTestsBase { final Task task = app.getTask(); final ActivityRecord app2 = new ActivityBuilder(mWm.mAtmService).setTask(task).build(); mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4); - doReturn(true).when(task).isAppTransitioning(); - // If the task is animating transition, this should be no-op. + doReturn(true).when(app).isInTransition(); + // If the task contains a transition, this should be no-op. mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); assertTrue(app2.hasFixedRotationTransform()); assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp()); - doReturn(false).when(task).isAppTransitioning(); + doReturn(false).when(app).isInTransition(); // Although this notifies app instead of app2 that uses the fixed rotation, app2 should // still finish the transform because there is no more transition event. mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index 84e94ff271c30..ab72a0f726715 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -793,6 +793,10 @@ public class TransitionTests extends WindowTestsBase { assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp()); assertNotNull(mDisplayContent.getAsyncRotationController()); + // The app is still in transition, so the callback should be no-op. + mDisplayContent.mTransitionController.dispatchLegacyAppTransitionFinished(app); + assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp()); + statusBar.setOrientationChanging(true); player.startTransition(); // Non-app windows should not be collected.