diff options
3 files changed, 39 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 976924459252..99506067311d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1559,6 +1559,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } final int rotation = rotationForActivityInDifferentOrientation(r); if (rotation == ROTATION_UNDEFINED) { + // The display rotation won't be changed by current top activity. If there was fixed + // rotation activity, its rotated state should be cleared to cancel the adjustments. + if (hasTopFixedRotationLaunchingApp() + // Avoid breaking recents animation. + && !mFixedRotationLaunchingApp.getTask().isAnimatingByRecents()) { + clearFixedRotationLaunchingApp(); + } return false; } if (!r.getParent().matchParentBounds()) { diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 9e0fee3927c3..64e8184e793f 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -647,11 +647,6 @@ class WindowToken extends WindowContainer<WindowState> { state.mIsTransforming = false; if (applyDisplayRotation != null) { applyDisplayRotation.run(); - } else { - // The display will not rotate to the rotation of this container, let's cancel them. - for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) { - state.mAssociatedTokens.get(i).cancelFixedRotationTransform(); - } } // The state is cleared at the end, because it is used to indicate that other windows can // use seamless rotation when applying rotation to display. @@ -659,6 +654,10 @@ class WindowToken extends WindowContainer<WindowState> { final WindowToken token = state.mAssociatedTokens.get(i); token.mFixedRotationTransformState = null; token.notifyFixedRotationTransform(false /* enabled */); + if (applyDisplayRotation == null) { + // Notify cancellation because the display does not change rotation. + token.cancelFixedRotationTransform(); + } } } @@ -707,7 +706,6 @@ class WindowToken extends WindowContainer<WindowState> { // The window may be detached or detaching. return; } - notifyFixedRotationTransform(false /* enabled */); final int originalRotation = getWindowConfiguration().getRotation(); onConfigurationChanged(parent.getConfiguration()); onCancelFixedRotationTransform(originalRotation); 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 11be74d1a8c7..3db28a41d789 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -89,6 +89,7 @@ import static org.mockito.Mockito.doCallRealMethod; import android.annotation.SuppressLint; import android.app.ActivityTaskManager; import android.app.WindowConfiguration; +import android.app.servertransaction.FixedRotationAdjustmentsItem; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; @@ -1468,6 +1469,33 @@ public class DisplayContentTests extends WindowTestsBase { } @Test + public void testClearIntermediateFixedRotation() throws RemoteException { + final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build(); + mDisplayContent.setFixedRotationLaunchingApp(activity, + (mDisplayContent.getRotation() + 1) % 4); + // Create a window so FixedRotationAdjustmentsItem can be sent. + createWindow(null, TYPE_APPLICATION_STARTING, activity, "AppWin"); + final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build(); + activity2.setVisible(false); + clearInvocations(mAtm.getLifecycleManager()); + // The first activity has applied fixed rotation but the second activity becomes the top + // before the transition is done and it has the same rotation as display, so the dispatched + // rotation adjustment of first activity must be cleared. + mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(activity2, + false /* checkOpening */); + + final ArgumentCaptor<FixedRotationAdjustmentsItem> adjustmentsCaptor = + ArgumentCaptor.forClass(FixedRotationAdjustmentsItem.class); + verify(mAtm.getLifecycleManager(), atLeastOnce()).scheduleTransaction( + eq(activity.app.getThread()), adjustmentsCaptor.capture()); + assertFalse(activity.hasFixedRotationTransform()); + final FixedRotationAdjustmentsItem clearAdjustments = FixedRotationAdjustmentsItem.obtain( + activity.token, null /* fixedRotationAdjustments */); + // The captor may match other items. The first one must be the item to clear adjustments. + assertEquals(clearAdjustments, adjustmentsCaptor.getAllValues().get(0)); + } + + @Test public void testRemoteRotation() { DisplayContent dc = createNewDisplay(); |