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

Commit bc3d6581 authored by Tony Huang's avatar Tony Huang
Browse files

Make AppTransition animations sharable (6/n)

1. Migrate wallpaper related animation.
2. Refactor and correct some handled animations.

Bug: 178678389
Test: manual
Change-Id: I1ea02fa946c1c28d53ac6b92786db17dacbb45c4
parent 29bdef95
Loading
Loading
Loading
Loading
+57 −11
Original line number Diff line number Diff line
@@ -16,15 +16,18 @@

package com.android.internal.policy;

import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN;
import static android.view.WindowManager.TRANSIT_OPEN;

import android.annotation.DrawableRes;
import android.annotation.NonNull;
@@ -46,6 +49,7 @@ import android.os.SystemProperties;
import android.util.Slog;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.TransitionOldType;
import android.view.WindowManager.TransitionType;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
@@ -62,11 +66,17 @@ import java.util.List;

/** @hide */
public class TransitionAnimation {
    public static final int WALLPAPER_TRANSITION_NONE = 0;
    public static final int WALLPAPER_TRANSITION_OPEN = 1;
    public static final int WALLPAPER_TRANSITION_CLOSE = 2;
    public static final int WALLPAPER_TRANSITION_INTRA_OPEN = 3;
    public static final int WALLPAPER_TRANSITION_INTRA_CLOSE = 4;

    // These are the possible states for the enter/exit activities during a thumbnail transition
    public static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
    public static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
    public static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
    public static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
    private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
    private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
    private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
    private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;

