diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java index 59f120deeb941..4d87c9583f64e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java @@ -61,6 +61,9 @@ class ActivityEmbeddingAnimationRunner { @VisibleForTesting final ActivityEmbeddingAnimationSpec mAnimationSpec; + @Nullable + private Animator mActiveAnimator; + ActivityEmbeddingAnimationRunner(@NonNull Context context, @NonNull ActivityEmbeddingController controller) { mController = controller; @@ -75,8 +78,10 @@ class ActivityEmbeddingAnimationRunner { // applied to make sure the surface is ready. final List> postStartTransactionCallbacks = new ArrayList<>(); - final Animator animator = createAnimator(info, startTransaction, finishTransaction, + final Animator animator = createAnimator(info, startTransaction, + finishTransaction, () -> mController.onAnimationFinished(transition), postStartTransactionCallbacks); + mActiveAnimator = animator; // Start the animation. if (!postStartTransactionCallbacks.isEmpty()) { @@ -98,6 +103,17 @@ class ActivityEmbeddingAnimationRunner { } } + void cancelAnimationFromMerge() { + if (mActiveAnimator == null) { + Log.e(TAG, + "No active ActivityEmbedding animator running but mergeAnimation is " + + "trying to cancel one." + ); + return; + } + mActiveAnimator.end(); + } + /** * Sets transition animation scale settings value. * @param scale The setting value of transition animation scale. @@ -153,6 +169,7 @@ class ActivityEmbeddingAnimationRunner { adapter.onAnimationEnd(t); } t.apply(); + mActiveAnimator = null; animationFinishCallback.run(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java index bfbddbbe4aa00..fbdbd3e61d926 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java @@ -118,6 +118,13 @@ public class ActivityEmbeddingController implements Transitions.TransitionHandle return true; } + @Override + public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + mAnimationRunner.cancelAnimationFromMerge(); + } + private boolean handleNonEmbeddedChanges(List changes) { final Rect nonClosingEmbeddedArea = new Rect(); for (int i = changes.size() - 1; i >= 0; i--) { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java index a625346e69c0d..4fca8b46a069a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java @@ -65,12 +65,14 @@ public class ActivityEmbeddingAnimationRunnerTests extends ActivityEmbeddingAnim final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0) .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) .build(); - doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any()); + doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), + any()); mAnimRunner.startAnimation(mTransition, info, mStartTransaction, mFinishTransaction); final ArgumentCaptor finishCallback = ArgumentCaptor.forClass(Runnable.class); - verify(mAnimRunner).createAnimator(eq(info), eq(mStartTransaction), eq(mFinishTransaction), + verify(mAnimRunner).createAnimator(eq(info), eq(mStartTransaction), + eq(mFinishTransaction), finishCallback.capture(), any()); verify(mStartTransaction).apply(); verify(mAnimator).start(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java index 4f4f356ef2e61..ab1ccd4599a2d 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java @@ -47,6 +47,7 @@ abstract class ActivityEmbeddingAnimationTestBase extends ShellTestCase { @Mock ShellInit mShellInit; + @Mock Transitions mTransitions; @Mock diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java index b8f615a1855f5..ba34f1f74cd3d 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java @@ -29,9 +29,13 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import android.animation.Animator; +import android.animation.ValueAnimator; import android.graphics.Rect; +import android.view.SurfaceControl; import android.window.TransitionInfo; +import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; @@ -58,7 +62,8 @@ public class ActivityEmbeddingControllerTests extends ActivityEmbeddingAnimation @Before public void setup() { super.setUp(); - doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any()); + doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), + any()); } @Test @@ -182,6 +187,44 @@ public class ActivityEmbeddingControllerTests extends ActivityEmbeddingAnimation verifyNoMoreInteractions(mFinishTransaction); } + @UiThreadTest + @Test + public void testMergeAnimation() { + final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0) + .addChange(createEmbeddedChange( + EMBEDDED_LEFT_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS)) + .build(); + + final ValueAnimator animator = ValueAnimator.ofFloat(0, 1); + animator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + mController.onAnimationFinished(mTransition); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + doReturn(animator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any()); + mController.startAnimation(mTransition, info, mStartTransaction, + mFinishTransaction, mFinishCallback); + verify(mFinishCallback, never()).onTransitionFinished(any(), any()); + mController.mergeAnimation(mTransition, info, new SurfaceControl.Transaction(), + mTransition, + (wct, cb) -> { + }); + verify(mFinishCallback).onTransitionFinished(any(), any()); + } + @Test public void testOnAnimationFinished() { // Should not call finish when there is no transition.