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.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;
@@ -282,6 +290,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) {

View File

@@ -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)
*/

View File

@@ -225,11 +225,27 @@ 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) {
// Once a pending enter transition got merged, make sure to append the reset of finishing
// operations to the finish transition.

View File

@@ -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);

View File

@@ -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

View File

@@ -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) {

View File

@@ -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();
}
};
}

View File

@@ -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.
}
}
};
}