    /**
     * Maximum duration for the clip reveal animation. This is used when there is a lot of movement
@@ -379,8 +389,15 @@ public class TransitionAnimation {
        }
    }

    public Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame,
            Rect displayFrame, Rect startRect) {
    public Animation createClipRevealAnimationLocked(@TransitionType int transit,
            int wallpaperTransit, boolean enter, Rect appFrame, Rect displayFrame, Rect startRect) {
        return createClipRevealAnimationLockedCompat(
                getTransitCompatType(transit, wallpaperTransit), enter, appFrame, displayFrame,
                startRect);
    }

    public Animation createClipRevealAnimationLockedCompat(@TransitionOldType int transit,
            boolean enter, Rect appFrame, Rect displayFrame, Rect startRect) {
        final Animation anim;
        if (enter) {
            final int appWidth = appFrame.width();
@@ -490,8 +507,14 @@ public class TransitionAnimation {
        return anim;
    }

    public Animation createScaleUpAnimationLocked(int transit, boolean enter,
            Rect containingFrame, Rect startRect) {
    public Animation createScaleUpAnimationLocked(@TransitionType int transit, int wallpaperTransit,
            boolean enter, Rect containingFrame, Rect startRect) {
        return createScaleUpAnimationLockedCompat(getTransitCompatType(transit, wallpaperTransit),
                enter, containingFrame, startRect);
    }

    public Animation createScaleUpAnimationLockedCompat(@TransitionOldType int transit,
            boolean enter, Rect containingFrame, Rect startRect) {
        Animation a;
        setupDefaultNextAppTransitionStartRect(startRect, mTmpRect);
        final int appWidth = containingFrame.width();
@@ -546,12 +569,19 @@ public class TransitionAnimation {
        return a;
    }

    public Animation createThumbnailEnterExitAnimationLocked(boolean enter, boolean scaleUp,
            Rect containingFrame, @TransitionType int transit, int wallpaperTransit,
            HardwareBuffer thumbnailHeader, Rect startRect) {
        return createThumbnailEnterExitAnimationLockedCompat(enter, scaleUp, containingFrame,
                getTransitCompatType(transit, wallpaperTransit), thumbnailHeader, startRect);
    }

    /**
     * This animation is created when we are doing a thumbnail transition, for the activity that is
     * leaving, and the activity that is entering.
     */
    public Animation createThumbnailEnterExitAnimationLocked(boolean enter, boolean scaleUp,
            Rect containingFrame, int transit, HardwareBuffer thumbnailHeader,
    public Animation createThumbnailEnterExitAnimationLockedCompat(boolean enter, boolean scaleUp,
            Rect containingFrame, @TransitionOldType int transit, HardwareBuffer thumbnailHeader,
            Rect startRect) {
        final int appWidth = containingFrame.width();
        final int appHeight = containingFrame.height();
@@ -897,7 +927,7 @@ public class TransitionAnimation {
     * Prepares the specified animation with a standard duration, interpolator, etc.
     */
    private Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight,
            int transit) {
            @TransitionOldType int transit) {
        // Pick the desired duration.  If this is an inter-activity transition,
        // it  is the standard duration for that.  Otherwise we use the longer
        // task transition duration.
@@ -994,6 +1024,22 @@ public class TransitionAnimation {
        return anim;
    }

    private static @TransitionOldType int getTransitCompatType(@TransitionType int transit,
            int wallpaperTransit) {
        if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
            return TRANSIT_OLD_WALLPAPER_INTRA_OPEN;
        } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_CLOSE) {
            return TRANSIT_OLD_WALLPAPER_INTRA_CLOSE;
        } else if (transit == TRANSIT_OPEN) {
            return TRANSIT_OLD_ACTIVITY_OPEN;
        } else if (transit == TRANSIT_CLOSE) {
            return TRANSIT_OLD_ACTIVITY_CLOSE;
        }

        // We only do some special handle for above type, so use type NONE for default behavior.
        return TRANSIT_OLD_NONE;
    }

    /**
     * Calculates the duration for the clip reveal animation. If the clip is "cut off", meaning that
     * the start rect is outside of the target rect, and there is a lot of movement going on.
+104 −50
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;

import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -134,6 +140,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
            mAnimations.remove(transition);
            finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
        };

        final int wallpaperTransit = getWallpaperTransitType(info);
        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            if (change.getMode() == TRANSIT_CHANGE) {
@@ -151,7 +159,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
            // Don't animate anything that isn't independent.
            if (!TransitionInfo.isIndependent(change, info)) continue;

            Animation a = loadAnimation(info, change);
            Animation a = loadAnimation(info, change, wallpaperTransit);
            if (a != null) {
                startAnimInternal(animations, a, change.getLeash(), onAnimFinish,
                        null /* position */);
@@ -180,14 +188,15 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
    }

    @Nullable
    private Animation loadAnimation(TransitionInfo info, TransitionInfo.Change change) {
    private Animation loadAnimation(TransitionInfo info, TransitionInfo.Change change,
            int wallpaperTransit) {
        Animation a = null;

        final int type = info.getType();
        final int flags = info.getFlags();
        final boolean isOpening = Transitions.isOpeningType(type);
        final int changeMode = change.getMode();
        final int changeFlags = change.getFlags();
        final boolean isOpeningType = Transitions.isOpeningType(type);
        final boolean enter = Transitions.isOpeningType(changeMode);
        final boolean isTask = change.getTaskInfo() != null;
        final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
@@ -196,7 +205,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {

        if (type == TRANSIT_RELAUNCH) {
            a = mTransitionAnimation.createRelaunchAnimation(
                    change.getStartAbsBounds(), mInsets, change.getEndAbsBounds());
                    change.getEndAbsBounds(), mInsets, change.getEndAbsBounds());
        } else if (type == TRANSIT_KEYGUARD_GOING_AWAY) {
            a = mTransitionAnimation.loadKeyguardExitAnimation(flags,
                    (changeFlags & FLAG_SHOW_WALLPAPER) != 0);
@@ -209,64 +218,81 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        } else if (overrideType == ANIM_OPEN_CROSS_PROFILE_APPS && enter) {
            a = mTransitionAnimation.loadCrossProfileAppEnterAnimation();
        } else if (overrideType == ANIM_CLIP_REVEAL) {
            a = mTransitionAnimation.createClipRevealAnimationLocked(changeMode, enter,
            a = mTransitionAnimation.createClipRevealAnimationLocked(type, wallpaperTransit, enter,
                    change.getEndAbsBounds(), change.getEndAbsBounds(),
                    options.getTransitionBounds());
        } else if (overrideType == ANIM_SCALE_UP) {
            a = mTransitionAnimation.createScaleUpAnimationLocked(changeMode, enter,
            a = mTransitionAnimation.createScaleUpAnimationLocked(type, wallpaperTransit, enter,
                    change.getEndAbsBounds(), options.getTransitionBounds());
        } else if (overrideType == ANIM_THUMBNAIL_SCALE_UP
                || overrideType == ANIM_THUMBNAIL_SCALE_DOWN) {
            final boolean scaleUp = overrideType == ANIM_THUMBNAIL_SCALE_UP;
            a = mTransitionAnimation.createThumbnailEnterExitAnimationLocked(enter, scaleUp,
                    change.getEndAbsBounds(), changeMode, options.getThumbnail(),
                    change.getEndAbsBounds(), type, wallpaperTransit, options.getThumbnail(),
                    options.getTransitionBounds());
        } else if (changeMode == TRANSIT_OPEN && isOpening) {
            if ((changeFlags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) {
                // This received a transferred starting window, so don't animate
                return null;
            }

            if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) {
                a = mTransitionAnimation.loadVoiceActivityOpenAnimation(true /** enter */);
            } else if (isTask) {
                a = mTransitionAnimation.loadDefaultAnimationAttr(
                        R.styleable.WindowAnimation_taskOpenEnterAnimation);
        } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
            a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                    ? R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
                    : R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation);
        } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_CLOSE) {
            a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                    ? R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
                    : R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation);
        } else if (wallpaperTransit == WALLPAPER_TRANSITION_OPEN) {
            a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                    ? R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
                    : R.styleable.WindowAnimation_wallpaperOpenExitAnimation);
        } else if (wallpaperTransit == WALLPAPER_TRANSITION_CLOSE) {
            a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                    ? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
                    : R.styleable.WindowAnimation_wallpaperCloseExitAnimation);
        } else if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) {
            if (isOpeningType) {
                a = mTransitionAnimation.loadVoiceActivityOpenAnimation(enter);
            } else {
                a = mTransitionAnimation.loadDefaultAnimationRes(
                        (changeFlags & FLAG_TRANSLUCENT) == 0
                        ? R.anim.activity_open_enter : R.anim.activity_translucent_open_enter);
                a = mTransitionAnimation.loadVoiceActivityExitAnimation(enter);
            }
        } else if (changeMode == TRANSIT_TO_FRONT && isOpening) {
            if ((changeFlags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) {
        } else if ((changeFlags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0 && isOpeningType) {
            // This received a transferred starting window, so don't animate
            return null;
            }

            if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) {
                a = mTransitionAnimation.loadVoiceActivityOpenAnimation(true /** enter */);
        } else if (type == TRANSIT_OPEN) {
            if (isTask) {
                a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                        ? R.styleable.WindowAnimation_taskOpenEnterAnimation
                        : R.styleable.WindowAnimation_taskOpenExitAnimation);
            } else {
                if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
                    a = mTransitionAnimation.loadDefaultAnimationRes(
                            R.anim.activity_translucent_open_enter);
                } else {
                a = mTransitionAnimation.loadDefaultAnimationAttr(
                        R.styleable.WindowAnimation_taskToFrontEnterAnimation);
            }
        } else if (changeMode == TRANSIT_CLOSE && !isOpening) {
            if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) {
                a = mTransitionAnimation.loadVoiceActivityExitAnimation(false /** enter */);
            } else if (isTask) {
                a = mTransitionAnimation.loadDefaultAnimationAttr(
                        R.styleable.WindowAnimation_taskCloseExitAnimation);
                    a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                            ? R.styleable.WindowAnimation_activityOpenEnterAnimation
                            : R.styleable.WindowAnimation_activityOpenExitAnimation);
                }
            }
        } else if (type == TRANSIT_TO_FRONT) {
            a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                    ? R.styleable.WindowAnimation_taskToFrontEnterAnimation
                    : R.styleable.WindowAnimation_taskToFrontExitAnimation);
        } else if (type == TRANSIT_CLOSE) {
            if (isTask) {
                a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                        ? R.styleable.WindowAnimation_taskCloseEnterAnimation
                        : R.styleable.WindowAnimation_taskCloseExitAnimation);
            } else {
                if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
                    a = mTransitionAnimation.loadDefaultAnimationRes(
                        (changeFlags & FLAG_TRANSLUCENT) == 0
                        ? R.anim.activity_close_exit : R.anim.activity_translucent_close_exit);
            }
        } else if (changeMode == TRANSIT_TO_BACK && !isOpening) {
            if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) {
                a = mTransitionAnimation.loadVoiceActivityExitAnimation(false /** enter */);
                            R.anim.activity_translucent_close_exit);
                } else {
                a = mTransitionAnimation.loadDefaultAnimationAttr(
                        R.styleable.WindowAnimation_taskToBackExitAnimation);
                    a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                            ? R.styleable.WindowAnimation_activityCloseEnterAnimation
                            : R.styleable.WindowAnimation_activityCloseExitAnimation);
                }
            }
        } else if (type == TRANSIT_TO_BACK) {
            a = mTransitionAnimation.loadDefaultAnimationAttr(enter
                    ? R.styleable.WindowAnimation_taskToBackEnterAnimation
                    : R.styleable.WindowAnimation_taskToBackExitAnimation);
        } else if (changeMode == TRANSIT_CHANGE) {
            // In the absence of a specific adapter, we just want to keep everything stationary.
            a = new AlphaAnimation(1.f, 1.f);
@@ -274,10 +300,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        }

        if (a != null) {
            Rect start = change.getStartAbsBounds();
            if (!a.isInitialized()) {
                Rect end = change.getEndAbsBounds();
                a.initialize(end.width(), end.height(), end.width(), end.height());
            }
            a.restrictDuration(MAX_ANIMATION_DURATION);
            a.initialize(end.width(), end.height(), start.width(), start.height());
            a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
        }
        return a;
