diff options
| author | 2022-06-23 16:59:27 +0000 | |
|---|---|---|
| committer | 2022-06-23 16:59:27 +0000 | |
| commit | dfbcd379bbf3cacc23fc4e91e2d3303afa90aeab (patch) | |
| tree | f5b53938a53971b02b81adbddcd1ae537a7fa216 | |
| parent | 1e43c3b429ab4199a353b7e881c4635cec437af7 (diff) | |
| parent | f0ff75fd249fc775463a64e11cf434ce5fd1f6a4 (diff) | |
Merge "End transitions when receiving merge request" into tm-qpr-dev
8 files changed, 137 insertions, 11 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 28427a808d90..c80c14f353d0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -42,6 +42,7 @@ import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SP import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP; import static com.android.wm.shell.transition.Transitions.isOpeningType; +import android.animation.Animator; import android.app.ActivityManager; import android.app.TaskInfo; import android.content.Context; @@ -248,6 +249,13 @@ public class PipTransition extends PipTransitionController { return false; } + @Override + public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + end(); + } + /** Helper to identify whether this handler is currently the one playing an animation */ private boolean isAnimatingLocally() { return mFinishTransaction != null; @@ -283,6 +291,13 @@ public class PipTransition extends PipTransitionController { } @Override + public void end() { + Animator animator = mPipAnimationController.getCurrentAnimator(); + if (animator == null) return; + animator.end(); + } + + @Override public boolean handleRotateDisplay(int startRotation, int endRotation, WindowContainerTransaction wct) { if (mRequestedEnterTransition != null && mOneShotAnimationType == ANIM_TYPE_ALPHA) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index d3f69f6762f9..a43b6043908b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -237,6 +237,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH @NonNull final Transitions.TransitionFinishCallback finishCallback) { } + /** End the currently-playing PiP animation. */ + public void end() { + } + /** * Callback interface for PiP transitions (both from and to PiP mode) */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java index f7057d454df9..e55729a883e0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java @@ -225,9 +225,25 @@ class SplitScreenTransitions { void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) { - if (mergeTarget == mAnimatingTransition && mActiveRemoteHandler != null) { + if (mergeTarget != mAnimatingTransition) return; + if (mActiveRemoteHandler != null) { mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback); + } else { + for (int i = mAnimations.size() - 1; i >= 0; --i) { + final Animator anim = mAnimations.get(i); + mTransitions.getAnimExecutor().execute(anim::end); + } + } + } + + boolean end() { + // If its remote, there's nothing we can do right now. + if (mActiveRemoteHandler != null) return false; + for (int i = mAnimations.size() - 1; i >= 0; --i) { + final Animator anim = mAnimations.get(i); + mTransitions.getAnimExecutor().execute(anim::end); } + return true; } void onTransitionMerged(@NonNull IBinder transition) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 6cfb700fc16a..4e7b20e3ae84 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -1521,6 +1521,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitTransitions.mergeAnimation(transition, info, t, mergeTarget, finishCallback); } + /** Jump the current transition animation to the end. */ + public boolean end() { + return mSplitTransitions.end(); + } + @Override public void onTransitionMerged(@NonNull IBinder transition) { mSplitTransitions.onTransitionMerged(transition); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java index 1ffe26df729f..7234d559e153 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java @@ -53,10 +53,18 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { private static class MixedTransition { static final int TYPE_ENTER_PIP_FROM_SPLIT = 1; + /** The default animation for this mixed transition. */ + static final int ANIM_TYPE_DEFAULT = 0; + + /** For ENTER_PIP_FROM_SPLIT, indicates that this is a to-home animation. */ + static final int ANIM_TYPE_GOING_HOME = 1; + final int mType; + int mAnimType = 0; final IBinder mTransition; Transitions.TransitionFinishCallback mFinishCallback = null; + Transitions.TransitionHandler mLeftoversHandler = null; /** * Mixed transitions are made up of multiple "parts". This keeps track of how many @@ -128,7 +136,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { MixedTransition mixed = null; for (int i = mActiveTransitions.size() - 1; i >= 0; --i) { if (mActiveTransitions.get(i).mTransition != transition) continue; - mixed = mActiveTransitions.remove(i); + mixed = mActiveTransitions.get(i); break; } if (mixed == null) return false; @@ -137,6 +145,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { return animateEnterPipFromSplit(mixed, info, startTransaction, finishTransaction, finishCallback); } else { + mActiveTransitions.remove(mixed); throw new IllegalStateException("Starting mixed animation without a known mixed type? " + mixed.mType); } @@ -178,6 +187,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; if (mixed.mInFlightSubAnimations > 0) return; + mActiveTransitions.remove(mixed); if (isGoingHome) { mSplitHandler.onTransitionAnimationComplete(); } @@ -216,8 +226,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { finishCB); // Dispatch the rest of the transition normally. This will most-likely be taken by // recents or default handler. - mPlayer.dispatchTransition(mixed.mTransition, everythingElse, otherStartT, - finishTransaction, finishCB, this); + mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, everythingElse, + otherStartT, finishTransaction, finishCB, this); } else { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Not leaving split, so just " + "forward animation to Pip-Handler."); @@ -235,6 +245,32 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, @NonNull Transitions.TransitionFinishCallback finishCallback) { + for (int i = 0; i < mActiveTransitions.size(); ++i) { + if (mActiveTransitions.get(i) != mergeTarget) continue; + MixedTransition mixed = mActiveTransitions.get(i); + if (mixed.mInFlightSubAnimations <= 0) { + // Already done, so no need to end it. + return; + } + if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) { + if (mixed.mAnimType == MixedTransition.ANIM_TYPE_GOING_HOME) { + boolean ended = mSplitHandler.end(); + // If split couldn't end (because it is remote), then don't end everything else + // since we have to play out the animation anyways. + if (!ended) return; + mPipHandler.end(); + if (mixed.mLeftoversHandler != null) { + mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget, + finishCallback); + } + } else { + mPipHandler.end(); + } + } else { + throw new IllegalStateException("Playing a mixed transition with unknown type? " + + mixed.mType); + } + } } @Override 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 c3eaa8ee1da0..05e5b8e66a00 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 @@ -523,6 +523,18 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { return true; } + @Override + public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + ArrayList<Animator> anims = mAnimations.get(mergeTarget); + if (anims == null) return; + for (int i = anims.size() - 1; i >= 0; --i) { + final Animator anim = anims.get(i); + mAnimExecutor.execute(anim::end); + } + } + private void edgeExtendWindow(TransitionInfo.Change change, Animation a, SurfaceControl.Transaction startTransaction, SurfaceControl.Transaction finishTransaction) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java index 76a09b38036c..302ba8444f05 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java @@ -114,6 +114,8 @@ public class RemoteAnimationAdapterCompat { private static IRemoteTransition.Stub wrapRemoteTransition( final RemoteAnimationRunnerCompat remoteAnimationAdapter) { return new IRemoteTransition.Stub() { + final ArrayMap<IBinder, Runnable> mFinishRunnables = new ArrayMap<>(); + @Override public void startAnimation(IBinder token, TransitionInfo info, SurfaceControl.Transaction t, @@ -229,19 +231,32 @@ public class RemoteAnimationAdapterCompat { } } }; + synchronized (mFinishRunnables) { + mFinishRunnables.put(token, animationFinishedCallback); + } // TODO(bc-unlcok): Pass correct transit type. - remoteAnimationAdapter.onAnimationStart( - TRANSIT_OLD_NONE, - appsCompat, wallpapersCompat, nonAppsCompat, - animationFinishedCallback); + remoteAnimationAdapter.onAnimationStart(TRANSIT_OLD_NONE, + appsCompat, wallpapersCompat, nonAppsCompat, () -> { + synchronized (mFinishRunnables) { + if (mFinishRunnables.remove(token) == null) return; + } + animationFinishedCallback.run(); + }); } @Override public void mergeAnimation(IBinder token, TransitionInfo info, SurfaceControl.Transaction t, IBinder mergeTarget, IRemoteTransitionFinishedCallback finishCallback) { - // TODO: hook up merge to recents onTaskAppeared if applicable. Until then, ignore - // any incoming merges. + // TODO: hook up merge to recents onTaskAppeared if applicable. Until then, adapt + // to legacy cancel. + final Runnable finishRunnable; + synchronized (mFinishRunnables) { + finishRunnable = mFinishRunnables.remove(mergeTarget); + } + if (finishRunnable == null) return; + remoteAnimationAdapter.onAnimationCancelled(); + finishRunnable.run(); } }; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index b96eee717260..e342896e1644 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -55,6 +55,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; import android.os.Trace; +import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.view.IRemoteAnimationFinishedCallback; @@ -191,6 +192,9 @@ public class KeyguardService extends Service { private static IRemoteTransition wrap(IRemoteAnimationRunner runner) { return new IRemoteTransition.Stub() { + final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks = + new ArrayMap<>(); + @Override public void startAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) @@ -205,11 +209,17 @@ public class KeyguardService extends Service { t.setAlpha(change.getLeash(), 1.0f); } t.apply(); + synchronized (mFinishCallbacks) { + mFinishCallbacks.put(transition, finishCallback); + } runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps), apps, wallpapers, nonApps, new IRemoteAnimationFinishedCallback.Stub() { @Override public void onAnimationFinished() throws RemoteException { + synchronized (mFinishCallbacks) { + if (mFinishCallbacks.remove(transition) == null) return; + } Slog.d(TAG, "Finish IRemoteAnimationRunner."); finishCallback.onTransitionFinished(null /* wct */, null /* t */); } @@ -220,7 +230,20 @@ public class KeyguardService extends Service { public void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IBinder mergeTarget, IRemoteTransitionFinishedCallback finishCallback) { - + try { + final IRemoteTransitionFinishedCallback origFinishCB; + synchronized (mFinishCallbacks) { + origFinishCB = mFinishCallbacks.remove(transition); + } + if (origFinishCB == null) { + // already finished (or not started yet), so do nothing. + return; + } + runner.onAnimationCancelled(); + origFinishCB.onTransitionFinished(null /* wct */, null /* t */); + } catch (RemoteException e) { + // nothing, we'll just let it finish on its own I guess. + } } }; } |