Android14 系统窗口动画分析 (二)

接着上一篇继续分析:

Android14 系统窗口动画分析 (一)

最终根据调用链路追踪到了SurfaceAnimator.java文件中

./frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimator.java

/**
 * Starts an animation.
 *
 * @param anim The object that bridges the controller, {@link SurfaceAnimator}, with the
 *             component responsible for running the animation. It runs the animation with
 *             {@link AnimationAdapter#startAnimation} once the hierarchy with
 *             the Leash has been set up.
 * @param hidden Whether the container holding the child surfaces is currently visible or not.
 *               This is important as it will start with the leash hidden or visible before
 *               handing it to the component that is responsible to run the animation.
 * @param animationFinishedCallback The callback being triggered when the animation finishes.
 * @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a
 *                                   cancel call to the underlying AnimationAdapter.
 * @param snapshotAnim The animation to run for the snapshot. {@code null} if there is no
 *                     snapshot.
 */
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
        @AnimationType int type,
        @Nullable OnAnimationFinishedCallback animationFinishedCallback,
        @Nullable Runnable animationCancelledCallback,
        @Nullable AnimationAdapter snapshotAnim, @Nullable SurfaceFreezer freezer) {
    cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
    //应用层设置进来的动画就在这个对象中
    mAnimation = anim;
    mAnimationType = type;
    mSurfaceAnimationFinishedCallback = animationFinishedCallback;
    mAnimationCancelledCallback = animationCancelledCallback;
    //这里的surface就是窗口的WindowState,父节点是WindowToken
    final SurfaceControl surface = mAnimatable.getSurfaceControl();
    if (surface == null) {
        Slog.w(TAG, "Unable to start animation, surface is null or no children.");
        cancelAnimation();
        return;
    }
    mLeash = freezer != null ? freezer.takeLeashForAnimation() : null;
    if (mLeash == null) {
        try {
          //这里最终调用了createAnimationLeash
          mLeash = createAnimationLeash(mAnimatable, surface, t, type,
                  mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
                  0 /* y */, hidden, mService.mTransactionFactory);
        } catch (OutOfResourcesException outOfResourcesExp) {
            ......
        }
        if (Build.isDebuggable()) {
            mLeashRemoved = false;
            mLeashCreateAtTime = SystemClock.elapsedRealtime();
        }
        mAnimatable.onAnimationLeashCreated(t, mLeash);
    }
    ...... 
}

static SurfaceControl createAnimationLeash(Animatable animatable, SurfaceControl surface,
        Transaction t, @AnimationType int type, int width, int height, int x, int y,
        boolean hidden, Supplier<Transaction> transactionFactory) {
    ProtoLog.i(WM_DEBUG_ANIM, "Reparenting to leash for %s", animatable);
    final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
            .setParent(animatable.getAnimationLeashParent())
            //这里就看到了animation-leash关键字样
            .setName(surface + " - animation-leash of " + animationTypeToString(type))
            // TODO(b/151665759) Defer reparent calls
            // We want the leash to be visible immediately because the transaction which shows
            // the leash may be deferred but the reparent will not. This will cause the leashed
            // surface to be invisible until the deferred transaction is applied. If this
            // doesn't work, you will can see the 2/3 button nav bar flicker during seamless
            // rotation.
            .setHidden(hidden)
            .setEffectLayer()
            .setCallsite("SurfaceAnimator.createAnimationLeash");
    final SurfaceControl leash = builder.build();
    t.setWindowCrop(leash, width, height);
    t.setPosition(leash, x, y);
    t.show(leash);
    t.setAlpha(leash, hidden ? 0 : 1);

    t.reparent(surface, leash);
    return leash;
}

继续看看getSurfaceControl的具体实现

1、WindowState的获取

./frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimator.java

interface Animatable {
    /**
     * @return The surface of the object to be animated.
     *         This SurfaceControl must be valid if non-null.
     */
    @Nullable SurfaceControl getSurfaceControl();
}

其实现是在WindowContainer.java中

./frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

/**
 * @return The SurfaceControl for this container.
 *         The SurfaceControl must be valid if non-null.
 */
@Override
public SurfaceControl getSurfaceControl() {
    return mSurfaceControl;
}

void setSurfaceControl(SurfaceControl sc) {
    mSurfaceControl = sc;
}

可以看出,mSurfaceControl相当于WindowState,WindowContainer相当于WindowToken

2、leash节点的插入

先看看窗口动画原理图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那leash是怎么插入到图层树中的呢?继续分析

./frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimator.java

static SurfaceControl createAnimationLeash(Animatable animatable, SurfaceControl surface,
        Transaction t, @AnimationType int type, int width, int height, int x, int y,
        boolean hidden, Supplier<Transaction> transactionFactory) {
    ProtoLog.i(WM_DEBUG_ANIM, "Reparenting to leash for %s", animatable);
    //第一步:makeAnimationLeash
    final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
            .setParent(animatable.getAnimationLeashParent())  //第二步:setParent,将leash挂载到WindowToken下面
            //这里就看到了animation-leash关键字样
            .setName(surface + " - animation-leash of " + animationTypeToString(type))
            // TODO(b/151665759) Defer reparent calls
            // We want the leash to be visible immediately because the transaction which shows
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值