diff options
| author | 2024-07-01 06:44:22 +0000 | |
|---|---|---|
| committer | 2024-07-01 06:44:22 +0000 | |
| commit | e4b2d224e90c1db8ff9e7e54c8f7ac97f29a155f (patch) | |
| tree | 070b0ea007de81c054314c37ba701b0698498320 | |
| parent | e335107f7a29ff1aaaac689354142989b779dcf2 (diff) | |
| parent | 73c4a2d1c695f3b2badc1138bceae9966001f450 (diff) | |
Merge "Allow custom animations for AE change transitions behind a flag." into main
3 files changed, 70 insertions, 13 deletions
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 5a42817e839b..d270d2b4ccf1 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 @@ -265,7 +265,7 @@ class ActivityEmbeddingAnimationRunner { for (TransitionInfo.Change change : openingChanges) { final Animation animation = animationProvider.get(info, change, openingWholeScreenBounds); - if (animation.getDuration() == 0) { + if (shouldUseJumpCutForAnimation(animation)) { continue; } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( @@ -290,7 +290,7 @@ class ActivityEmbeddingAnimationRunner { } final Animation animation = animationProvider.get(info, change, closingWholeScreenBounds); - if (animation.getDuration() == 0) { + if (shouldUseJumpCutForAnimation(animation)) { continue; } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( @@ -444,8 +444,16 @@ class ActivityEmbeddingAnimationRunner { calculateParentBounds(change, boundsAnimationChange, parentBounds); // There are two animations in the array. The first one is for the start leash // (snapshot), and the second one is for the end leash (TaskFragment). - final Animation[] animations = mAnimationSpec.createChangeBoundsChangeAnimations(change, - parentBounds); + final Animation[] animations = + mAnimationSpec.createChangeBoundsChangeAnimations(info, change, parentBounds); + // Jump cut if either animation has zero for duration. + if (Flags.activityEmbeddingAnimationCustomizationFlag()) { + for (Animation animation : animations) { + if (shouldUseJumpCutForAnimation(animation)) { + return new ArrayList<>(); + } + } + } // Keep track as we might need to add background color for the animation. // Although there may be multiple change animation, record one of them is sufficient // because the background color will be added to the root leash for the whole animation. @@ -492,12 +500,19 @@ class ActivityEmbeddingAnimationRunner { // window without bounds change. animation = ActivityEmbeddingAnimationSpec.createNoopAnimation(change); } else if (TransitionUtil.isClosingType(change.getMode())) { - animation = mAnimationSpec.createChangeBoundsCloseAnimation(change, parentBounds); + animation = + mAnimationSpec.createChangeBoundsCloseAnimation(info, change, parentBounds); shouldShowBackgroundColor = false; } else { - animation = mAnimationSpec.createChangeBoundsOpenAnimation(change, parentBounds); + animation = + mAnimationSpec.createChangeBoundsOpenAnimation(info, change, parentBounds); shouldShowBackgroundColor = false; } + if (Flags.activityEmbeddingAnimationCustomizationFlag()) { + if (shouldUseJumpCutForAnimation(animation)) { + return new ArrayList<>(); + } + } adapters.add(new ActivityEmbeddingAnimationAdapter(animation, change, TransitionUtil.getRootFor(change, info))); } @@ -640,6 +655,12 @@ class ActivityEmbeddingAnimationRunner { return true; } + /** Whether or not to use jump cut based on the animation. */ + @VisibleForTesting + static boolean shouldUseJumpCutForAnimation(@NonNull Animation animation) { + return animation.getDuration() == 0; + } + /** Updates the changes to end states in {@code startTransaction} for jump cut animation. */ private void prepareForJumpCut(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java index 8d49614b021b..f49b90d08a75 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java @@ -46,7 +46,6 @@ import com.android.window.flags.Flags; import com.android.wm.shell.shared.TransitionUtil; /** Animation spec for ActivityEmbedding transition. */ -// TODO(b/206557124): provide an easier way to customize animation class ActivityEmbeddingAnimationSpec { private static final String TAG = "ActivityEmbeddingAnimSpec"; @@ -95,8 +94,14 @@ class ActivityEmbeddingAnimationSpec { /** Animation for window that is opening in a change transition. */ @NonNull - Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change, - @NonNull Rect parentBounds) { + Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo info, + @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) { + if (Flags.activityEmbeddingAnimationCustomizationFlag()) { + final Animation customAnimation = loadCustomAnimation(info, change); + if (customAnimation != null) { + return customAnimation; + } + } // Use end bounds for opening. final Rect bounds = change.getEndAbsBounds(); final int startLeft; @@ -123,8 +128,14 @@ class ActivityEmbeddingAnimationSpec { /** Animation for window that is closing in a change transition. */ @NonNull - Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo.Change change, - @NonNull Rect parentBounds) { + Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo info, + @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) { + if (Flags.activityEmbeddingAnimationCustomizationFlag()) { + final Animation customAnimation = loadCustomAnimation(info, change); + if (customAnimation != null) { + return customAnimation; + } + } // Use start bounds for closing. final Rect bounds = change.getStartAbsBounds(); final int endTop; @@ -155,8 +166,17 @@ class ActivityEmbeddingAnimationSpec { * the second one is for the end leash. */ @NonNull - Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo.Change change, - @NonNull Rect parentBounds) { + Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo info, + @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) { + if (Flags.activityEmbeddingAnimationCustomizationFlag()) { + // TODO(b/293658614): Support more complicated animations that may need more than a noop + // animation as the start leash. + final Animation noopAnimation = createNoopAnimation(change); + final Animation customAnimation = loadCustomAnimation(info, change); + if (customAnimation != null) { + return new Animation[]{noopAnimation, customAnimation}; + } + } // Both start bounds and end bounds are in screen coordinates. We will post translate // to the local coordinates in ActivityEmbeddingAnimationAdapter#onAnimationUpdate final Rect startBounds = change.getStartAbsBounds(); 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 731f75bf9f5d..55b6bd278f20 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 @@ -21,10 +21,12 @@ import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY; import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW; import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.calculateParentBounds; +import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.shouldUseJumpCutForAnimation; import static com.android.wm.shell.transition.Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; @@ -40,6 +42,8 @@ import android.graphics.Rect; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; import android.window.TransitionInfo; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -281,6 +285,18 @@ public class ActivityEmbeddingAnimationRunnerTests extends ActivityEmbeddingAnim actualParentBounds); } + @Test + public void testShouldUseJumpCutForAnimation() { + final Animation noopAnimation = new AlphaAnimation(0f, 1f); + assertTrue("Animation without duration should use jump cut.", + shouldUseJumpCutForAnimation(noopAnimation)); + + final Animation alphaAnimation = new AlphaAnimation(0f, 1f); + alphaAnimation.setDuration(100); + assertFalse("Animation with duration should not use jump cut.", + shouldUseJumpCutForAnimation(alphaAnimation)); + } + @NonNull private static TransitionInfo.Change prepareChangeForParentBoundsCalculationTest( @NonNull Point endRelOffset, @NonNull Rect endAbsBounds, @NonNull Point endParentSize) { |