Finish fixed rotation of recents until transition is done

With gesture navigation, while swiping up a landscape activity
a bit and give up the swipe to return to original activity, the
portrait recents activity may still perform relayout before it
becomes invisible. If the fixed rotated configuration is cleared
too early, the out configuration of relayout will be the same as
current display which is landscape. That causes an unexpected
Activity#onConfigurationChanged is called. If home is the recents,
the symptom may be that the widgets are reloaded.

Fixes: 157651692
Test: atest RecentsAnimationControllerTest# \
      testRecentViewInFixedPortraitWhenTopAppInLandscape
Change-Id: I3fde61a6914ca9abf704e737c089101b32cac3aa
This commit is contained in:
Riddle Hsu
2020-06-10 22:58:20 +08:00
parent a4614b0f1f
commit e291c7d0a7
2 changed files with 17 additions and 5 deletions

View File

@@ -5647,8 +5647,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
// Because it won't affect display orientation, just finish the transform.
animatingRecents.finishFixedRotationTransform();
// The recents activity should be going to be invisible (switch to another app or
// return to original top). Only clear the top launching record without finishing
// the transform immediately because it won't affect display orientation. And before
// the visibility is committed, the recents activity may perform relayout which may
// cause unexpected configuration change if the rotated configuration is restored.
// The transform will be finished when the transition is done.
setFixedRotationLaunchingAppUnchecked(null);
} else {
// If there is already a launching activity that is not the recents, before its

View File

@@ -349,11 +349,19 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
assertEquals(Configuration.ORIENTATION_PORTRAIT,
homeActivity.getConfiguration().orientation);
// Home activity won't become top (return to landActivity), so its fixed rotation and the
// top rotated record should be cleared.
// Home activity won't become top (return to landActivity), so the top rotated record should
// be cleared.
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
assertFalse(homeActivity.hasFixedRotationTransform());
assertFalse(mDefaultDisplay.isFixedRotationLaunchingApp(homeActivity));
assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp());
// The transform should keep until the transition is done, so the restored configuration
// won't be sent to activity and cause unnecessary configuration change.
assertTrue(homeActivity.hasFixedRotationTransform());
// In real case the transition will be executed from RecentsAnimation#finishAnimation.
mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(
homeActivity.token);
assertFalse(homeActivity.hasFixedRotationTransform());
}
@Test