Use getSyncTransaction in SurfaceAnimator and SurfaceFreezer

Otherwise, when we ever use SurfaceFreezer for change transition, it may
have race condition with WM Shell.

Bug: 227533765
Test: verify with ActivityEmbedding app in split screen.
Change-Id: I7027e624303f3fa76dafde0e2372ecc93d15f516
This commit is contained in:
Chris Li
2022-05-10 21:22:15 +08:00
parent c9ab8713b8
commit 410b36e547
8 changed files with 63 additions and 8 deletions

View File

@@ -50,10 +50,15 @@ class Dimmer {
}
@Override
public SurfaceControl.Transaction getPendingTransaction() {
public SurfaceControl.Transaction getSyncTransaction() {
return mHost.getSyncTransaction();
}
@Override
public SurfaceControl.Transaction getPendingTransaction() {
return mHost.getPendingTransaction();
}
@Override
public void commitPendingTransaction() {
mHost.commitPendingTransaction();
@@ -105,7 +110,7 @@ class Dimmer {
void removeSurface() {
if (mDimLayer != null && mDimLayer.isValid()) {
getPendingTransaction().remove(mDimLayer);
getSyncTransaction().remove(mDimLayer);
}
mDimLayer = null;
}

View File

@@ -565,6 +565,7 @@ class ScreenRotationAnimation {
private SimpleSurfaceAnimatable.Builder initializeBuilder() {
return new SimpleSurfaceAnimatable.Builder()
.setSyncTransactionSupplier(mDisplayContent::getSyncTransaction)
.setPendingTransactionSupplier(mDisplayContent::getPendingTransaction)
.setCommitTransactionRunnable(mDisplayContent::commitPendingTransaction)
.setAnimationLeashSupplier(mDisplayContent::makeOverlay);

View File

@@ -41,6 +41,7 @@ public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable {
private final SurfaceControl mParentSurfaceControl;
private final Runnable mCommitTransactionRunnable;
private final Supplier<SurfaceControl.Builder> mAnimationLeashFactory;
private final Supplier<SurfaceControl.Transaction> mSyncTransaction;
private final Supplier<SurfaceControl.Transaction> mPendingTransaction;
private final BiConsumer<SurfaceControl.Transaction, SurfaceControl> mOnAnimationLeashCreated;
private final Consumer<SurfaceControl.Transaction> mOnAnimationLeashLost;
@@ -60,10 +61,16 @@ public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable {
mAnimationLeashFactory = builder.mAnimationLeashFactory;
mOnAnimationLeashCreated = builder.mOnAnimationLeashCreated;
mOnAnimationLeashLost = builder.mOnAnimationLeashLost;
mSyncTransaction = builder.mSyncTransactionSupplier;
mPendingTransaction = builder.mPendingTransactionSupplier;
mOnAnimationFinished = builder.mOnAnimationFinished;
}
@Override
public SurfaceControl.Transaction getSyncTransaction() {
return mSyncTransaction.get();
}
@NonNull
@Override
public SurfaceControl.Transaction getPendingTransaction() {
@@ -159,6 +166,9 @@ public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable {
@Nullable
private Consumer<Runnable> mOnAnimationFinished = null;
@NonNull
private Supplier<SurfaceControl.Transaction> mSyncTransactionSupplier;
@NonNull
private Supplier<SurfaceControl.Transaction> mPendingTransactionSupplier;
@@ -206,6 +216,15 @@ public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable {
return this;
}
/**
* @see SurfaceAnimator.Animatable#getSyncTransaction()
*/
public Builder setSyncTransactionSupplier(
@NonNull Supplier<SurfaceControl.Transaction> syncTransactionSupplier) {
mSyncTransactionSupplier = syncTransactionSupplier;
return this;
}
/**
* @see SurfaceAnimator.Animatable#getPendingTransaction()
*/
@@ -290,6 +309,9 @@ public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable {
}
public SurfaceAnimator.Animatable build() {
if (mSyncTransactionSupplier == null) {
throw new IllegalArgumentException("mSyncTransactionSupplier cannot be null");
}
if (mPendingTransactionSupplier == null) {
throw new IllegalArgumentException("mPendingTransactionSupplier cannot be null");
}

View File

@@ -128,7 +128,7 @@ class SurfaceAnimator {
}
final OnAnimationFinishedCallback animationFinishCallback =
mSurfaceAnimationFinishedCallback;
reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
reset(mAnimatable.getSyncTransaction(), true /* destroyLeash */);
if (staticAnimationFinishedCallback != null) {
staticAnimationFinishedCallback.onAnimationFinished(type, anim);
}
@@ -234,7 +234,7 @@ class SurfaceAnimator {
final boolean delayed = mAnimationStartDelayed;
mAnimationStartDelayed = false;
if (delayed && mAnimation != null) {
mAnimation.startAnimation(mLeash, mAnimatable.getPendingTransaction(),
mAnimation.startAnimation(mLeash, mAnimatable.getSyncTransaction(),
mAnimationType, mInnerAnimationFinishedCallback);
mAnimatable.commitPendingTransaction();
}
@@ -264,7 +264,7 @@ class SurfaceAnimator {
* Cancels any currently running animation.
*/
void cancelAnimation() {
cancelAnimation(mAnimatable.getPendingTransaction(), false /* restarting */,
cancelAnimation(mAnimatable.getSyncTransaction(), false /* restarting */,
true /* forwardCancel */);
mAnimatable.commitPendingTransaction();
}
@@ -319,7 +319,7 @@ class SurfaceAnimator {
return;
}
endDelayingAnimationStart();
final Transaction t = mAnimatable.getPendingTransaction();
final Transaction t = mAnimatable.getSyncTransaction();
cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
mLeash = from.mLeash;
mAnimation = from.mAnimation;
@@ -619,6 +619,12 @@ class SurfaceAnimator {
*/
interface Animatable {
/**
* Use this method instead of {@link #getPendingTransaction()} if the transaction should be
* synchronized with the client.
*/
@NonNull Transaction getSyncTransaction();
/**
* @return The pending transaction that will be committed in the next frame.
*/

View File

@@ -1004,7 +1004,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
void onDisplayChanged(DisplayContent dc) {
if (mDisplayContent != null && mDisplayContent.mChangingContainers.remove(this)) {
// Cancel any change transition queued-up for this container on the old display.
mSurfaceFreezer.unfreeze(getPendingTransaction());
mSurfaceFreezer.unfreeze(getSyncTransaction());
}
mDisplayContent = dc;
if (dc != null && dc != this) {
@@ -2689,6 +2689,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @return {@link #mBLASTSyncTransaction} if available. Otherwise, returns
* {@link #getPendingTransaction()}
*/
@Override
public Transaction getSyncTransaction() {
if (mSyncTransactionCommitCallbackDepth > 0) {
return mSyncTransaction;
@@ -2759,7 +2760,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
void cancelAnimation() {
doAnimationFinished(mSurfaceAnimator.getAnimationType(), mSurfaceAnimator.getAnimation());
mSurfaceAnimator.cancelAnimation();
mSurfaceFreezer.unfreeze(getPendingTransaction());
mSurfaceFreezer.unfreeze(getSyncTransaction());
}
/** Whether we can start change transition with this window and current display status. */

View File

@@ -166,6 +166,11 @@ class WindowContainerThumbnail implements Animatable {
proto.end(token);
}
@Override
public Transaction getSyncTransaction() {
return mWindowContainer.getSyncTransaction();
}
@Override
public Transaction getPendingTransaction() {
return mWindowContainer.getPendingTransaction();

View File

@@ -63,6 +63,11 @@ public class DimmerTests extends WindowTestsBase {
return mControl;
}
@Override
public SurfaceControl.Transaction getSyncTransaction() {
return mTransaction;
}
@Override
public SurfaceControl.Transaction getPendingTransaction() {
return mTransaction;
@@ -101,6 +106,11 @@ public class DimmerTests extends WindowTestsBase {
return mHostControl;
}
@Override
public SurfaceControl.Transaction getSyncTransaction() {
return mHostTransaction;
}
@Override
public SurfaceControl.Transaction getPendingTransaction() {
return mHostTransaction;

View File

@@ -337,6 +337,11 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, wm);
}
@Override
public SurfaceControl.Transaction getSyncTransaction() {
return mTransaction;
}
@Override
public Transaction getPendingTransaction() {
return mTransaction;