summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java5
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java18
4 files changed, 46 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 971bebd8c486..225a6ea20f3d 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -442,7 +442,9 @@ public class DisplayRotation {
return false;
}
- if (mDisplayContent.mFixedRotationTransitionListener
+ final RecentsAnimationController recentsAnimController =
+ mService.getRecentsAnimationController();
+ if (recentsAnimController != null && mDisplayContent.mFixedRotationTransitionListener
.isTopFixedOrientationRecentsAnimating()
// If screen is off or the device is going to sleep, then still allow to update.
&& mService.mPolicy.okToAnimate(false /* ignoreScreenOn */)) {
@@ -450,6 +452,7 @@ public class DisplayRotation {
// In order to ignore its requested orientation to avoid a sensor led rotation (e.g
// user rotating the device while the recents animation is running), we ignore
// rotation update while the animation is running.
+ recentsAnimController.setCheckRotationAfterCleanup();
return false;
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index ba85c9800e56..03ff06c9d7f1 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -123,6 +123,7 @@ public class RecentsAnimationController implements DeathRecipient {
private final int mDisplayId;
private boolean mWillFinishToHome = false;
private final Runnable mFailsafeRunnable = this::onFailsafe;
+ private Runnable mCheckRotationAfterCleanup;
// The recents component app token that is shown behind the visibile tasks
private ActivityRecord mTargetActivityRecord;
@@ -921,6 +922,24 @@ public class RecentsAnimationController implements DeathRecipient {
}
/**
+ * If the display rotation change is ignored while recents animation is running, make sure that
+ * the pending rotation change will be applied after the animation finishes.
+ */
+ void setCheckRotationAfterCleanup() {
+ if (mCheckRotationAfterCleanup != null) return;
+ mCheckRotationAfterCleanup = () -> {
+ synchronized (mService.mGlobalLock) {
+ if (mDisplayContent.getDisplayRotation()
+ .updateRotationAndSendNewConfigIfChanged()) {
+ if (mTargetActivityRecord != null) {
+ mTargetActivityRecord.finishFixedRotationTransform();
+ }
+ }
+ }
+ };
+ }
+
+ /**
* @return Whether we should defer the cancel from a root task order change until the next app
* transition.
*/
@@ -1007,6 +1026,10 @@ public class RecentsAnimationController implements DeathRecipient {
if (mStatusBar != null) {
mStatusBar.onRecentsAnimationStateChanged(false /* running */);
}
+ if (mCheckRotationAfterCleanup != null) {
+ mService.mH.post(mCheckRotationAfterCleanup);
+ mCheckRotationAfterCleanup = null;
+ }
}
void scheduleFailsafe() {
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 e3402177140d..24bbf4682157 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1562,6 +1562,7 @@ public class DisplayContentTests extends WindowTestsBase {
final ActivityRecord activity = createActivityRecord(mDisplayContent);
final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent);
recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+ doReturn(mock(RecentsAnimationController.class)).when(mWm).getRecentsAnimationController();
// Do not rotate if the recents animation is animating on top.
mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity);
@@ -2513,7 +2514,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
}
- private static int getRotatedOrientation(DisplayContent dc) {
+ static int getRotatedOrientation(DisplayContent dc) {
return dc.mBaseDisplayWidth > dc.mBaseDisplayHeight
? SCREEN_ORIENTATION_PORTRAIT
: SCREEN_ORIENTATION_LANDSCAPE;
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 d88fbee6ae13..a680cba8b266 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -41,8 +41,8 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
@@ -439,6 +439,22 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
@Test
+ public void testCheckRotationAfterCleanup() {
+ mWm.setRecentsAnimationController(mController);
+ spyOn(mDisplayContent.mFixedRotationTransitionListener);
+ doReturn(true).when(mDisplayContent.mFixedRotationTransitionListener)
+ .isTopFixedOrientationRecentsAnimating();
+ // Rotation update is skipped while the recents animation is running.
+ assertFalse(mDisplayContent.getDisplayRotation().updateOrientation(DisplayContentTests
+ .getRotatedOrientation(mDefaultDisplay), false /* forceUpdate */));
+ final int prevRotation = mDisplayContent.getRotation();
+ mWm.cleanupRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
+ waitHandlerIdle(mWm.mH);
+ // The display should be updated to the changed orientation after the animation is finished.
+ assertNotEquals(mDisplayContent.getRotation(), prevRotation);
+ }
+
+ @Test
public void testWallpaperHasFixedRotationApplied() {
unblockDisplayRotation(mDefaultDisplay);
mWm.setRecentsAnimationController(mController);