Merge "Pass in finishTransaction to TransitionHandler#startAnimation" into sc-v2-dev

This commit is contained in:
Ben Lin
2021-05-21 06:20:33 +00:00
committed by Android (Google) Code Review
11 changed files with 80 additions and 42 deletions

View File

@@ -204,7 +204,8 @@ public class LegacySplitScreenTransitions implements Transitions.TransitionHandl
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
if (transition != mPendingDismiss && transition != mPendingEnter) {
// If we're not in split-mode, just abort
@@ -239,12 +240,12 @@ public class LegacySplitScreenTransitions implements Transitions.TransitionHandl
if (change.getParent() != null) {
// This is probably reparented, so we want the parent to be immediately visible
final TransitionInfo.Change parentChange = info.getChange(change.getParent());
t.show(parentChange.getLeash());
t.setAlpha(parentChange.getLeash(), 1.f);
startTransaction.show(parentChange.getLeash());
startTransaction.setAlpha(parentChange.getLeash(), 1.f);
// and then animate this layer outside the parent (since, for example, this is
// the home task animating from fullscreen to part-screen).
t.reparent(leash, info.getRootLeash());
t.setLayer(leash, info.getChanges().size() - i);
startTransaction.reparent(leash, info.getRootLeash());
startTransaction.setLayer(leash, info.getChanges().size() - i);
// build the finish reparent/reposition
mFinishTransaction.reparent(leash, parentChange.getLeash());
mFinishTransaction.setPosition(leash,
@@ -271,12 +272,12 @@ public class LegacySplitScreenTransitions implements Transitions.TransitionHandl
if (transition == mPendingEnter
&& mListener.mPrimary.token.equals(change.getContainer())
|| mListener.mSecondary.token.equals(change.getContainer())) {
t.setWindowCrop(leash, change.getStartAbsBounds().width(),
startTransaction.setWindowCrop(leash, change.getStartAbsBounds().width(),
change.getStartAbsBounds().height());
if (mListener.mPrimary.token.equals(change.getContainer())) {
// Move layer to top since we want it above the oversized home task during
// animation even though home task is on top in hierarchy.
t.setLayer(leash, info.getChanges().size() + 1);
startTransaction.setLayer(leash, info.getChanges().size() + 1);
}
}
boolean isOpening = Transitions.isOpeningType(info.getType());
@@ -289,7 +290,7 @@ public class LegacySplitScreenTransitions implements Transitions.TransitionHandl
// Dismissing via snap-to-top/bottom means that the dismissed task is already
// not-visible (usually cropped to oblivion) so immediately set its alpha to 0
// and don't animate it so it doesn't pop-in when reparented.
t.setAlpha(leash, 0.f);
startTransaction.setAlpha(leash, 0.f);
} else {
startExampleAnimation(leash, false /* show */);
}
@@ -311,7 +312,7 @@ public class LegacySplitScreenTransitions implements Transitions.TransitionHandl
}
mSplitScreen.finishEnterSplitTransition(homeIsVisible);
}
t.apply();
startTransaction.apply();
onFinish();
return true;
}

View File

@@ -35,6 +35,7 @@ import android.view.SurfaceControl;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransactionCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -68,7 +69,8 @@ public class PipTransition extends PipTransitionController {
@Override
public boolean startAnimation(@android.annotation.NonNull IBinder transition,
@android.annotation.NonNull TransitionInfo info,
@android.annotation.NonNull SurfaceControl.Transaction t,
@android.annotation.NonNull SurfaceControl.Transaction startTransaction,
@android.annotation.NonNull SurfaceControl.Transaction finishTransaction,
@android.annotation.NonNull Transitions.TransitionFinishCallback finishCallback) {
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -76,7 +78,8 @@ public class PipTransition extends PipTransitionController {
&& change.getTaskInfo().configuration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_PINNED) {
mFinishCallback = finishCallback;
return startEnterAnimation(change.getTaskInfo(), change.getLeash(), t);
return startEnterAnimation(change.getTaskInfo(), change.getLeash(),
startTransaction, finishTransaction);
}
}
return false;
@@ -96,17 +99,25 @@ public class PipTransition extends PipTransitionController {
WindowContainerTransaction wct = new WindowContainerTransaction();
prepareFinishResizeTransaction(taskInfo, destinationBounds,
direction, tx, wct);
mFinishCallback.onTransitionFinished(wct, null);
mFinishCallback.onTransitionFinished(wct, new WindowContainerTransactionCallback() {
@Override
public void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t) {
t.merge(tx);
t.apply();
}
});
finishResizeForMenu(destinationBounds);
}
private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
final SurfaceControl.Transaction t) {
final SurfaceControl.Transaction startTransaction,
final SurfaceControl.Transaction finishTransaction) {
setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams,
taskInfo.topActivityInfo);
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
final Rect currentBounds = taskInfo.configuration.windowConfiguration.getBounds();
PipAnimationController.PipTransitionAnimator animator;
finishTransaction.setPosition(leash, destinationBounds.left, destinationBounds.top);
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
final Rect sourceHintRect =
PipBoundsAlgorithm.getValidSourceHintRect(
@@ -115,8 +126,8 @@ public class PipTransition extends PipTransitionController {
currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
0 /* startingAngle */, Surface.ROTATION_0);
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
t.setAlpha(leash, 0f);
t.apply();
startTransaction.setAlpha(leash, 0f);
startTransaction.apply();
animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
0f, 1f);
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
@@ -158,6 +169,5 @@ public class PipTransition extends PipTransitionController {
}
wct.setBounds(taskInfo.token, taskBounds);
wct.setBoundsChangeTransaction(taskInfo.token, tx);
}
}

