Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +13 −4 Original line number Diff line number Diff line Loading @@ -255,8 +255,13 @@ class ActivityEmbeddingAnimationRunner { int offsetLayer = TYPE_LAYER_OFFSET; final List<ActivityEmbeddingAnimationAdapter> adapters = new ArrayList<>(); for (TransitionInfo.Change change : openingChanges) { final Animation animation = animationProvider.get(info, change, openingWholeScreenBounds); if (animation.getDuration() == 0) { continue; } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( info, change, animationProvider, openingWholeScreenBounds); info, change, animation, openingWholeScreenBounds); if (isOpening) { adapter.overrideLayer(offsetLayer++); } Loading @@ -275,8 +280,13 @@ class ActivityEmbeddingAnimationRunner { adapters.add(snapshotAdapter); } } final Animation animation = animationProvider.get(info, change, closingWholeScreenBounds); if (animation.getDuration() == 0) { continue; } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( info, change, animationProvider, closingWholeScreenBounds); info, change, animation, closingWholeScreenBounds); if (!isOpening) { adapter.overrideLayer(offsetLayer++); } Loading Loading @@ -353,8 +363,7 @@ class ActivityEmbeddingAnimationRunner { @NonNull private ActivityEmbeddingAnimationAdapter createOpenCloseAnimationAdapter( @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, @NonNull AnimationProvider animationProvider, @NonNull Rect wholeAnimationBounds) { final Animation animation = animationProvider.get(info, change, wholeAnimationBounds); @NonNull Animation animation, @NonNull Rect wholeAnimationBounds) { return new ActivityEmbeddingAnimationAdapter(animation, change, change.getLeash(), wholeAnimationBounds, TransitionUtil.getRootFor(change, info)); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +25 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static android.app.ActivityOptions.ANIM_CUSTOM; import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE; import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.graphics.Rect; import android.view.animation.AlphaAnimation; Loading @@ -34,8 +36,6 @@ import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.window.TransitionInfo; import androidx.annotation.NonNull; import com.android.internal.policy.TransitionAnimation; import com.android.wm.shell.util.TransitionUtil; Loading Loading @@ -201,11 +201,10 @@ class ActivityEmbeddingAnimationSpec { Animation loadOpenAnimation(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) { final boolean isEnter = TransitionUtil.isOpeningType(change.getMode()); final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); final Animation customAnimation = loadCustomAnimation(info, isEnter); final Animation animation; if (options != null && options.getType() == ANIM_CUSTOM) { animation = mTransitionAnimation.loadAnimationRes(options.getPackageName(), isEnter ? options.getEnterResId() : options.getExitResId()); if (customAnimation != null) { animation = customAnimation; } else if (shouldShowBackdrop(info, change)) { animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter ? com.android.internal.R.anim.task_fragment_clear_top_open_enter Loading @@ -229,11 +228,10 @@ class ActivityEmbeddingAnimationSpec { Animation loadCloseAnimation(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) { final boolean isEnter = TransitionUtil.isOpeningType(change.getMode()); final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); final Animation customAnimation = loadCustomAnimation(info, isEnter); final Animation animation; if (options != null && options.getType() == ANIM_CUSTOM) { animation = mTransitionAnimation.loadAnimationRes(options.getPackageName(), isEnter ? options.getEnterResId() : options.getExitResId()); if (customAnimation != null) { animation = customAnimation; } else if (shouldShowBackdrop(info, change)) { animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter ? com.android.internal.R.anim.task_fragment_clear_top_close_enter Loading @@ -259,4 +257,21 @@ class ActivityEmbeddingAnimationSpec { mTransitionAnimation, false); return a != null && a.getShowBackdrop(); } @Nullable private Animation loadCustomAnimation(@NonNull TransitionInfo info, boolean isEnter) { final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); if (options == null || options.getType() != ANIM_CUSTOM) { return null; } final Animation anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(), isEnter ? options.getEnterResId() : options.getExitResId()); if (anim != null) { return anim; } // The app may be intentional to use an invalid resource as a no-op animation. // ActivityEmbeddingAnimationRunner#createOpenCloseAnimationAdapters will skip the // animation with duration 0. Then it will use prepareForJumpCut for empty adapters. return new AlphaAnimation(1f, 1f); } } libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java +17 −0 Original line number Diff line number Diff line Loading @@ -98,4 +98,21 @@ public class ActivityEmbeddingAnimationRunnerTests extends ActivityEmbeddingAnim // The animation should be empty when it is behind starting window. assertEquals(0, animator.getDuration()); } @Test public void testInvalidCustomAnimation() { final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0) .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) .build(); info.setAnimationOptions(TransitionInfo.AnimationOptions .makeCustomAnimOptions("packageName", 0 /* enterResId */, 0 /* exitResId */, 0 /* backgroundColor */, false /* overrideTaskTransition */)); final Animator animator = mAnimRunner.createAnimator( info, mStartTransaction, mFinishTransaction, () -> mFinishCallback.onTransitionFinished(null /* wct */), new ArrayList<>()); // An invalid custom animation is equivalent to jump-cut. assertEquals(0, animator.getDuration()); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +13 −4 Original line number Diff line number Diff line Loading @@ -255,8 +255,13 @@ class ActivityEmbeddingAnimationRunner { int offsetLayer = TYPE_LAYER_OFFSET; final List<ActivityEmbeddingAnimationAdapter> adapters = new ArrayList<>(); for (TransitionInfo.Change change : openingChanges) { final Animation animation = animationProvider.get(info, change, openingWholeScreenBounds); if (animation.getDuration() == 0) { continue; } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( info, change, animationProvider, openingWholeScreenBounds); info, change, animation, openingWholeScreenBounds); if (isOpening) { adapter.overrideLayer(offsetLayer++); } Loading @@ -275,8 +280,13 @@ class ActivityEmbeddingAnimationRunner { adapters.add(snapshotAdapter); } } final Animation animation = animationProvider.get(info, change, closingWholeScreenBounds); if (animation.getDuration() == 0) { continue; } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( info, change, animationProvider, closingWholeScreenBounds); info, change, animation, closingWholeScreenBounds); if (!isOpening) { adapter.overrideLayer(offsetLayer++); } Loading Loading @@ -353,8 +363,7 @@ class ActivityEmbeddingAnimationRunner { @NonNull private ActivityEmbeddingAnimationAdapter createOpenCloseAnimationAdapter( @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, @NonNull AnimationProvider animationProvider, @NonNull Rect wholeAnimationBounds) { final Animation animation = animationProvider.get(info, change, wholeAnimationBounds); @NonNull Animation animation, @NonNull Rect wholeAnimationBounds) { return new ActivityEmbeddingAnimationAdapter(animation, change, change.getLeash(), wholeAnimationBounds, TransitionUtil.getRootFor(change, info)); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +25 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static android.app.ActivityOptions.ANIM_CUSTOM; import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE; import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.graphics.Rect; import android.view.animation.AlphaAnimation; Loading @@ -34,8 +36,6 @@ import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.window.TransitionInfo; import androidx.annotation.NonNull; import com.android.internal.policy.TransitionAnimation; import com.android.wm.shell.util.TransitionUtil; Loading Loading @@ -201,11 +201,10 @@ class ActivityEmbeddingAnimationSpec { Animation loadOpenAnimation(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) { final boolean isEnter = TransitionUtil.isOpeningType(change.getMode()); final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); final Animation customAnimation = loadCustomAnimation(info, isEnter); final Animation animation; if (options != null && options.getType() == ANIM_CUSTOM) { animation = mTransitionAnimation.loadAnimationRes(options.getPackageName(), isEnter ? options.getEnterResId() : options.getExitResId()); if (customAnimation != null) { animation = customAnimation; } else if (shouldShowBackdrop(info, change)) { animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter ? com.android.internal.R.anim.task_fragment_clear_top_open_enter Loading @@ -229,11 +228,10 @@ class ActivityEmbeddingAnimationSpec { Animation loadCloseAnimation(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) { final boolean isEnter = TransitionUtil.isOpeningType(change.getMode()); final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); final Animation customAnimation = loadCustomAnimation(info, isEnter); final Animation animation; if (options != null && options.getType() == ANIM_CUSTOM) { animation = mTransitionAnimation.loadAnimationRes(options.getPackageName(), isEnter ? options.getEnterResId() : options.getExitResId()); if (customAnimation != null) { animation = customAnimation; } else if (shouldShowBackdrop(info, change)) { animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter ? com.android.internal.R.anim.task_fragment_clear_top_close_enter Loading @@ -259,4 +257,21 @@ class ActivityEmbeddingAnimationSpec { mTransitionAnimation, false); return a != null && a.getShowBackdrop(); } @Nullable private Animation loadCustomAnimation(@NonNull TransitionInfo info, boolean isEnter) { final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); if (options == null || options.getType() != ANIM_CUSTOM) { return null; } final Animation anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(), isEnter ? options.getEnterResId() : options.getExitResId()); if (anim != null) { return anim; } // The app may be intentional to use an invalid resource as a no-op animation. // ActivityEmbeddingAnimationRunner#createOpenCloseAnimationAdapters will skip the // animation with duration 0. Then it will use prepareForJumpCut for empty adapters. return new AlphaAnimation(1f, 1f); } }
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java +17 −0 Original line number Diff line number Diff line Loading @@ -98,4 +98,21 @@ public class ActivityEmbeddingAnimationRunnerTests extends ActivityEmbeddingAnim // The animation should be empty when it is behind starting window. assertEquals(0, animator.getDuration()); } @Test public void testInvalidCustomAnimation() { final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0) .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) .build(); info.setAnimationOptions(TransitionInfo.AnimationOptions .makeCustomAnimOptions("packageName", 0 /* enterResId */, 0 /* exitResId */, 0 /* backgroundColor */, false /* overrideTaskTransition */)); final Animator animator = mAnimRunner.createAnimator( info, mStartTransaction, mFinishTransaction, () -> mFinishCallback.onTransitionFinished(null /* wct */), new ArrayList<>()); // An invalid custom animation is equivalent to jump-cut. assertEquals(0, animator.getDuration()); } }