Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e804eea authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Add support of custom animation in ActivityEmbeddingController

Because ActivityEmbeddingAnimationRunner will union the bounds of
open changes as the animation parent size (Animation#initialize),
it won't animate on a small region as DefaultTransitionHandler
that uses end bounds.

E.g. one {OPEN,FILL_TASK} TaskFragment and two {CLOSE} TaskFragment.

Bug: 288233059
Test: atest ActivityEmbeddingControllerTests# \
            testShouldAnimate_containsAnimationOptions
Test: With a device that supports activity embedding.
      Below cases can run their specified animation:
      1. Launch Settings->Display->Brightness level
      2. Security->Device unlock->Fingerprint Unlock
         while a secured lock is set and the device only uses
         fingerprintStatusUtils.getSettingsClassName().
Change-Id: Idda515ba483c1c55508dd07450f10f3e9f232e52
parent c9d20f37
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.wm.shell.activityembedding;


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;

@@ -199,8 +201,12 @@ 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 animation;
        if (shouldShowBackdrop(info, change)) {
        if (options != null && options.getType() == ANIM_CUSTOM) {
            animation = mTransitionAnimation.loadAnimationRes(options.getPackageName(),
                    isEnter ? options.getEnterResId() : options.getExitResId());
        } else if (shouldShowBackdrop(info, change)) {
            animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
                    ? com.android.internal.R.anim.task_fragment_clear_top_open_enter
                    : com.android.internal.R.anim.task_fragment_clear_top_open_exit);
@@ -223,8 +229,12 @@ 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 animation;
        if (shouldShowBackdrop(info, change)) {
        if (options != null && options.getType() == ANIM_CUSTOM) {
            animation = mTransitionAnimation.loadAnimationRes(options.getPackageName(),
                    isEnter ? options.getEnterResId() : options.getExitResId());
        } else if (shouldShowBackdrop(info, change)) {
            animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
                    ? com.android.internal.R.anim.task_fragment_clear_top_close_enter
                    : com.android.internal.R.anim.task_fragment_clear_top_close_exit);
+13 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.activityembedding;

import static android.app.ActivityOptions.ANIM_CUSTOM;
import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
import static android.window.TransitionInfo.FLAG_FILLS_TASK;
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
@@ -110,13 +111,19 @@ public class ActivityEmbeddingController implements Transitions.TransitionHandle
        }

        final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
        if (options != null
                // Scene-transition will be handled by app side.
                && (options.getType() == ANIM_SCENE_TRANSITION
                // Use default transition handler to animate override animation.
                || isSupportedOverrideAnimation(options))) {
        if (options != null) {
            // Scene-transition should be handled by app side.
            if (options.getType() == ANIM_SCENE_TRANSITION) {
                return false;
            }
            // The case of ActivityOptions#makeCustomAnimation, Activity#overridePendingTransition,
            // and Activity#overrideActivityTransition are supported.
            if (options.getType() == ANIM_CUSTOM) {
                return true;
            }
            // Use default transition handler to animate other override animation.
            return !isSupportedOverrideAnimation(options);
        }

        return true;
    }
+19 −0
Original line number Diff line number Diff line
@@ -187,6 +187,25 @@ public class ActivityEmbeddingControllerTests extends ActivityEmbeddingAnimation
        verifyNoMoreInteractions(mFinishTransaction);
    }

    @Test
    public void testShouldAnimate_containsAnimationOptions() {
        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
                .addChange(createEmbeddedChange(EMBEDDED_RIGHT_BOUNDS, TASK_BOUNDS, TASK_BOUNDS))
                .build();

        info.setAnimationOptions(TransitionInfo.AnimationOptions
                .makeCustomAnimOptions("packageName", 0 /* enterResId */, 0 /* exitResId */,
                        0 /* backgroundColor */, false /* overrideTaskTransition */));
        assertTrue(mController.shouldAnimate(info));

        info.setAnimationOptions(TransitionInfo.AnimationOptions
                .makeSceneTransitionAnimOptions());
        assertFalse(mController.shouldAnimate(info));

        info.setAnimationOptions(TransitionInfo.AnimationOptions.makeCrossProfileAnimOptions());
        assertFalse(mController.shouldAnimate(info));
    }

    @UiThreadTest
    @Test
    public void testMergeAnimation() {