View File

@@ -58,7 +58,8 @@ public class TvPipTransition extends PipTransitionController {
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@android.annotation.NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
return false;
}

View File

@@ -84,17 +84,19 @@ class SplitScreenTransitions {
}
void playAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback,
@NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot) {
mFinishCallback = finishCallback;
mAnimatingTransition = transition;
if (mRemoteHandler != null) {
mRemoteHandler.startAnimation(transition, info, t, mRemoteFinishCB);
mRemoteHandler.startAnimation(transition, info, startTransaction, finishTransaction,
mRemoteFinishCB);
mRemoteHandler = null;
return;
}
playInternalAnimation(transition, info, t, mainRoot, sideRoot);
playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot);
}
private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,

View File

@@ -672,7 +672,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public boolean startAnimation(@NonNull IBinder transition,
@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
if (transition != mSplitTransitions.mPendingDismiss
&& transition != mSplitTransitions.mPendingEnter) {
@@ -717,14 +718,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
boolean shouldAnimate = true;
if (mSplitTransitions.mPendingEnter == transition) {
shouldAnimate = startPendingEnterAnimation(transition, info, t);
shouldAnimate = startPendingEnterAnimation(transition, info, startTransaction);
} else if (mSplitTransitions.mPendingDismiss == transition) {
shouldAnimate = startPendingDismissAnimation(transition, info, t);
shouldAnimate = startPendingDismissAnimation(transition, info, startTransaction);
}
if (!shouldAnimate) return false;
mSplitTransitions.playAnimation(transition, info, t, finishCallback,
mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
mSplitTransitions.playAnimation(transition, info, startTransaction, finishTransaction,
finishCallback, mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
return true;
}

View File

@@ -84,7 +84,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
"start default transition animation, info = %s", info);
@@ -104,12 +105,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getMode() == TRANSIT_CHANGE) {
// No default animation for this, so just update bounds/position.
t.setPosition(change.getLeash(),
startTransaction.setPosition(change.getLeash(),
change.getEndAbsBounds().left - change.getEndRelOffset().x,
change.getEndAbsBounds().top - change.getEndRelOffset().y);
if (change.getTaskInfo() != null) {
// Skip non-tasks since those usually have null bounds.
t.setWindowCrop(change.getLeash(),
startTransaction.setWindowCrop(change.getLeash(),
change.getEndAbsBounds().width(), change.getEndAbsBounds().height());
}
}
@@ -122,7 +123,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
startAnimInternal(animations, a, change.getLeash(), onAnimFinish);
}
}
t.apply();
startTransaction.apply();
// run finish now in-case there are no animations
onAnimFinish.run();
return true;

View File

@@ -57,7 +57,8 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
if (mTransition != transition) return false;
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Using registered One-shot remote"
@@ -82,7 +83,7 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
if (mRemote.asBinder() != null) {
mRemote.asBinder().linkToDeath(remoteDied, 0 /* flags */);
}
mRemote.startAnimation(transition, info, t, cb);
mRemote.startAnimation(transition, info, startTransaction, cb);
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);
if (mRemote.asBinder() != null) {

View File

@@ -99,7 +99,8 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
IRemoteTransition pendingRemote = mRequestedRemotes.get(transition);
if (pendingRemote == null) {
@@ -146,7 +147,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
if (remote.asBinder() != null) {
remote.asBinder().linkToDeath(remoteDied, 0 /* flags */);
}
remote.startAnimation(transition, info, t, cb);
remote.startAnimation(transition, info, startTransaction, cb);
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);
if (remote.asBinder() != null) {

View File

@@ -382,7 +382,7 @@ public class Transitions implements RemoteCallable<Transitions> {
}
boolean startAnimation(@NonNull ActiveTransition active, TransitionHandler handler) {
return handler.startAnimation(active.mToken, active.mInfo, active.mStartT,
return handler.startAnimation(active.mToken, active.mInfo, active.mStartT, active.mFinishT,
(wct, cb) -> onFinish(active.mToken, wct, cb));
}
@@ -566,12 +566,19 @@ public class Transitions implements RemoteCallable<Transitions> {
* Starts a transition animation. This is always called if handleRequest returned non-null
* for a particular transition. Otherwise, it is only called if no other handler before
* it handled the transition.
*
* @param startTransaction the transaction given to the handler to be applied before the
* transition animation. Note the handler is expected to call on
* {@link SurfaceControl.Transaction#apply()} for startTransaction.
* @param finishTransaction the transaction given to the handler to be applied after the
* transition animation. Unlike startTransaction, the handler is NOT
* expected to apply this transaction. The Transition system will
* apply it when finishCallback is called.
* @param finishCallback Call this when finished. This MUST be called on main thread.
* @return true if transition was handled, false if not (falls-back to default).
*/
boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull TransitionFinishCallback finishCallback);
/**

View File

@@ -130,6 +130,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
boolean accepted = mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
assertTrue(accepted);
@@ -167,6 +168,7 @@ public class SplitTransitionTests extends ShellTestCase {
info.addChange(hideChange);
mSideStage.onTaskAppeared(newTask, createMockSurface());
boolean accepted = mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
assertFalse(accepted);
@@ -187,6 +189,7 @@ public class SplitTransitionTests extends ShellTestCase {
info.addChange(closeChange);
mSideStage.onTaskVanished(newTask);
accepted = mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
assertFalse(accepted);
@@ -222,6 +225,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskVanished(mMainChild);
mSideStage.onTaskVanished(mSideChild);
mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
assertFalse(mStageCoordinator.isSplitScreenVisible());
@@ -243,6 +247,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskVanished(mMainChild);
mSideStage.onTaskVanished(mSideChild);
boolean accepted = mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
assertTrue(accepted);
@@ -273,6 +278,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskVanished(mMainChild);
mSideStage.onTaskVanished(mSideChild);
boolean accepted = mStageCoordinator.startAnimation(transition, info,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
assertTrue(accepted);
@@ -297,6 +303,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
mStageCoordinator.startAnimation(enterTransit, enterInfo,
mock(SurfaceControl.Transaction.class),
mock(SurfaceControl.Transaction.class),
mock(Transitions.TransitionFinishCallback.class));
mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction());
@@ -335,7 +342,8 @@ public class SplitTransitionTests extends ShellTestCase {
@Override
public void startAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
SurfaceControl.Transaction startTransaction,
IRemoteTransitionFinishedCallback finishCallback)
throws RemoteException {
mCalled = true;
finishCallback.onTransitionFinished(mRemoteFinishWCT);

View File

@@ -127,11 +127,13 @@ public class ShellTransitionTests {
TestTransitionHandler testHandler = new TestTransitionHandler() {
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
for (TransitionInfo.Change chg : info.getChanges()) {
if (chg.getMode() == TRANSIT_CHANGE) {
return super.startAnimation(transition, info, t, finishCallback);
return super.startAnimation(transition, info, startTransaction,
finishTransaction, finishCallback);
}
}
return false;
@@ -358,9 +360,11 @@ public class ShellTransitionTests {
oneShot.setTransition(transitToken);
IBinder anotherToken = new Binder();
assertFalse(oneShot.startAnimation(anotherToken, new TransitionInfo(transitType, 0),
mock(SurfaceControl.Transaction.class), testFinish));
mock(SurfaceControl.Transaction.class), mock(SurfaceControl.Transaction.class),
testFinish));
assertTrue(oneShot.startAnimation(transitToken, new TransitionInfo(transitType, 0),
mock(SurfaceControl.Transaction.class), testFinish));
mock(SurfaceControl.Transaction.class), mock(SurfaceControl.Transaction.class),
testFinish));
}
@Test
@@ -477,7 +481,8 @@ public class ShellTransitionTests {
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
mFinishes.add(finishCallback);
return true;