Merge "End transitions when receiving merge request" into tm-qpr-dev

This commit is contained in:
Evan Rosky
2022-06-23 16:59:27 +00:00
committed by Android (Google) Code Review
8 changed files with 137 additions and 11 deletions

View File

@@ -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.TRANSIT_REMOVE_PIP;
import static com.android.wm.shell.transition.Transitions.isOpeningType; import static com.android.wm.shell.transition.Transitions.isOpeningType;
import android.animation.Animator;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.TaskInfo; import android.app.TaskInfo;
import android.content.Context; import android.content.Context;
@@ -248,6 +249,13 @@ public class PipTransition extends PipTransitionController {
return false; 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 */ /** Helper to identify whether this handler is currently the one playing an animation */
private boolean isAnimatingLocally() { private boolean isAnimatingLocally() {
return mFinishTransaction != null; return mFinishTransaction != null;
@@ -282,6 +290,13 @@ public class PipTransition extends PipTransitionController {
} }
} }
@Override
public void end() {
Animator animator = mPipAnimationController.getCurrentAnimator();
if (animator == null) return;
animator.end();
}
@Override @Override
public boolean handleRotateDisplay(int startRotation, int endRotation, public boolean handleRotateDisplay(int startRotation, int endRotation,
WindowContainerTransaction wct) { WindowContainerTransaction wct) {

View File

@@ -237,6 +237,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH
@NonNull final Transitions.TransitionFinishCallback finishCallback) { @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) * Callback interface for PiP transitions (both from and to PiP mode)
*/ */

View File

@@ -225,11 +225,27 @@ class SplitScreenTransitions {
void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) { IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) {
if (mergeTarget == mAnimatingTransition && mActiveRemoteHandler != null) { if (mergeTarget != mAnimatingTransition) return;
if (mActiveRemoteHandler != null) {
mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback); 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) { void onTransitionMerged(@NonNull IBinder transition) {
// Once a pending enter transition got merged, make sure to append the reset of finishing // Once a pending enter transition got merged, make sure to append the reset of finishing
// operations to the finish transition. // operations to the finish transition.

View File

@@ -1521,6 +1521,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.mergeAnimation(transition, info, t, mergeTarget, finishCallback); mSplitTransitions.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
} }
/** Jump the current transition animation to the end. */
public boolean end() {
return mSplitTransitions.end();
}
@Override @Override
public void onTransitionMerged(@NonNull IBinder transition) { public void onTransitionMerged(@NonNull IBinder transition) {
mSplitTransitions.onTransitionMerged(transition); mSplitTransitions.onTransitionMerged(transition);

View File

@@ -53,10 +53,18 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
private static class MixedTransition { private static class MixedTransition {
static final int TYPE_ENTER_PIP_FROM_SPLIT = 1; 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; final int mType;
int mAnimType = 0;
final IBinder mTransition; final IBinder mTransition;
Transitions.TransitionFinishCallback mFinishCallback = null; Transitions.TransitionFinishCallback mFinishCallback = null;
Transitions.TransitionHandler mLeftoversHandler = null;
/** /**
* Mixed transitions are made up of multiple "parts". This keeps track of how many * 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; MixedTransition mixed = null;
for (int i = mActiveTransitions.size() - 1; i >= 0; --i) { for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
if (mActiveTransitions.get(i).mTransition != transition) continue; if (mActiveTransitions.get(i).mTransition != transition) continue;
mixed = mActiveTransitions.remove(i); mixed = mActiveTransitions.get(i);
break; break;
} }
if (mixed == null) return false; if (mixed == null) return false;
@@ -137,6 +145,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
return animateEnterPipFromSplit(mixed, info, startTransaction, finishTransaction, return animateEnterPipFromSplit(mixed, info, startTransaction, finishTransaction,
finishCallback); finishCallback);
} else { } else {
mActiveTransitions.remove(mixed);
throw new IllegalStateException("Starting mixed animation without a known mixed type? " throw new IllegalStateException("Starting mixed animation without a known mixed type? "
+ mixed.mType); + mixed.mType);
} }
@@ -178,6 +187,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
--mixed.mInFlightSubAnimations; --mixed.mInFlightSubAnimations;
if (mixed.mInFlightSubAnimations > 0) return; if (mixed.mInFlightSubAnimations > 0) return;
mActiveTransitions.remove(mixed);
if (isGoingHome) { if (isGoingHome) {
mSplitHandler.onTransitionAnimationComplete(); mSplitHandler.onTransitionAnimationComplete();
} }
@@ -216,8 +226,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
finishCB); finishCB);
// Dispatch the rest of the transition normally. This will most-likely be taken by // Dispatch the rest of the transition normally. This will most-likely be taken by
// recents or default handler. // recents or default handler.
mPlayer.dispatchTransition(mixed.mTransition, everythingElse, otherStartT, mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, everythingElse,
finishTransaction, finishCB, this); otherStartT, finishTransaction, finishCB, this);
} else { } else {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Not leaving split, so just " ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Not leaving split, so just "
+ "forward animation to Pip-Handler."); + "forward animation to Pip-Handler.");
@@ -235,6 +245,32 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@NonNull Transitions.TransitionFinishCallback finishCallback) { @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 @Override

View File

@@ -523,6 +523,18 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return true; 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, private void edgeExtendWindow(TransitionInfo.Change change,
Animation a, SurfaceControl.Transaction startTransaction, Animation a, SurfaceControl.Transaction startTransaction,
SurfaceControl.Transaction finishTransaction) { SurfaceControl.Transaction finishTransaction) {

View File

@@ -114,6 +114,8 @@ public class RemoteAnimationAdapterCompat {
private static IRemoteTransition.Stub wrapRemoteTransition( private static IRemoteTransition.Stub wrapRemoteTransition(
final RemoteAnimationRunnerCompat remoteAnimationAdapter) { final RemoteAnimationRunnerCompat remoteAnimationAdapter) {
return new IRemoteTransition.Stub() { return new IRemoteTransition.Stub() {
final ArrayMap<IBinder, Runnable> mFinishRunnables = new ArrayMap<>();
@Override @Override
public void startAnimation(IBinder token, TransitionInfo info, public void startAnimation(IBinder token, TransitionInfo info,
SurfaceControl.Transaction t, SurfaceControl.Transaction t,
@@ -229,19 +231,32 @@ public class RemoteAnimationAdapterCompat {
} }
} }
}; };
synchronized (mFinishRunnables) {
mFinishRunnables.put(token, animationFinishedCallback);
}
// TODO(bc-unlcok): Pass correct transit type. // TODO(bc-unlcok): Pass correct transit type.
remoteAnimationAdapter.onAnimationStart( remoteAnimationAdapter.onAnimationStart(TRANSIT_OLD_NONE,
TRANSIT_OLD_NONE, appsCompat, wallpapersCompat, nonAppsCompat, () -> {
appsCompat, wallpapersCompat, nonAppsCompat, synchronized (mFinishRunnables) {
animationFinishedCallback); if (mFinishRunnables.remove(token) == null) return;
}
animationFinishedCallback.run();
});
} }
@Override @Override
public void mergeAnimation(IBinder token, TransitionInfo info, public void mergeAnimation(IBinder token, TransitionInfo info,
SurfaceControl.Transaction t, IBinder mergeTarget, SurfaceControl.Transaction t, IBinder mergeTarget,
IRemoteTransitionFinishedCallback finishCallback) { IRemoteTransitionFinishedCallback finishCallback) {
// TODO: hook up merge to recents onTaskAppeared if applicable. Until then, ignore // TODO: hook up merge to recents onTaskAppeared if applicable. Until then, adapt
// any incoming merges. // to legacy cancel.
final Runnable finishRunnable;
synchronized (mFinishRunnables) {
finishRunnable = mFinishRunnables.remove(mergeTarget);
}
if (finishRunnable == null) return;
remoteAnimationAdapter.onAnimationCancelled();
finishRunnable.run();
} }
}; };
} }

View File

@@ -55,6 +55,7 @@ import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.Trace; import android.os.Trace;
import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import android.util.Slog; import android.util.Slog;
import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationFinishedCallback;
@@ -191,6 +192,9 @@ public class KeyguardService extends Service {
private static IRemoteTransition wrap(IRemoteAnimationRunner runner) { private static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
return new IRemoteTransition.Stub() { return new IRemoteTransition.Stub() {
final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
new ArrayMap<>();
@Override @Override
public void startAnimation(IBinder transition, TransitionInfo info, public void startAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
@@ -205,11 +209,17 @@ public class KeyguardService extends Service {
t.setAlpha(change.getLeash(), 1.0f); t.setAlpha(change.getLeash(), 1.0f);
} }
t.apply(); t.apply();
synchronized (mFinishCallbacks) {
mFinishCallbacks.put(transition, finishCallback);
}
runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps), runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps),
apps, wallpapers, nonApps, apps, wallpapers, nonApps,
new IRemoteAnimationFinishedCallback.Stub() { new IRemoteAnimationFinishedCallback.Stub() {
@Override @Override
public void onAnimationFinished() throws RemoteException { public void onAnimationFinished() throws RemoteException {
synchronized (mFinishCallbacks) {
if (mFinishCallbacks.remove(transition) == null) return;
}
Slog.d(TAG, "Finish IRemoteAnimationRunner."); Slog.d(TAG, "Finish IRemoteAnimationRunner.");
finishCallback.onTransitionFinished(null /* wct */, null /* t */); finishCallback.onTransitionFinished(null /* wct */, null /* t */);
} }
@@ -220,7 +230,20 @@ public class KeyguardService extends Service {
public void mergeAnimation(IBinder transition, TransitionInfo info, public void mergeAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t, IBinder mergeTarget, SurfaceControl.Transaction t, IBinder mergeTarget,
IRemoteTransitionFinishedCallback finishCallback) { 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.
}
} }
}; };
} }