Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +27 −6 Original line number Diff line number Diff line Loading @@ -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( Loading @@ -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( Loading Loading @@ -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. Loading Loading @@ -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))); } Loading Loading @@ -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) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +27 −7 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +27 −6 Original line number Diff line number Diff line Loading @@ -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( Loading @@ -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( Loading Loading @@ -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. Loading Loading @@ -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))); } Loading Loading @@ -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) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +27 −7 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading