diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index f5ea8221a9490..ebd82caeb9452 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1169,6 +1169,9 @@ class DisplayContent extends DisplayArea.Root implements WindowManagerPolicy.Dis } activity.onRemovedFromDisplay(); + if (activity == mFixedRotationLaunchingApp) { + setFixedRotationLaunchingAppUnchecked(null); + } } @Override @@ -1452,6 +1455,12 @@ class DisplayContent extends DisplayArea.Root implements WindowManagerPolicy.Dis // It has been set and not yet finished. return true; } + if (!r.occludesParent() || r.isVisible()) { + // While entering or leaving a translucent or floating activity (e.g. dialog style), + // there is a visible activity in the background. Then it still needs rotation animation + // to cover the activity configuration change. + return false; + } if (checkOpening) { if (!mAppTransition.isTransitionSet() || !mOpeningApps.contains(r)) { // Apply normal rotation animation in case of the activity set different requested @@ -5456,6 +5465,12 @@ class DisplayContent extends DisplayArea.Root implements WindowManagerPolicy.Dis */ void onStartRecentsAnimation(@NonNull ActivityRecord r) { mAnimatingRecents = r; + if (r.isVisible() && mFocusedApp != null && !mFocusedApp.occludesParent()) { + // The recents activity has shown with the orientation determined by the top + // activity, keep its current orientation to avoid flicking by the configuration + // change of visible activity. + return; + } rotateInDifferentOrientationIfNeeded(r); if (r.hasFixedRotationTransform()) { // Set the record so we can recognize it to continue to update display orientation diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 2171d75256f2f..668f04785bbc5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1506,6 +1506,7 @@ public class ActivityRecordTests extends ActivityTestsBase { .setRotation((mActivity.getWindowConfiguration().getRotation() + 1) % 4) .build(); setRotatedScreenOrientationSilently(mActivity); + mActivity.setVisible(false); final IWindowSession session = WindowManagerGlobal.getWindowSession(); spyOn(session); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java index 4dbf79a4a5a6b..1d13788bc5230 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -456,6 +456,7 @@ public class AppWindowTokenTests extends WindowTestsBase { @Test public void testTransferStartingWindowSetFixedRotation() { final ActivityRecord topActivity = createTestActivityRecordForGivenTask(mTask); + topActivity.setVisible(false); mTask.positionChildAt(topActivity, POSITION_TOP); mActivity.addStartingWindow(mPackageName, android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, 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 ba0a5bd59be86..3041bc973a15d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1081,6 +1081,7 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.onRequestedOverrideConfigurationChanged(config); final ActivityRecord app = mAppWindow.mActivityRecord; + app.setVisible(false); mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */); mDisplayContent.mOpeningApps.add(app); @@ -1135,6 +1136,7 @@ public class DisplayContentTests extends WindowTestsBase { // Launch another activity before the transition is finished. final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot) .setDisplay(mDisplayContent).build().getTopMostActivity(); + app2.setVisible(false); mDisplayContent.mOpeningApps.add(app2); app2.setRequestedOrientation(newOrientation); @@ -1277,6 +1279,14 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.setFixedRotationLaunchingAppUnchecked(mAppWindow.mActivityRecord); displayRotation.setRotation((displayRotation.getRotation() + 1) % 4); assertTrue(displayRotation.updateRotationUnchecked(false)); + + // The recents activity should not apply fixed rotation if the top activity is not opaque. + mDisplayContent.mFocusedApp = mAppWindow.mActivityRecord; + doReturn(false).when(mDisplayContent.mFocusedApp).occludesParent(); + doReturn(ROTATION_90).when(mDisplayContent).rotationForActivityInDifferentOrientation( + eq(recentsActivity)); + mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity); + assertFalse(recentsActivity.hasFixedRotationTransform()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 130e5550b2a2b..3c98272311f7e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -517,6 +517,7 @@ public class SizeCompatTests extends ActivityTestsBase { setUpApp(new TestDisplayContent.Builder(mService, dw, dh).setNotch(notchHeight).build()); addStatusBar(mActivity.mDisplayContent); + mActivity.setVisible(false); mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */); mActivity.mDisplayContent.mOpeningApps.add(mActivity);