diff options
| author | 2025-03-10 18:18:21 -0700 | |
|---|---|---|
| committer | 2025-03-10 18:18:21 -0700 | |
| commit | 1347d67e1844fd66ac1e36b284efd1f72e2d4d6b (patch) | |
| tree | b1e138860dd47be44c6f493756c241ccff578ff7 | |
| parent | d89610c3ca2118d86e41ce22d963f0d7e7295188 (diff) | |
| parent | 19be81cc1138ac67f1a25909c56ad9921acadaa0 (diff) | |
Merge "Remove legacy window level seamless rotation" into main
10 files changed, 49 insertions, 374 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 76a39d9c884a..afacae8d0c13 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2161,7 +2161,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** Re-show the previously hidden windows if all seamless rotated windows are done. */ void finishAsyncRotationIfPossible() { final AsyncRotationController controller = mAsyncRotationController; - if (controller != null && !mDisplayRotation.hasSeamlessRotatingWindow()) { + if (controller != null) { controller.completeAll(); mAsyncRotationController = null; } @@ -2238,11 +2238,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private void applyRotation(final int oldRotation, final int rotation) { mDisplayRotation.applyCurrentRotation(rotation); - final boolean shellTransitions = mTransitionController.getTransitionPlayer() != null; - final boolean rotateSeamlessly = - mDisplayRotation.isRotatingSeamlessly() && !shellTransitions; - final Transaction transaction = - shellTransitions ? getSyncTransaction() : getPendingTransaction(); + // We need to update our screen size information to match the new rotation. If the rotation // has actually changed then this method will return true and, according to the comment at // the top of the method, the caller is obligated to call computeNewConfigurationLocked(). @@ -2250,25 +2246,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // #computeScreenConfiguration() later. updateDisplayAndOrientation(null /* outConfig */); - if (!shellTransitions) { - forAllWindows(w -> { - w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly); - }, true /* traverseTopToBottom */); - mPinnedTaskController.startSeamlessRotationIfNeeded(transaction, oldRotation, rotation); - if (!mDisplayRotation.hasSeamlessRotatingWindow()) { - // Make sure DisplayRotation#isRotatingSeamlessly() will return false. - mDisplayRotation.cancelSeamlessRotation(); - } - } + // Before setDisplayProjection is applied by the start transaction of transition, + // set the transform hint to avoid using surface in old rotation. + setFixedTransformHint(getPendingTransaction(), mSurfaceControl, rotation); + // The sync transaction should already contains setDisplayProjection, so unset the + // hint to restore the natural state when the transaction is applied. + getSyncTransaction().unsetFixedTransformHint(mSurfaceControl); - if (shellTransitions) { - // Before setDisplayProjection is applied by the start transaction of transition, - // set the transform hint to avoid using surface in old rotation. - setFixedTransformHint(getPendingTransaction(), mSurfaceControl, rotation); - // The sync transaction should already contains setDisplayProjection, so unset the - // hint to restore the natural state when the transaction is applied. - transaction.unsetFixedTransformHint(mSurfaceControl); - } scheduleAnimation(); mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation); @@ -2870,8 +2854,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // If the transition finished callback cannot match the token for some reason, make sure the // rotated state is cleared if it is already invisible. if (mFixedRotationLaunchingApp != null && !mFixedRotationLaunchingApp.isVisibleRequested() - && !mFixedRotationLaunchingApp.isVisible() - && !mDisplayRotation.isRotatingSeamlessly()) { + && !mFixedRotationLaunchingApp.isVisible()) { clearFixedRotationLaunchingApp(); } // If there won't be a transition to notify the launch is done, then it should be ready to @@ -5072,7 +5055,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent; - if (!inTransition() && !mDisplayRotation.isRotatingSeamlessly()) { + if (!inTransition()) { mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId, mLastHasContent, mTmpApplySurfaceChangesTransactionState.preferredRefreshRate, diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 9cf792d82f56..9edbb70c3b74 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -168,19 +168,6 @@ public class DisplayRotation { private int mDeferredRotationPauseCount; /** - * A count of the windows which are 'seamlessly rotated', e.g. a surface at an old orientation - * is being transformed. We freeze orientation updates while any windows are seamlessly rotated, - * so we need to track when this hits zero so we can apply deferred orientation updates. - */ - private int mSeamlessRotationCount; - - /** - * True in the interval from starting seamless rotation until the last rotated window draws in - * the new orientation. - */ - private boolean mRotatingSeamlessly; - - /** * Behavior of rotation suggestions. * * @see Settings.Secure#SHOW_ROTATION_SUGGESTIONS @@ -630,15 +617,6 @@ public class DisplayRotation { return true; } - if (shouldRotateSeamlessly(oldRotation, rotation, forceUpdate)) { - // The screen rotation animation uses a screenshot to freeze the screen while windows - // resize underneath. When we are rotating seamlessly, we allow the elements to - // transition to their rotated state independently and without a freeze required. - prepareSeamlessRotation(); - } else { - cancelSeamlessRotation(); - } - // Give a remote handler (system ui) some time to reposition things. startRemoteRotation(oldRotation, mRotation); @@ -677,42 +655,6 @@ public class DisplayRotation { } } - /** - * This ensures that normal rotation animation is used. E.g. {@link #mRotatingSeamlessly} was - * set by previous {@link #updateRotationUnchecked}, but another orientation change happens - * before calling {@link DisplayContent#sendNewConfiguration} (remote rotation hasn't finished) - * and it doesn't choose seamless rotation. - */ - void cancelSeamlessRotation() { - if (!mRotatingSeamlessly) { - return; - } - mDisplayContent.forAllWindows(w -> { - if (w.mSeamlesslyRotated) { - w.cancelSeamlessRotation(); - w.mSeamlesslyRotated = false; - } - }, true /* traverseTopToBottom */); - mSeamlessRotationCount = 0; - mRotatingSeamlessly = false; - mDisplayContent.finishAsyncRotationIfPossible(); - } - - private void prepareSeamlessRotation() { - // We are careful to reset this in case a window was removed before it finished - // seamless rotation. - mSeamlessRotationCount = 0; - mRotatingSeamlessly = true; - } - - boolean isRotatingSeamlessly() { - return mRotatingSeamlessly; - } - - boolean hasSeamlessRotatingWindow() { - return mSeamlessRotationCount > 0; - } - @VisibleForTesting boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) { // Display doesn't need to be frozen because application has been started in correct @@ -750,13 +692,6 @@ public class DisplayRotation { return false; } - // We can't rotate (seamlessly or not) while waiting for the last seamless rotation to - // complete (that is, waiting for windows to redraw). It's tempting to check - // mSeamlessRotationCount but that could be incorrect in the case of window-removal. - if (!forceUpdate && mDisplayContent.getWindow(win -> win.mSeamlesslyRotated) != null) { - return false; - } - return true; } @@ -774,28 +709,6 @@ public class DisplayRotation { return oldRotation != Surface.ROTATION_180 && newRotation != Surface.ROTATION_180; } - void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) { - if (seamlesslyRotated == w.mSeamlesslyRotated || w.mForceSeamlesslyRotate) { - return; - } - - w.mSeamlesslyRotated = seamlesslyRotated; - if (seamlesslyRotated) { - mSeamlessRotationCount++; - } else { - mSeamlessRotationCount--; - } - if (mSeamlessRotationCount == 0) { - ProtoLog.i(WM_DEBUG_ORIENTATION, - "Performing post-rotate rotation after seamless rotation"); - // Finish seamless rotation. - mRotatingSeamlessly = false; - mDisplayContent.finishAsyncRotationIfPossible(); - - updateRotationAndSendNewConfigIfChanged(); - } - } - void restoreSettings(int userRotationMode, int userRotation, int fixedToUserRotation) { mFixedToUserRotation = fixedToUserRotation; diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java index 6dd7d35856df..6e59828c8ff2 100644 --- a/services/core/java/com/android/server/wm/PinnedTaskController.java +++ b/services/core/java/com/android/server/wm/PinnedTaskController.java @@ -21,20 +21,13 @@ import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import android.app.PictureInPictureParams; import android.content.res.Resources; -import android.graphics.Insets; -import android.graphics.Matrix; import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; -import android.util.RotationUtils; import android.util.Slog; import android.view.IPinnedTaskListener; -import android.view.Surface; -import android.view.SurfaceControl; -import android.window.PictureInPictureSurfaceTransaction; import java.io.PrintWriter; @@ -71,11 +64,7 @@ class PinnedTaskController { * based on the new rotation. */ private Rect mDestRotatedBounds; - /** - * Non-null if the entering PiP task from recents animation will cause display rotation to - * change. The transaction is based on the old rotation. - */ - private PictureInPictureSurfaceTransaction mPipTransaction; + /** Whether to skip task configuration change once. */ private boolean mFreezingTaskConfig; /** Defer display orientation change if the PiP task is animating across orientations. */ @@ -212,14 +201,12 @@ class PinnedTaskController { } /** - * Sets the transaction for {@link #startSeamlessRotationIfNeeded} if the orientation of display - * will be changed. This is only called when finishing recents animation with pending - * orientation change that will be handled by - * {@link DisplayContent.FixedRotationTransitionListener#onFinishRecentsAnimation}. + * Sets a hint if the orientation of display will be changed. This is only called when + * finishing recents animation with pending orientation change that will be handled by + * {@link DisplayContent.FixedRotationTransitionListener}. */ - void setEnterPipTransaction(PictureInPictureSurfaceTransaction tx) { + void setEnterPipWithRotatedTransientLaunch() { mFreezingTaskConfig = true; - mPipTransaction = tx; } /** Called when the activity in PiP task has PiP windowing mode (at the end of animation). */ @@ -233,81 +220,6 @@ class PinnedTaskController { } /** - * Resets rotation and applies scale and position to PiP task surface to match the current - * rotation of display. The final surface matrix will be replaced by PiPTaskOrganizer after it - * receives the callback of fixed rotation completion. - */ - void startSeamlessRotationIfNeeded(SurfaceControl.Transaction t, - int oldRotation, int newRotation) { - final Rect bounds = mDestRotatedBounds; - final PictureInPictureSurfaceTransaction pipTx = mPipTransaction; - final boolean emptyPipPositionTx = pipTx == null || pipTx.mPosition == null; - if (bounds == null && emptyPipPositionTx) { - return; - } - final TaskDisplayArea taskArea = mDisplayContent.getDefaultTaskDisplayArea(); - final Task pinnedTask = taskArea.getRootPinnedTask(); - if (pinnedTask == null) { - return; - } - - mDestRotatedBounds = null; - mPipTransaction = null; - final Rect areaBounds = taskArea.getBounds(); - if (!emptyPipPositionTx) { - // The transaction from recents animation is in old rotation. So the position needs to - // be rotated. - float dx = pipTx.mPosition.x; - float dy = pipTx.mPosition.y; - final Matrix matrix = pipTx.getMatrix(); - if (pipTx.mRotation == 90) { - dx = pipTx.mPosition.y; - dy = areaBounds.right - pipTx.mPosition.x; - matrix.postRotate(-90); - } else if (pipTx.mRotation == -90) { - dx = areaBounds.bottom - pipTx.mPosition.y; - dy = pipTx.mPosition.x; - matrix.postRotate(90); - } - matrix.postTranslate(dx, dy); - final SurfaceControl leash = pinnedTask.getSurfaceControl(); - t.setMatrix(leash, matrix, new float[9]); - if (pipTx.hasCornerRadiusSet()) { - t.setCornerRadius(leash, pipTx.mCornerRadius); - } - Slog.i(TAG, "Seamless rotation PiP tx=" + pipTx + " pos=" + dx + "," + dy); - return; - } - - final PictureInPictureParams params = pinnedTask.getPictureInPictureParams(); - final Rect sourceHintRect = params != null && params.hasSourceBoundsHint() - ? params.getSourceRectHint() - : null; - Slog.i(TAG, "Seamless rotation PiP bounds=" + bounds + " hintRect=" + sourceHintRect); - final int rotationDelta = RotationUtils.deltaRotation(oldRotation, newRotation); - // Adjust for display cutout if applicable. - if (sourceHintRect != null && rotationDelta == Surface.ROTATION_270) { - if (pinnedTask.getDisplayCutoutInsets() != null) { - final int rotationBackDelta = RotationUtils.deltaRotation(newRotation, oldRotation); - final Rect displayCutoutInsets = RotationUtils.rotateInsets( - Insets.of(pinnedTask.getDisplayCutoutInsets()), rotationBackDelta).toRect(); - sourceHintRect.offset(displayCutoutInsets.left, displayCutoutInsets.top); - } - } - final Rect contentBounds = sourceHintRect != null && areaBounds.contains(sourceHintRect) - ? sourceHintRect : areaBounds; - final int w = contentBounds.width(); - final int h = contentBounds.height(); - final float scale = w <= h ? (float) bounds.width() / w : (float) bounds.height() / h; - final int insetLeft = (int) ((contentBounds.left - areaBounds.left) * scale + .5f); - final int insetTop = (int) ((contentBounds.top - areaBounds.top) * scale + .5f); - final Matrix matrix = new Matrix(); - matrix.setScale(scale, scale); - matrix.postTranslate(bounds.left - insetLeft, bounds.top - insetTop); - t.setMatrix(pinnedTask.getSurfaceControl(), matrix, new float[9]); - } - - /** * Returns {@code true} to skip {@link Task#onConfigurationChanged} because it is expected that * there will be a orientation change and a PiP configuration change. */ @@ -321,7 +233,6 @@ class PinnedTaskController { mFreezingTaskConfig = false; mDeferOrientationChanging = false; mDestRotatedBounds = null; - mPipTransaction = null; } /** @@ -381,9 +292,6 @@ class PinnedTaskController { if (mDestRotatedBounds != null) { pw.println(prefix + " mPendingBounds=" + mDestRotatedBounds); } - if (mPipTransaction != null) { - pw.println(prefix + " mPipTransaction=" + mPipTransaction); - } pw.println(prefix + " mIsImeShowing=" + mIsImeShowing); pw.println(prefix + " mImeHeight=" + mImeHeight); pw.println(prefix + " mMinAspectRatio=" + mMinAspectRatio); diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 803c21ccab6e..30313fc63857 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -1249,7 +1249,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { // Skip dispatching the change for PiP task to avoid its activity drawing for the // intermediate state which will cause flickering. The final PiP bounds in new // rotation will be applied by PipTransition. - ar.mDisplayContent.mPinnedTaskController.setEnterPipTransaction(null); + ar.mDisplayContent.mPinnedTaskController.setEnterPipWithRotatedTransientLaunch(); } return inPip; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c078d67b6cc6..ac190ffb90a3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2132,7 +2132,6 @@ public class WindowManagerService extends IWindowManager.Stub } final DisplayContent dc = win.getDisplayContent(); - dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */); win.resetAppOpsState(); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 4a93904e466c..a270af56cbcd 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -169,7 +169,6 @@ import static com.android.server.wm.WindowStateProto.IS_READY_FOR_DISPLAY; import static com.android.server.wm.WindowStateProto.IS_VISIBLE; import static com.android.server.wm.WindowStateProto.KEEP_CLEAR_AREAS; import static com.android.server.wm.WindowStateProto.MERGED_LOCAL_INSETS_SOURCES; -import static com.android.server.wm.WindowStateProto.PENDING_SEAMLESS_ROTATION; import static com.android.server.wm.WindowStateProto.REMOVED; import static com.android.server.wm.WindowStateProto.REMOVE_ON_EXIT; import static com.android.server.wm.WindowStateProto.REQUESTED_HEIGHT; @@ -231,7 +230,6 @@ import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.Surface; -import android.view.Surface.Rotation; import android.view.SurfaceControl; import android.view.View; import android.view.ViewDebug; @@ -399,7 +397,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP * rotation. */ final boolean mForceSeamlesslyRotate; - SeamlessRotator mPendingSeamlessRotate; private RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks; @@ -593,13 +590,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP /** The time when the window was last requested to redraw for orientation change. */ private long mOrientationChangeRedrawRequestTime; - /** - * The orientation during the last visible call to relayout. If our - * current orientation is different, the window can't be ready - * to be shown. - */ - int mLastVisibleLayoutRotation = -1; - /** Is this window now (or just being) removed? */ boolean mRemoved; @@ -655,15 +645,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP boolean mIsSurfacePositionPaused; /** - * During seamless rotation we have two phases, first the old window contents - * are rotated to look as if they didn't move in the new coordinate system. Then we - * have to freeze updates to this layer (to preserve the transformation) until - * the resize actually occurs. This is true from when the transformation is set - * and false until the transaction to resize is sent. - */ - boolean mSeamlesslyRotated = false; - - /** * Whether the IME insets have been consumed. If {@code true}, this window won't be able to * receive visible IME insets; {@code false}, otherwise. */ @@ -778,11 +759,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ private boolean mInsetsAnimationRunning; - private final Consumer<SurfaceControl.Transaction> mSeamlessRotationFinishedConsumer = t -> { - finishSeamlessRotation(t); - updateSurfacePosition(t); - }; - private final Consumer<SurfaceControl.Transaction> mSetSurfacePositionConsumer = t -> { // Only apply the position to the surface when there's no leash created. if (mSurfaceControl != null && mSurfaceControl.isValid() && !mSurfaceAnimator.hasLeash()) { @@ -899,69 +875,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return visible && mFrozenInsetsState == null; } - void seamlesslyRotateIfAllowed(Transaction transaction, @Rotation int oldRotation, - @Rotation int rotation, boolean requested) { - // Invisible windows and the wallpaper do not participate in the seamless rotation animation - if (!isVisibleNow() || mIsWallpaper) { - return; - } - - if (mToken.hasFixedRotationTransform()) { - // The transform of its surface is handled by fixed rotation. - return; - } - final Task task = getTask(); - if (task != null && task.inPinnedWindowingMode()) { - // It is handled by PinnedTaskController. Note that the windowing mode of activity - // and windows may still be fullscreen. - return; - } - - if (mPendingSeamlessRotate != null) { - oldRotation = mPendingSeamlessRotate.getOldRotation(); - } - - // Skip performing seamless rotation when the controlled insets is IME with visible state. - if (mControllableInsetProvider != null - && mControllableInsetProvider.getSource().getType() == WindowInsets.Type.ime()) { - return; - } - - if (mForceSeamlesslyRotate || requested) { - if (mControllableInsetProvider != null) { - mControllableInsetProvider.startSeamlessRotation(); - } - mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo(), - false /* applyFixedTransformationHint */); - // The surface position is going to be unrotated according to the last position. - // Make sure the source position is up-to-date. - mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y); - mPendingSeamlessRotate.unrotate(transaction, this); - getDisplayContent().getDisplayRotation().markForSeamlessRotation(this, - true /* seamlesslyRotated */); - applyWithNextDraw(mSeamlessRotationFinishedConsumer); - } - } - - void cancelSeamlessRotation() { - finishSeamlessRotation(getPendingTransaction()); - } - - void finishSeamlessRotation(SurfaceControl.Transaction t) { - if (mPendingSeamlessRotate == null) { - return; - } - - mPendingSeamlessRotate.finish(t, this); - mPendingSeamlessRotate = null; - - getDisplayContent().getDisplayRotation().markForSeamlessRotation(this, - false /* seamlesslyRotated */); - if (mControllableInsetProvider != null) { - mControllableInsetProvider.finishSeamlessRotation(); - } - } - List<Rect> getSystemGestureExclusion() { return mExclusionRects; } @@ -2176,8 +2089,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 && !isDragResizing() && hasMovementAnimation - && !mWinAnimator.mLastHidden - && !mSeamlesslyRotated; + && !mWinAnimator.mLastHidden; } /** @@ -3998,7 +3910,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP proto.write(REMOVED, mRemoved); proto.write(IS_ON_SCREEN, isOnScreen()); proto.write(IS_VISIBLE, isVisible); - proto.write(PENDING_SEAMLESS_ROTATION, mPendingSeamlessRotate != null); proto.write(FORCE_SEAMLESS_ROTATION, mForceSeamlesslyRotate); proto.write(HAS_COMPAT_SCALE, hasCompatScale()); proto.write(GLOBAL_SCALE, mGlobalScale); @@ -4144,14 +4055,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP + " mDestroying=" + mDestroying + " mRemoved=" + mRemoved); } - pw.print(prefix + "mForceSeamlesslyRotate=" + mForceSeamlesslyRotate - + " seamlesslyRotate: pending="); - if (mPendingSeamlessRotate != null) { - mPendingSeamlessRotate.dump(pw); - } else { - pw.print("null"); - } - pw.println(); if (mXOffset != 0 || mYOffset != 0) { pw.println(prefix + "mXOffset=" + mXOffset + " mYOffset=" + mYOffset); @@ -4883,8 +4786,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWinAnimator.mEnterAnimationPending = true; } - mLastVisibleLayoutRotation = getDisplayContent().getRotation(); - mWinAnimator.mEnteringAnimation = true; Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareToDisplay"); @@ -5282,9 +5183,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final AsyncRotationController asyncRotationController = mDisplayContent.getAsyncRotationController(); - if ((asyncRotationController != null - && asyncRotationController.hasSeamlessOperation(mToken)) - || mPendingSeamlessRotate != null) { + if (asyncRotationController != null + && asyncRotationController.hasSeamlessOperation(mToken)) { // Freeze position while un-rotating the window, so its surface remains at the position // corresponding to the original rotation. return; 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 8992c2e632b2..7f242dea9f45 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -2021,8 +2021,6 @@ public class ActivityRecordTests extends WindowTestsBase { display.setFixedRotationLaunchingAppUnchecked(activity); displayRotation.updateRotationUnchecked(true /* forceUpdate */); - assertTrue(displayRotation.isRotatingSeamlessly()); - // The launching rotated app should not be cleared when waiting for remote rotation. display.continueUpdateOrientationForDiffOrienLaunchingApp(); assertTrue(display.isFixedRotationLaunchingApp(activity)); 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 4c81f738138a..25fdedf32908 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1706,8 +1706,6 @@ public class DisplayContentTests extends WindowTestsBase { app.setVisible(true); doReturn(false).when(app).inTransition(); mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token); - mStatusBarWindow.finishSeamlessRotation(t); - mNavBarWindow.finishSeamlessRotation(t); // The fixed rotation should be cleared and the new rotation is applied to display. assertFalse(app.hasFixedRotationTransform()); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 59ee2f5c8e9f..5624677779a2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -23,9 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.InsetsSource.ID_IME; -import static android.view.Surface.ROTATION_0; -import static android.view.Surface.ROTATION_270; -import static android.view.Surface.ROTATION_90; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; @@ -88,7 +85,6 @@ import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; -import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; @@ -673,56 +669,6 @@ public class WindowStateTests extends WindowTestsBase { } @Test - public void testSeamlesslyRotateWindow() { - final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build(); - final SurfaceControl.Transaction t = spy(StubTransaction.class); - - makeWindowVisible(app); - app.mSurfaceControl = mock(SurfaceControl.class); - final Rect frame = app.getFrame(); - frame.set(10, 20, 60, 80); - app.updateSurfacePosition(t); - assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top)); - app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true /* requested */); - assertTrue(app.mSeamlesslyRotated); - - // Verify we un-rotate the window state surface. - final Matrix matrix = new Matrix(); - // Un-rotate 90 deg. - matrix.setRotate(270); - // Translate it back to origin. - matrix.postTranslate(0, mDisplayInfo.logicalWidth); - verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class)); - - // Verify we update the position as well. - final float[] curSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y}; - matrix.mapPoints(curSurfacePos); - verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1])); - - app.finishSeamlessRotation(t); - assertFalse(app.mSeamlesslyRotated); - assertNull(app.mPendingSeamlessRotate); - - // Simulate the case with deferred layout and animation. - app.resetSurfacePositionForAnimationLeash(t); - clearInvocations(t); - mWm.mWindowPlacerLocked.deferLayout(); - app.updateSurfacePosition(t); - // Because layout is deferred, the position should keep the reset value. - assertTrue(app.mLastSurfacePosition.equals(0, 0)); - - app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_270, true /* requested */); - // The last position must be updated so the surface can be unrotated properly. - assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top)); - matrix.setRotate(90); - matrix.postTranslate(mDisplayInfo.logicalHeight, 0); - curSurfacePos[0] = frame.left; - curSurfacePos[1] = frame.top; - matrix.mapPoints(curSurfacePos); - verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1])); - } - - @Test public void testVisibilityChangeSwitchUser() { final WindowState window = newWindowBuilder("app", TYPE_APPLICATION).build(); window.mHasSurface = true; diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index a02c3db1e636..8907a72e0b34 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -17,6 +17,8 @@ package com.android.server.wm; import static android.view.InsetsSource.ID_IME; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_90; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; @@ -35,16 +37,19 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Configuration; +import android.graphics.Matrix; import android.os.Bundle; import android.os.IBinder; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; +import android.view.SurfaceControl; import android.view.WindowInsets; import android.window.WindowContext; @@ -335,6 +340,31 @@ public class WindowTokenTests extends WindowTestsBase { } @Test + public void testSeamlesslyRotate() { + final SurfaceControl.Transaction t = mTransaction; + final TestWindowToken token = createTestWindowToken(0, mDisplayContent); + token.mLastSurfacePosition.x = 10; + token.mLastSurfacePosition.y = 20; + final SeamlessRotator rotator = new SeamlessRotator(ROTATION_0, ROTATION_90, + mDisplayContent.getDisplayInfo(), false /* applyFixedTransformationHint */); + clearInvocations(t); + rotator.unrotate(t, token); + + // Verify surface is un-rotated. + final Matrix matrix = new Matrix(); + // Un-rotate 90 deg. + matrix.setRotate(270); + // Translate it back to origin. + matrix.postTranslate(0, mDisplayInfo.logicalWidth); + verify(t).setMatrix(eq(token.mSurfaceControl), eq(matrix), any(float[].class)); + + final float[] curSurfacePos = {token.mLastSurfacePosition.x, token.mLastSurfacePosition.y}; + matrix.mapPoints(curSurfacePos); + verify(t).setPosition(eq(token.mSurfaceControl), + eq(curSurfacePos[0]), eq(curSurfacePos[1])); + } + + @Test @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API) public void onDisplayChanged_differentDisplay_reparented() { final TestWindowToken token = createTestWindowToken(0, mDisplayContent); |