Loading services/core/java/com/android/server/wm/DisplayContent.java +8 −1 Original line number Diff line number Diff line Loading @@ -1643,6 +1643,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } mAtmService.mChainTracker.endPartial(); } if (!mSetIgnoreOrientationRequest && (changes & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0) { // Update new size for the rotated activities, if any. applyFixedRotationForNonTopVisibleActivityIfNeeded(); } sendNewConfiguration(); } Loading Loading @@ -1871,7 +1876,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } final int displayRotation = getRotation(); final int rotation = mDisplayRotation.rotationForOrientation(orientation, displayRotation); if (rotation == displayRotation) { final DisplayFrames rotatedFrames = ar.getFixedRotationTransformDisplayFrames(); if (rotation == displayRotation && (rotatedFrames == null || (rotatedFrames.mWidth == mDisplayFrames.mWidth && rotatedFrames.mHeight == mDisplayFrames.mHeight))) { return; } startFixedRotationTransform(ar, rotation); Loading services/core/java/com/android/server/wm/WindowContainer.java +7 −3 Original line number Diff line number Diff line Loading @@ -3166,8 +3166,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // set first, since we don't want rotation included in this (for now). mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y); if (mTransitionController.isShellTransitionsEnabled() && !mTransitionController.useShellTransitionsRotation()) { if (!mTransitionController.useShellTransitionsRotation()) { if (deltaRotation != Surface.ROTATION_0) { updateSurfaceRotation(t, deltaRotation, null /* positionLeash */); mDisplayContent.setFixedTransformHint(getPendingTransaction(), mSurfaceControl, Loading @@ -3190,8 +3189,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // parent must be non-null otherwise deltaRotation would be 0. RotationUtils.rotateSurface(t, mSurfaceControl, deltaRotation); mTmpPos.set(mLastSurfacePosition.x, mLastSurfacePosition.y); final Rect parentBounds = getParent().getBounds(); final boolean flipped = (deltaRotation % 2) != 0; final Rect parentBounds = getParentBoundsForSurfaceRotation(flipped); RotationUtils.rotatePoint(mTmpPos, deltaRotation, flipped ? parentBounds.height() : parentBounds.width(), flipped ? parentBounds.width() : parentBounds.height()); Loading @@ -3199,6 +3198,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< mTmpPos.x, mTmpPos.y); } /** This is used to calculate the offset of rotated surface in the parent. */ Rect getParentBoundsForSurfaceRotation(boolean flipped) { return getParent().getBounds(); } @VisibleForTesting Point getLastSurfacePosition() { return mLastSurfacePosition; Loading services/core/java/com/android/server/wm/WindowToken.java +27 −0 Original line number Diff line number Diff line Loading @@ -448,6 +448,11 @@ class WindowToken extends WindowContainer<WindowState> { void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames, Configuration config) { if (mFixedRotationTransformState != null) { if (mFixedRotationTransformState.mDisplayFrames.mRotation == displayFrames.mRotation) { // Invalidate the position, so WindowContainer#updateSurfacePosition can update // the surface position with new size for the same rotation. mLastSurfacePosition.offset(-1, -1); } mFixedRotationTransformState.disassociate(this); } config = new Configuration(config); Loading @@ -467,6 +472,12 @@ class WindowToken extends WindowContainer<WindowState> { return; } if (mFixedRotationTransformState != null) { if (mFixedRotationTransformState.mDisplayFrames.mRotation == fixedRotationState.mDisplayFrames.mRotation) { // Invalidate the position, so WindowContainer#updateSurfacePosition can update // the surface position with new size for the same rotation. mLastSurfacePosition.offset(-1, -1); } mFixedRotationTransformState.disassociate(this); } mFixedRotationTransformState = fixedRotationState; Loading Loading @@ -675,6 +686,22 @@ class WindowToken extends WindowContainer<WindowState> { super.updateSurfaceRotation(t, deltaRotation, positionLeash); } @Override Rect getParentBoundsForSurfaceRotation(boolean flipped) { if (mFixedRotationTransformState == null) { return super.getParentBoundsForSurfaceRotation(flipped); } // Use the bounds from transform state because it is calculated by the latest display size. // In case the display is resizing that the parent hasn't applied new configuration. if (!flipped) { return mFixedRotationTransformState.mDisplayFrames.mUnrestricted; } final int w = mFixedRotationTransformState.mDisplayFrames.mHeight; final int h = mFixedRotationTransformState.mDisplayFrames.mWidth; mTmpPrevBounds.set(0, 0, w, h); return mTmpPrevBounds; } @Override void resetSurfacePositionForAnimationLeash(SurfaceControl.Transaction t) { // Keep the transformed position to animate because the surface will show in different Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +34 −0 Original line number Diff line number Diff line Loading @@ -1798,6 +1798,40 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.hasTopFixedRotationLaunchingApp()); } @Test public void testNonTopVisibleFixedOrientationOnDisplayResize() { useFakeSettingsProvider(); spyOn(mWm.mAppCompatConfiguration); doReturn(false).when(mWm.mAppCompatConfiguration).isTranslucentLetterboxingEnabled(); setReverseDefaultRotation(mDisplayContent, false); makeDisplayPortrait(mDisplayContent); final ActivityRecord nonTopVisible = new ActivityBuilder(mAtm).setCreateTask(true) .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE).setVisible(false).build(); new ActivityBuilder(mAtm).setCreateTask(true) .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) .setActivityTheme(android.R.style.Theme_Translucent).build(); nonTopVisible.setVisibleRequested(true); clearInvocations(mTransaction); mDisplayContent.updateOrientation(); mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded(); assertTrue(nonTopVisible.hasFixedRotationTransform()); verify(mTransaction).setPosition(eq(nonTopVisible.mSurfaceControl), eq((float) mDisplayContent.mBaseDisplayWidth), eq(0f)); clearInvocations(mTransaction); final int newW = mDisplayContent.mBaseDisplayWidth / 2; final int newH = mDisplayContent.mBaseDisplayHeight / 2; mDisplayContent.setForcedSize(newW, newH); final DisplayFrames rotatedFrames = nonTopVisible.getFixedRotationTransformDisplayFrames(); assertNotNull(rotatedFrames); assertEquals(newH, rotatedFrames.mWidth); assertEquals(newW, rotatedFrames.mHeight); verify(mTransaction).setPosition(eq(nonTopVisible.mSurfaceControl), eq((float) newW), eq(0f)); } @Test public void testSecondaryInternalDisplayRotationFollowsDefaultDisplay() { final DisplayRotationCoordinator coordinator = Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +8 −1 Original line number Diff line number Diff line Loading @@ -1643,6 +1643,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } mAtmService.mChainTracker.endPartial(); } if (!mSetIgnoreOrientationRequest && (changes & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0) { // Update new size for the rotated activities, if any. applyFixedRotationForNonTopVisibleActivityIfNeeded(); } sendNewConfiguration(); } Loading Loading @@ -1871,7 +1876,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } final int displayRotation = getRotation(); final int rotation = mDisplayRotation.rotationForOrientation(orientation, displayRotation); if (rotation == displayRotation) { final DisplayFrames rotatedFrames = ar.getFixedRotationTransformDisplayFrames(); if (rotation == displayRotation && (rotatedFrames == null || (rotatedFrames.mWidth == mDisplayFrames.mWidth && rotatedFrames.mHeight == mDisplayFrames.mHeight))) { return; } startFixedRotationTransform(ar, rotation); Loading
services/core/java/com/android/server/wm/WindowContainer.java +7 −3 Original line number Diff line number Diff line Loading @@ -3166,8 +3166,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // set first, since we don't want rotation included in this (for now). mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y); if (mTransitionController.isShellTransitionsEnabled() && !mTransitionController.useShellTransitionsRotation()) { if (!mTransitionController.useShellTransitionsRotation()) { if (deltaRotation != Surface.ROTATION_0) { updateSurfaceRotation(t, deltaRotation, null /* positionLeash */); mDisplayContent.setFixedTransformHint(getPendingTransaction(), mSurfaceControl, Loading @@ -3190,8 +3189,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // parent must be non-null otherwise deltaRotation would be 0. RotationUtils.rotateSurface(t, mSurfaceControl, deltaRotation); mTmpPos.set(mLastSurfacePosition.x, mLastSurfacePosition.y); final Rect parentBounds = getParent().getBounds(); final boolean flipped = (deltaRotation % 2) != 0; final Rect parentBounds = getParentBoundsForSurfaceRotation(flipped); RotationUtils.rotatePoint(mTmpPos, deltaRotation, flipped ? parentBounds.height() : parentBounds.width(), flipped ? parentBounds.width() : parentBounds.height()); Loading @@ -3199,6 +3198,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< mTmpPos.x, mTmpPos.y); } /** This is used to calculate the offset of rotated surface in the parent. */ Rect getParentBoundsForSurfaceRotation(boolean flipped) { return getParent().getBounds(); } @VisibleForTesting Point getLastSurfacePosition() { return mLastSurfacePosition; Loading
services/core/java/com/android/server/wm/WindowToken.java +27 −0 Original line number Diff line number Diff line Loading @@ -448,6 +448,11 @@ class WindowToken extends WindowContainer<WindowState> { void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames, Configuration config) { if (mFixedRotationTransformState != null) { if (mFixedRotationTransformState.mDisplayFrames.mRotation == displayFrames.mRotation) { // Invalidate the position, so WindowContainer#updateSurfacePosition can update // the surface position with new size for the same rotation. mLastSurfacePosition.offset(-1, -1); } mFixedRotationTransformState.disassociate(this); } config = new Configuration(config); Loading @@ -467,6 +472,12 @@ class WindowToken extends WindowContainer<WindowState> { return; } if (mFixedRotationTransformState != null) { if (mFixedRotationTransformState.mDisplayFrames.mRotation == fixedRotationState.mDisplayFrames.mRotation) { // Invalidate the position, so WindowContainer#updateSurfacePosition can update // the surface position with new size for the same rotation. mLastSurfacePosition.offset(-1, -1); } mFixedRotationTransformState.disassociate(this); } mFixedRotationTransformState = fixedRotationState; Loading Loading @@ -675,6 +686,22 @@ class WindowToken extends WindowContainer<WindowState> { super.updateSurfaceRotation(t, deltaRotation, positionLeash); } @Override Rect getParentBoundsForSurfaceRotation(boolean flipped) { if (mFixedRotationTransformState == null) { return super.getParentBoundsForSurfaceRotation(flipped); } // Use the bounds from transform state because it is calculated by the latest display size. // In case the display is resizing that the parent hasn't applied new configuration. if (!flipped) { return mFixedRotationTransformState.mDisplayFrames.mUnrestricted; } final int w = mFixedRotationTransformState.mDisplayFrames.mHeight; final int h = mFixedRotationTransformState.mDisplayFrames.mWidth; mTmpPrevBounds.set(0, 0, w, h); return mTmpPrevBounds; } @Override void resetSurfacePositionForAnimationLeash(SurfaceControl.Transaction t) { // Keep the transformed position to animate because the surface will show in different Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +34 −0 Original line number Diff line number Diff line Loading @@ -1798,6 +1798,40 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.hasTopFixedRotationLaunchingApp()); } @Test public void testNonTopVisibleFixedOrientationOnDisplayResize() { useFakeSettingsProvider(); spyOn(mWm.mAppCompatConfiguration); doReturn(false).when(mWm.mAppCompatConfiguration).isTranslucentLetterboxingEnabled(); setReverseDefaultRotation(mDisplayContent, false); makeDisplayPortrait(mDisplayContent); final ActivityRecord nonTopVisible = new ActivityBuilder(mAtm).setCreateTask(true) .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE).setVisible(false).build(); new ActivityBuilder(mAtm).setCreateTask(true) .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) .setActivityTheme(android.R.style.Theme_Translucent).build(); nonTopVisible.setVisibleRequested(true); clearInvocations(mTransaction); mDisplayContent.updateOrientation(); mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded(); assertTrue(nonTopVisible.hasFixedRotationTransform()); verify(mTransaction).setPosition(eq(nonTopVisible.mSurfaceControl), eq((float) mDisplayContent.mBaseDisplayWidth), eq(0f)); clearInvocations(mTransaction); final int newW = mDisplayContent.mBaseDisplayWidth / 2; final int newH = mDisplayContent.mBaseDisplayHeight / 2; mDisplayContent.setForcedSize(newW, newH); final DisplayFrames rotatedFrames = nonTopVisible.getFixedRotationTransformDisplayFrames(); assertNotNull(rotatedFrames); assertEquals(newH, rotatedFrames.mWidth); assertEquals(newW, rotatedFrames.mHeight); verify(mTransaction).setPosition(eq(nonTopVisible.mSurfaceControl), eq((float) newW), eq(0f)); } @Test public void testSecondaryInternalDisplayRotationFollowsDefaultDisplay() { final DisplayRotationCoordinator coordinator = Loading