diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index afc70a448aa8c..08eb2c9b6bbed 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -154,8 +154,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { private final int mCurrentUserId; - private ScreenRotationAnimation mRotationAnimation; - private Drawable mEnterpriseThumbnailDrawable; private BroadcastReceiver mEnterpriseResourceUpdatedReceiver = new BroadcastReceiver() { @@ -340,12 +338,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { final Runnable onAnimFinish = () -> { if (!animations.isEmpty()) return; - - if (mRotationAnimation != null) { - mRotationAnimation.kill(); - mRotationAnimation = null; - } - mAnimations.remove(transition); finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); }; @@ -365,11 +357,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { isSeamlessDisplayChange = isRotationSeamless(info, mDisplayController); final int anim = getRotationAnimation(info); if (!(isSeamlessDisplayChange || anim == ROTATION_ANIMATION_JUMPCUT)) { - mRotationAnimation = new ScreenRotationAnimation(mContext, mSurfaceSession, - mTransactionPool, startTransaction, change, info.getRootLeash(), - anim); - mRotationAnimation.startAnimation(animations, onAnimFinish, - mTransitionAnimationScaleSetting, mMainExecutor, mAnimExecutor); + startRotationAnimation(startTransaction, change, info, anim, animations, + onAnimFinish); continue; } } else { @@ -413,6 +402,13 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { startTransaction.setWindowCrop(change.getLeash(), change.getEndAbsBounds().width(), change.getEndAbsBounds().height()); } + // Rotation change of independent non display window container. + if (change.getParent() == null + && change.getStartRotation() != change.getEndRotation()) { + startRotationAnimation(startTransaction, change, info, + ROTATION_ANIMATION_ROTATE, animations, onAnimFinish); + continue; + } } // Don't animate anything that isn't independent. @@ -543,6 +539,31 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } } + private void startRotationAnimation(SurfaceControl.Transaction startTransaction, + TransitionInfo.Change change, TransitionInfo info, int animHint, + ArrayList animations, Runnable onAnimFinish) { + final ScreenRotationAnimation anim = new ScreenRotationAnimation(mContext, mSurfaceSession, + mTransactionPool, startTransaction, change, info.getRootLeash(), animHint); + // The rotation animation may consist of 3 animations: fade-out screenshot, fade-in real + // content, and background color. The item of "animGroup" will be removed if the sub + // animation is finished. Then if the list becomes empty, the rotation animation is done. + final ArrayList animGroup = new ArrayList<>(3); + final ArrayList animGroupStore = new ArrayList<>(3); + final Runnable finishCallback = () -> { + if (!animGroup.isEmpty()) return; + anim.kill(); + animations.removeAll(animGroupStore); + onAnimFinish.run(); + }; + anim.startAnimation(animGroup, finishCallback, mTransitionAnimationScaleSetting, + mMainExecutor, mAnimExecutor); + for (int i = animGroup.size() - 1; i >= 0; i--) { + final Animator animator = animGroup.get(i); + animGroupStore.add(animator); + animations.add(animator); + } + } + private void edgeExtendWindow(TransitionInfo.Change change, Animation a, SurfaceControl.Transaction startTransaction, SurfaceControl.Transaction finishTransaction) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java index 1005ef1705f0f..a843b2a0ac39f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java @@ -84,7 +84,7 @@ class ScreenRotationAnimation { private final Context mContext; private final TransactionPool mTransactionPool; private final float[] mTmpFloats = new float[9]; - /** The leash of display. */ + /** The leash of the changing window container. */ private final SurfaceControl mSurfaceControl; private final Rect mStartBounds = new Rect(); private final Rect mEndBounds = new Rect(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index e6006c4fc6d0e..cd29741b50641 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -356,7 +356,7 @@ public class Transitions implements RemoteCallable { // Put all the OPEN/SHOW on top if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) { // Wallpaper is always at the bottom. - layer = 0; + layer = -zSplitLine; } else if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) { if (isOpening) { // put on top diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 86e14c2faa040..86fa3560a69e5 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2453,8 +2453,7 @@ class WindowState extends WindowContainer implements WindowManagerP dc.setImeLayeringTarget(null); dc.computeImeTarget(true /* updateImeTarget */); } - if (dc.getImeInputTarget() == this - && (mActivityRecord == null || !mActivityRecord.isRelaunching())) { + if (dc.getImeInputTarget() == this && !inRelaunchingActivity()) { dc.updateImeInputAndControlTarget(null); } @@ -2581,7 +2580,10 @@ class WindowState extends WindowContainer implements WindowManagerP // usually unnoticeable (e.g. covered by rotation animation) and the animation // bounds could be inconsistent, such as depending on when the window applies // its draw transaction with new rotation. - final boolean allowExitAnimation = !getDisplayContent().inTransition(); + final boolean allowExitAnimation = !getDisplayContent().inTransition() + // There will be a new window so the exit animation may not be visible or + // look weird if its orientation is changed. + && !inRelaunchingActivity(); if (wasVisible) { final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE; @@ -3871,7 +3873,7 @@ class WindowState extends WindowContainer implements WindowManagerP // If the activity is scheduled to relaunch, skip sending the resized to ViewRootImpl now // since it will be destroyed anyway. This also prevents the client from receiving // windowing mode change before it is destroyed. - if (mActivityRecord != null && mActivityRecord.isRelaunching()) { + if (inRelaunchingActivity()) { return; } // If this is an activity or wallpaper and is invisible or going invisible, don't report @@ -3957,6 +3959,10 @@ class WindowState extends WindowContainer implements WindowManagerP Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } + boolean inRelaunchingActivity() { + return mActivityRecord != null && mActivityRecord.isRelaunching(); + } + boolean isClientLocal() { return mClient instanceof IWindow.Stub; } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index bbb21f8122c57..72e7e65ae43a3 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -46,6 +46,7 @@ import android.view.DisplayInfo; import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; +import android.view.WindowManager; import android.view.WindowManager.LayoutParams.WindowType; import android.window.WindowContext; @@ -558,6 +559,12 @@ class WindowToken extends WindowContainer { // The window may be detached or detaching. return; } + if (mTransitionController.isShellTransitionsEnabled() + && asActivityRecord() != null && isVisible()) { + // Trigger an activity level rotation transition. + mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_CHANGE, this); + mTransitionController.setReady(this); + } final int originalRotation = getWindowConfiguration().getRotation(); onConfigurationChanged(parent.getConfiguration()); onCancelFixedRotationTransform(originalRotation);