Check pending rotation change after recents animation
Rotation change was skipped while running recents animation to avoid interrupting the animation and may apply unexpected intermediate orientation to recents activity. But the rotation change should be still applied after the animation is finished. Otherwise the display may stay in old rotation. The case may be more obvious since live tile is introduced, because the animation keeps running until switch to app. E.g. enable auto rotation and the top is a rotatable app in landscape, and then enter recents and rotate the device to portrait. After going back to the current app, the display is still in landscape. Fix: 199371058 Test: RecentsAnimationControllerTest#testCheckRotationAfterCleanup Change-Id: I5e7487b08e139b251d160bd0627326b83351640e
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -920,6 +921,24 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
mCancelDeferredWithScreenshot = screenshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -438,6 +438,22 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
||||
assertTrue(activity.hasFixedRotationTransform());
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
Reference in New Issue
Block a user