From 5a5734bbbaa96e4c2647eaed655ffac128ea3d5f Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 25 Jul 2020 00:37:48 +0800 Subject: [PATCH] Finish fixed rotation after recents moved to top While the task transition is running, its activity is the animation source. If recents animation is triggered and finished before the transition is done, the animation source will be notified that the transition is finished. At this timing, the rotated activity is still the top activity. Since it is moving to back, the display orientation is unnecessary to be updated for the intermediate state. That avoids flickering by not committing visibility due to configuration change. Fixes: 160239226 Test: atest RecentsAnimationControllerTest# \ testKeepFixedRotationWhenMovingRecentsToTop Change-Id: I5c5c12338b9bc0cd8a99655a843a33d8729f8892 Merged-In: I5c5c12338b9bc0cd8a99655a843a33d8729f8892 --- .../com/android/server/wm/DisplayContent.java | 21 ++++++++++++-- .../server/wm/RecentsAnimationController.java | 8 +++-- .../server/wm/DisplayContentTests.java | 2 +- .../wm/RecentsAnimationControllerTest.java | 29 +++++++++++++++++-- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index fcbc7564cabbd..ed1f221576d9c 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5642,6 +5642,9 @@ class DisplayContent extends WindowContainer= 0; i--) { final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { @@ -742,8 +747,7 @@ public class RecentsAnimationController implements DeathRecipient { mTargetActivityRecord.token); } } - mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation( - reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION /* moveRecentsToBack */); + mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(); // Notify that the animation has ended if (mStatusBar != null) { 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 cbccfb3725e9b..dc838f1bb2889 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1282,7 +1282,7 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(displayRotation.updateRotationUnchecked(false)); // Rotation can be updated if the recents animation is finished. - mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(false); + mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(); assertTrue(displayRotation.updateRotationUnchecked(false)); // Rotation can be updated if the recents animation is animating but it is not on top, e.g. diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index 8e85e7b96d1f0..f2771175b5237 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -363,12 +363,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertFalse(homeActivity.hasFixedRotationTransform()); } - @Test - public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() { + private ActivityRecord prepareFixedRotationLaunchingAppWithRecentsAnim() { final ActivityRecord homeActivity = createHomeActivity(); homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); final ActivityRecord activity = createActivityRecord(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + // Add a window so it can be animated by the recents. + final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win"); + activity.addWindow(win); // Assume an activity is launching to different rotation. mDefaultDisplay.setFixedRotationLaunchingApp(activity, (mDefaultDisplay.getRotation() + 1) % 4); @@ -379,6 +381,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { // Before the transition is done, the recents animation is triggered. initializeRecentsAnimationController(mController, homeActivity); assertFalse(homeActivity.hasFixedRotationTransform()); + assertTrue(mController.isAnimatingTask(activity.getTask())); + + return activity; + } + + @Test + public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() { + final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim(); // Simulate giving up the swipe up gesture to keep the original activity as top. mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); @@ -387,6 +397,21 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp()); } + @Test + public void testKeepFixedRotationWhenMovingRecentsToTop() { + final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim(); + // Assume a transition animation has started running before recents animation. Then the + // activity will receive onAnimationFinished that notifies app transition finished when + // removing the recents animation of task. + activity.getTask().getAnimationSources().add(activity); + + // Simulate swiping to home/recents before the transition is done. + mController.cleanupAnimation(REORDER_MOVE_TO_TOP); + // The rotation transform should be preserved. In real case, it will be cleared by the next + // move-to-top transition. + assertTrue(activity.hasFixedRotationTransform()); + } + @Test public void testWallpaperHasFixedRotationApplied() { mWm.setRecentsAnimationController(mController);