Loading services/core/java/com/android/server/wm/DisplayContent.java +10 −27 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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(). Loading @@ -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(); } } 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); } getSyncTransaction().unsetFixedTransformHint(mSurfaceControl); scheduleAnimation(); mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation); Loading Loading @@ -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 Loading Loading @@ -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, Loading services/core/java/com/android/server/wm/DisplayRotation.java +0 −87 Original line number Diff line number Diff line Loading @@ -167,19 +167,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. * Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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; } Loading @@ -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; Loading services/core/java/com/android/server/wm/PinnedTaskController.java +5 −97 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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). */ Loading @@ -232,81 +219,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. Loading @@ -321,7 +233,6 @@ class PinnedTaskController { mFreezingTaskConfig = false; mDeferOrientationChanging = false; mDestRotatedBounds = null; mPipTransaction = null; } /** Loading Loading @@ -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); Loading services/core/java/com/android/server/wm/Transition.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading services/core/java/com/android/server/wm/WindowManagerService.java +0 −1 Original line number Diff line number Diff line Loading @@ -2132,7 +2132,6 @@ public class WindowManagerService extends IWindowManager.Stub } final DisplayContent dc = win.getDisplayContent(); dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */); win.resetAppOpsState(); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +10 −27 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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(). Loading @@ -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(); } } 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); } getSyncTransaction().unsetFixedTransformHint(mSurfaceControl); scheduleAnimation(); mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation); Loading Loading @@ -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 Loading Loading @@ -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, Loading
services/core/java/com/android/server/wm/DisplayRotation.java +0 −87 Original line number Diff line number Diff line Loading @@ -167,19 +167,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. * Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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; } Loading @@ -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; Loading
services/core/java/com/android/server/wm/PinnedTaskController.java +5 −97 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -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). */ Loading @@ -232,81 +219,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. Loading @@ -321,7 +233,6 @@ class PinnedTaskController { mFreezingTaskConfig = false; mDeferOrientationChanging = false; mDestRotatedBounds = null; mPipTransaction = null; } /** Loading Loading @@ -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); Loading
services/core/java/com/android/server/wm/Transition.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +0 −1 Original line number Diff line number Diff line Loading @@ -2132,7 +2132,6 @@ public class WindowManagerService extends IWindowManager.Stub } final DisplayContent dc = win.getDisplayContent(); dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */); win.resetAppOpsState(); Loading