Loading services/core/java/com/android/server/wm/DisplayContent.java +7 −0 Original line number Diff line number Diff line Loading @@ -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()) { Loading services/core/java/com/android/server/wm/WindowToken.java +4 −6 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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(); } } } Loading Loading @@ -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); Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +28 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1467,6 +1468,33 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(recentsActivity.hasFixedRotationTransform()); } @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(); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +7 −0 Original line number Diff line number Diff line Loading @@ -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()) { Loading
services/core/java/com/android/server/wm/WindowToken.java +4 −6 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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(); } } } Loading Loading @@ -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); Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +28 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1467,6 +1468,33 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(recentsActivity.hasFixedRotationTransform()); } @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(); Loading