@@ -397,6 +424,33 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        startAnimInternal(animations, a, wt.getSurface(), finisher, null /* position */);
    }

    private static int getWallpaperTransitType(TransitionInfo info) {
        boolean hasOpenWallpaper = false;
        boolean hasCloseWallpaper = false;

        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            if ((change.getFlags() & FLAG_SHOW_WALLPAPER) != 0) {
                if (Transitions.isOpeningType(change.getMode())) {
                    hasOpenWallpaper = true;
                } else if (Transitions.isClosingType(change.getMode())) {
                    hasCloseWallpaper = true;
                }
            }
        }

        if (hasOpenWallpaper && hasCloseWallpaper) {
            return Transitions.isOpeningType(info.getType())
                    ? WALLPAPER_TRANSITION_INTRA_OPEN : WALLPAPER_TRANSITION_INTRA_CLOSE;
        } else if (hasOpenWallpaper) {
            return WALLPAPER_TRANSITION_OPEN;
        } else if (hasCloseWallpaper) {
            return WALLPAPER_TRANSITION_CLOSE;
        } else {
            return WALLPAPER_TRANSITION_NONE;
        }
    }

    private static void applyTransformation(long time, SurfaceControl.Transaction t,
            SurfaceControl leash, Animation anim, Transformation transformation, float[] matrix,
            Point position) {
+3 −3
Original line number Diff line number Diff line
@@ -875,7 +875,7 @@ public class AppTransition implements Dump {
                            + "transit=%s Callers=%s",
                    a, appTransitionOldToString(transit), Debug.getCallers(3));
        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
            a = mTransitionAnimation.createClipRevealAnimationLocked(
            a = mTransitionAnimation.createClipRevealAnimationLockedCompat(
                    transit, enter, frame, displayFrame,
                    mDefaultNextAppTransitionAnimationSpec != null
                            ? mDefaultNextAppTransitionAnimationSpec.rect : null);
@@ -884,7 +884,7 @@ public class AppTransition implements Dump {
                            + "transit=%s Callers=%s",
                    a, appTransitionOldToString(transit), Debug.getCallers(3));
        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
            a = mTransitionAnimation.createScaleUpAnimationLocked(transit, enter, frame,
            a = mTransitionAnimation.createScaleUpAnimationLockedCompat(transit, enter, frame,
                    mDefaultNextAppTransitionAnimationSpec != null
                            ? mDefaultNextAppTransitionAnimationSpec.rect : null);
            ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
@@ -896,7 +896,7 @@ public class AppTransition implements Dump {
            mNextAppTransitionScaleUp =
                    (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
            final HardwareBuffer thumbnailHeader = getAppTransitionThumbnailHeader(container);
            a = mTransitionAnimation.createThumbnailEnterExitAnimationLocked(enter,
            a = mTransitionAnimation.createThumbnailEnterExitAnimationLockedCompat(enter,
                    mNextAppTransitionScaleUp, frame, transit, thumbnailHeader,
                    mDefaultNextAppTransitionAnimationSpec != null
                            ? mDefaultNextAppTransitionAnimationSpec.rect : null);