Android 16系统源码_窗口动画(二)窗口显示动画源码调用流程

发布于:2025-07-16 ⋅ 阅读:(25) ⋅ 点赞:(0)

前言

Android 16系统源码_窗口动画(一)窗口过渡动画层级图分析这篇文章我们有分析过,系统触发窗口显示动画的过程中,会创建一个leash图层,本篇文章我们将会结合源码具体来分析下该图层的创建流程。

一 创建Leash图层的代码源头

1.1 查找创建leash图层的代码源头

触发窗口动画时候的SurfaceFlinger图层信息如下所示。
leash过渡动画
在叶子节点下回多了一个含有animation-leash关键字的Surface图层,我们直接在源码中查找animation-leash of 关键字,可以定位到SurfaceAnimator这个类的394行。

/base/services/core/java/com/android/server/wm/SurfaceAnimator.java:394:                .setName(surface + " - animation-leash of " + animationTypeToString(type))

class SurfaceAnimator {
    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) {
        if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to leash");

        final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
                .setParent(animatable.getAnimationLeashParent())
                .setName(surface + " - animation-leash of " + animationTypeToString(type))
                .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;
    }
}

二 创建leash图层的源码流程

2.1 createAnimationLeash方法调用流程

2.1.1 堆栈信息

通过断点调试可以得到SurfaceAnimator的createAnimationLeash方法的调用堆栈信息。
堆栈信息

2.1.2 createAnimationLeash方法源码调用流程

结合以上方法调用栈,在系统源码中进行定位可以得到以下调用流程

//frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
class WindowSurfacePlacer {
    void requestTraversal() {
    	...代码省略...
        mService.mAnimationHandler.post(mPerformSurfacePlacement);
    }
    private class Traverser implements Runnable {
        @Override
        public void run() {
            synchronized (mService.mGlobalLock) {
            	//调用performSurfacePlacement方法
                performSurfacePlacement();
            }
        }
    }

    final void performSurfacePlacement() {
        performSurfacePlacement(false /* force */);
    }

    final void performSurfacePlacement(boolean force) {
			...代码省略...
          performSurfacePlacementLoop();
			...代码省略...
    }
    private final WindowManagerService mService;
    private void performSurfacePlacementLoop() {
			...代码省略...
			//调用RootWindowContainer的performSurfacePlacement方法  
           mService.mRoot.performSurfacePlacement();
			...代码省略...           
    }

}
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
class RootWindowContainer extends WindowContainer<DisplayContent>
        implements DisplayManager.DisplayListener {

    void performSurfacePlacement() {
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
        try {
            performSurfacePlacementNoTrace();
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }
     void performSurfacePlacementNoTrace() {
		...代码省略...         
      	//调用applySurfaceChangesTransaction
          applySurfaceChangesTransaction();
		...代码省略...            
     }

    protected final WindowList<E> mChildren = new WindowList<E>();

    private void applySurfaceChangesTransaction() {
		...代码省略...           
        final int count = mChildren.size();
        for (int j = 0; j < count; ++j) {
            final DisplayContent dc = mChildren.get(j);
            dc.applySurfaceChangesTransaction();
        }
		...代码省略...               
  }     
}
//frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
    void applySurfaceChangesTransaction() {
    	...代码省略...
       forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
    	...代码省略...            
	}
	
	//关键回调,触发WindowState的commitFinishDrawingLocked方法
    private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {    
    		...代码省略...
            // Take care of the window being ready to display.
            final boolean committed = w.mWinAnimator.commitFinishDrawingLocked();
    		...代码省略...            
	}
	
  }
//frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
class WindowStateAnimator {
    // This must be called while inside a transaction.
    boolean commitFinishDrawingLocked() {
        if (DEBUG_STARTING_WINDOW_VERBOSE &&
                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
            Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
                    + drawStateToString());
        }
        if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
            return false;
        }
        if (DEBUG_ANIM) {
            Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
        }
        mDrawState = READY_TO_SHOW;
        boolean result = false;
        final ActivityRecord activity = mWin.mActivityRecord;
        if (activity == null || activity.canShowWindows()
                || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
            //调用WindowState的performShowLocked方法
            result = mWin.performShowLocked();
        }
        return result;
    }
}

//frameworks/base/services/core/java/com/android/server/wm/WindowState.java
class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState,
        InsetsControlTarget, InputTarget {
	boolean performShowLocked() {
		...代码省略...   
	    mWinAnimator.applyEnterAnimationLocked();
		...代码省略...       
	}
}

class WindowStateAnimator {

    void applyEnterAnimationLocked() {
        // If we are the new part of a window replacement transition and we have requested
        // not to animate, we instead want to make it seamless, so we don't want to apply
        // an enter transition.
        if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
            return;
        }
        final int transit;
        if (mEnterAnimationPending) {
            mEnterAnimationPending = false;
            transit = WindowManagerPolicy.TRANSIT_ENTER;
        } else {
            transit = WindowManagerPolicy.TRANSIT_SHOW;
        }
        // We don't apply animation for application main window here since this window type
        // should be controlled by ActivityRecord in general. Wallpaper is also excluded because
        // WallpaperController should handle it.
        if (mAttrType != TYPE_BASE_APPLICATION && !mIsWallpaper) {
            applyAnimationLocked(transit, true);
        }

        if (mService.mAccessibilityController.hasCallbacks()) {
            mService.mAccessibilityController.onWindowTransition(mWin, transit);
        }
    }

	//根据情况选择不同的窗口动画资源样式
    boolean applyAnimationLocked(int transit, boolean isEntrance) {
        if (mWin.isAnimating() && mAnimationIsEntrance == isEntrance) {
            // If we are trying to apply an animation, but already running
            // an animation of the same type, then just leave that one alone.
            return true;
        }

        if (mWin.mAttrs.type == TYPE_INPUT_METHOD) {
            mWin.getDisplayContent().adjustForImeIfNeeded();
            if (isEntrance) {
                mWin.setDisplayLayoutNeeded();
                mService.mWindowPlacerLocked.requestTraversal();
            }
        }

        if (mWin.mControllableInsetProvider != null) {
            // All our animations should be driven by the insets control target.
            return false;
        }

        // Only apply an animation if the display isn't frozen.  If it is
        // frozen, there is no reason to animate and it can cause strange
        // artifacts when we unfreeze the display if some different animation
        // is running.
        if (mWin.mToken.okToAnimate()) {
            int anim = mWin.getDisplayContent().getDisplayPolicy().selectAnimation(mWin, transit);
            int attr = -1;
            Animation a = null;
            if (anim != DisplayPolicy.ANIMATION_STYLEABLE) {
                if (anim != DisplayPolicy.ANIMATION_NONE) {
                    Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#loadAnimation");
                    a = AnimationUtils.loadAnimation(mContext, anim);
                    Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
                }
            } else {
                switch (transit) {
                    case WindowManagerPolicy.TRANSIT_ENTER:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
                        break;
                    case WindowManagerPolicy.TRANSIT_EXIT:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
                        break;
                    case WindowManagerPolicy.TRANSIT_SHOW:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
                        break;
                    case WindowManagerPolicy.TRANSIT_HIDE:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
                        break;
                }
                if (attr >= 0) {
                	//加载窗口定制的动画资源
                    a = mWin.mDisplayContent.mTransitionAnimation.loadAnimationAttr(
                            mWin.mAttrs, attr, TRANSIT_OLD_NONE);
                }
            }
            if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.VERBOSE)) {
            	//关键日志打印
                ProtoLog.v(WM_DEBUG_ANIM, "applyAnimation: win=%s"
                        + " anim=%d attr=0x%x a=%s transit=%d type=%d isEntrance=%b Callers %s",
                        this, anim, attr, a, transit, mAttrType, isEntrance, Debug.getCallers(20));
            }
            if (a != null) {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#startAnimation");
                //调动WindowState的startAnimation方法,开启动画
                mWin.startAnimation(a);
                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
                mAnimationIsEntrance = isEntrance;
            }
        } else {
            mWin.cancelAnimation();
        }

        return mWin.isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION);
    }
}

class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState,
        InsetsControlTarget, InputTarget {

    void startAnimation(Animation anim) {
    	...代码省略...  
        final DisplayInfo displayInfo = getDisplayInfo();
        anim.initialize(mWindowFrames.mFrame.width(), mWindowFrames.mFrame.height(),
                displayInfo.appWidth, displayInfo.appHeight);
        anim.restrictDuration(MAX_ANIMATION_DURATION);
        anim.scaleCurrentDuration(mWmService.getWindowAnimationScaleLocked());
        final Point position = new Point();
        transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
                position);
        //创建本地动画对象LocalAnimationAdapter
        final AnimationAdapter adapter = new LocalAnimationAdapter(
                new WindowAnimationSpec(anim, position, false /* canSkipFirstFrame */,
                        0 /* windowCornerRadius */),
                mWmService.mSurfaceAnimationRunner);
        final Transaction t = mActivityRecord != null
                ? getSyncTransaction() : getPendingTransaction();
        startAnimation(t, adapter);
        commitPendingTransaction();
    }

    private void startAnimation(Transaction t, AnimationAdapter adapter) {
    	//继续调用父类的startAnimation方法
        startAnimation(t, adapter, mWinAnimator.mLastHidden, ANIMATION_TYPE_WINDOW_ANIMATION);
    }
}
//frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable {

    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
            @AnimationType int type) {
        startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */);
    }
    
    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
            @AnimationType int type,
            @Nullable OnAnimationFinishedCallback animationFinishedCallback) {
        startAnimation(t, anim, hidden, type, animationFinishedCallback,
                null /* adapterAnimationCancelledCallback */, null /* snapshotAnim */);
    }
    
    protected final SurfaceAnimator mSurfaceAnimator;
    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
            @AnimationType int type,
            @Nullable OnAnimationFinishedCallback animationFinishedCallback,
            @Nullable Runnable animationCancelledCallback,
            @Nullable AnimationAdapter snapshotAnim) {
        ProtoLog.v(WM_DEBUG_ANIM, "Starting animation on %s: type=%d, anim=%s",
                this, type, anim);

        // TODO: This should use isVisible() but because isVisible has a really weird meaning at
        // the moment this doesn't work for all animatable window containers.
        //调用SurfaceAnimator的startAnimation方法
        mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback,
                animationCancelledCallback, snapshotAnim);
    }
}
//frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimator.java
class SurfaceAnimator {
    private AnimationAdapter mAnimation;
	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;//将LocalAnimationAdapter类型的anim赋值给mAnimation 
        mAnimationType = type;
        mSurfaceAnimationFinishedCallback = animationFinishedCallback;
        mAnimationCancelledCallback = animationCancelledCallback;
        final SurfaceControl surface = mAnimatable.getSurfaceControl();
        if (surface == null) {
            Slog.w(TAG, "Unable to start animation, surface is null or no children.");
            cancelAnimation();
            return;
        }
        if (mLeash == null) {
        	//调动createAnimationLeash方法创建窗口动画对应的leash图层
            mLeash = createAnimationLeash(mAnimatable, surface, t, type,
                    mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
                    0 /* y */, hidden, mService.mTransactionFactory);
            mAnimatable.onAnimationLeashCreated(t, mLeash);
        }
        if (mAnimationStartDelayed) {
            if (DEBUG_ANIM) Slog.i(TAG, "Animation start delayed");
            return;
        }
        //调用LocalAnimationAdapter的startAnimation方法,开始执行动画
        mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
        ...代码省略...        
	}
	
    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())//设置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);//指定当前窗口的父类为leash动画图层
        return leash;
    }
}

以上代码需要重点关注以下几点

  1. 在WindowStateAnimator的loadAnimationAttr方法中,会判断使用哪种窗口动画以及进行窗口动画资源的加载。
  2. 在WindowState的startAnimation方法中,会创建LocalAnimationAdapter本地动画实例对象。
  3. 在SurfaceAnimator的createAnimationLeash方法中,会创建leash动画图层,并将该图层的父类设置为当前窗口的父类,将当前窗口的父类设置为leash动画图层。

2.1.3 时序图

时序图

三 窗口动画

3.1 窗口动画的执行

动画的执行主要是在SurfaceAnimator的startAnimation方法中。

//frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimator.java
class SurfaceAnimator {
    private AnimationAdapter mAnimation;
	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;//将LocalAnimationAdapter类型的anim赋值给mAnimation 
        mAnimationType = type;
        mSurfaceAnimationFinishedCallback = animationFinishedCallback;
        mAnimationCancelledCallback = animationCancelledCallback;
        final SurfaceControl surface = mAnimatable.getSurfaceControl();
        if (surface == null) {
            Slog.w(TAG, "Unable to start animation, surface is null or no children.");
            cancelAnimation();
            return;
        }
        if (mLeash == null) {
        	//调动createAnimationLeash方法创建窗口动画对应的leash图层
            mLeash = createAnimationLeash(mAnimatable, surface, t, type,
                    mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
                    0 /* y */, hidden, mService.mTransactionFactory);
            mAnimatable.onAnimationLeashCreated(t, mLeash);
        }
        if (mAnimationStartDelayed) {
            if (DEBUG_ANIM) Slog.i(TAG, "Animation start delayed");
            return;
        }
        //调用LocalAnimationAdapter的startAnimation方法,开始执行动画
        mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
        ...代码省略...        
	}

SurfaceAnimator的startAnimation方法在调用createAnimationLeash方法创建leash图层之后,会调用LocalAnimationAdapter的startAnimation方法执行窗口动画。

//frameworks/base/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
class LocalAnimationAdapter implements AnimationAdapter {

    private final AnimationSpec mSpec;
    private final SurfaceAnimationRunner mAnimator;

    LocalAnimationAdapter(AnimationSpec spec, SurfaceAnimationRunner animator) {
        mSpec = spec;
        mAnimator = animator;
    }

    @Override
    public void startAnimation(SurfaceControl animationLeash, Transaction t,
            @AnimationType int type, @NonNull OnAnimationFinishedCallback finishCallback) {
        //调用SurfaceAnimationRunner的startAnimation方法
        mAnimator.startAnimation(mSpec, animationLeash, t,
                () -> finishCallback.onAnimationFinished(type, this));
    }
}
//frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
class SurfaceAnimationRunner {

    private static final class RunningAnimation {
        final AnimationSpec mAnimSpec;
        final SurfaceControl mLeash;
        final Runnable mFinishCallback;
        ValueAnimator mAnim;

        @GuardedBy("mCancelLock")
        private boolean mCancelled;

        RunningAnimation(AnimationSpec animSpec, SurfaceControl leash, Runnable finishCallback) {
            mAnimSpec = animSpec;
            mLeash = leash;
            mFinishCallback = finishCallback;
        }
    }
    
    final ArrayMap<SurfaceControl, RunningAnimation> mPendingAnimations = new ArrayMap<>();
    void startAnimation(AnimationSpec a, SurfaceControl animationLeash, Transaction t,
            Runnable finishCallback) {
        synchronized (mLock) {
        	//将AnimationSpec、SurfaceControl、Runnable三个参数封装成RunningAnimation对象
            final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash,
                    finishCallback);
            //将leash图层和其对应的RunningAnimation对象统一放到mPendingAnimations中,后面需要用到        
            mPendingAnimations.put(animationLeash, runningAnim);
            if (!mAnimationStartDeferred) {
                mChoreographer.postFrameCallback(this::startAnimations);//为同步信号设置回调方法startAnimations
            }
            // Some animations (e.g. move animations) require the initial transform to be applied
            // immediately.
            //这里最终会触发窗口对应的Surface的位置变化
            applyTransformation(runningAnim, t, 0 /* currentPlayTime */);
        }
    }
    
    private void startAnimations(long frameTimeNanos) {
    	//继续调用startPendingAnimationsLocke方法
        startPendingAnimationsLocked();
    }
   
    @GuardedBy("mLock")
    private void startPendingAnimationsLocked() {
        for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
        	//获取每个leash图层对应的RunningAnimation动画参数封装对象,执行对应的动画
            startAnimationLocked(mPendingAnimations.valueAt(i));
        }
        mPendingAnimations.clear();
    }
    
    private final Transaction mFrameTransaction;
    @GuardedBy("mLock")
    private void startAnimationLocked(RunningAnimation a) {
        final ValueAnimator anim = mAnimatorFactory.makeAnimator();
        // Animation length is already expected to be scaled.
        anim.overrideDurationScale(1.0f);
        anim.setDuration(a.mAnimSpec.getDuration());
        anim.addUpdateListener(animation -> {
            synchronized (mCancelLock) {
                if (!a.mCancelled) {
                    final long duration = anim.getDuration();
                    long currentPlayTime = anim.getCurrentPlayTime();
                    if (currentPlayTime > duration) {
                        currentPlayTime = duration;
                    }
                    //调用applyTransformation方法
                    applyTransformation(a, mFrameTransaction, currentPlayTime);
                }
            }
            // Transaction will be applied in the commit phase.
            scheduleApplyTransaction();
        });
        anim.addListener(new AnimatorListenerAdapter() {
      		...代码省略...
        });
        a.mAnim = anim;
        mRunningAnimations.put(a.mLeash, a);
        anim.start();
        if (a.mAnimSpec.canSkipFirstFrame()) {
            // If we can skip the first frame, we start one frame later.
            anim.setCurrentPlayTime(mChoreographer.getFrameIntervalNanos() / NANOS_PER_MS);
        }
        // Immediately start the animation by manually applying an animation frame. Otherwise, the
        // start time would only be set in the next frame, leading to a delay.
        anim.doAnimationFrame(mChoreographer.getFrameTime());
    }
}

    private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {
    	//RunningAnimation的mAnimSpec属性最早是在WindowState的startAnimation方法赋值的,
    	//这里调用的是WindowAnimationSpec的apply方法
        a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
    }
}

//frameworks/base/services/core/java/com/android/server/wm/WindowAnimationSpec.java
public class WindowAnimationSpec implements AnimationSpec {
	//此方法最终触发SurfaceControl的变化
    @Override
    public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
        final TmpValues tmp = mThreadLocalTmps.get();
        tmp.transformation.clear();
        mAnimation.getTransformation(currentPlayTime, tmp.transformation);
        tmp.transformation.getMatrix().postTranslate(mPosition.x, mPosition.y);
        t.setMatrix(leash, tmp.transformation.getMatrix(), tmp.floats);//设置图层的矩阵位置
        t.setAlpha(leash, tmp.transformation.getAlpha());//设置图层的透明度

        boolean cropSet = false;
        if (mRootTaskClipMode == ROOT_TASK_CLIP_NONE) {
            if (tmp.transformation.hasClipRect()) {
                t.setWindowCrop(leash, tmp.transformation.getClipRect());
                cropSet = true;
            }
        } else {
            mTmpRect.set(mRootTaskBounds);
            if (tmp.transformation.hasClipRect()) {
                mTmpRect.intersect(tmp.transformation.getClipRect());
            }
            t.setWindowCrop(leash, mTmpRect);
            cropSet = true;
        }

        // We can only apply rounded corner if a crop is set, as otherwise the value is meaningless,
        // since it doesn't have anything it's relative to.
        if (cropSet && mAnimation.hasRoundedCorners() && mWindowCornerRadius > 0) {
            t.setCornerRadius(leash, mWindowCornerRadius);
        }
    }
}
public final class SurfaceControl implements Parcelable {
    public static class Transaction implements Closeable, Parcelable {
       @UnsupportedAppUsage
        public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) {
            matrix.getValues(float9);
            setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y],
                    float9[MSKEW_X], float9[MSCALE_Y]);
            setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]);
            return this;
        }
        @NonNull
        public Transaction setAlpha(@NonNull SurfaceControl sc,
                @FloatRange(from = 0.0, to = 1.0) float alpha) {
            checkPreconditions(sc);
            nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
            return this;
        }
	}
}

3.2 时序图

时序图

四 移除Leash图层的代码源头

4.1 SurfaceControl$Transaction的remove方法

在窗口显示动画执行完毕之后,之前创建的leash图层将会被移除。在安卓系统中当一个Surface图层被移除的时候,会触发SurfaceControl$Transaction的remove方法,我们可以借这个方法追踪代码调用流程。

public final class SurfaceControl implements Parcelable {
	public static class Transaction implements Closeable, Parcelable {
	        public Transaction remove(@NonNull SurfaceControl sc) {
	            reparent(sc, null);//将当前Surface的父亲设置为空
	            sc.release();//释放
	            return this;
	        }
	 }
}

3.2 remove方法调用流程

3.2.1 堆栈信息

通过断点调试可以得到SurfaceControl$Transaction的remove方法的调用堆栈信息。方法调用堆栈01

3.2.2 remove方法源码调用流程

SurfaceAnimationRunner的startAnimation方法最终走到startAnimationLocked方法。

//frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
class SurfaceAnimationRunner {

    private static final class RunningAnimation {
        final AnimationSpec mAnimSpec;
        final SurfaceControl mLeash;
        final Runnable mFinishCallback;
        ValueAnimator mAnim;

        @GuardedBy("mCancelLock")
        private boolean mCancelled;

        RunningAnimation(AnimationSpec animSpec, SurfaceControl leash, Runnable finishCallback) {
            mAnimSpec = animSpec;
            mLeash = leash;
            mFinishCallback = finishCallback;
        }
    }

    @GuardedBy("mLock")
    private void startAnimationLocked(RunningAnimation a) {
		...代码省略...;
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
				...代码省略...
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                synchronized (mLock) {
                    mRunningAnimations.remove(a.mLeash);
                    synchronized (mCancelLock) {
                        if (!a.mCancelled) {
                            // Post on other thread that we can push final state without jank.
                            //动画结束,触发leash图层对应的Runnable对象的run方法,
                            //触发在LocalAnimationAdapter中设置的回调,OnAnimationFinishedCallback的onAnimationFinished方法
                            mAnimationThreadHandler.post(a.mFinishCallback);
                        }
                    }
                }
            }
        });
		...代码省略...
    }
}

//frameworks/base/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
class LocalAnimationAdapter implements AnimationAdapter {

    private final AnimationSpec mSpec;
    private final SurfaceAnimationRunner mAnimator;

    LocalAnimationAdapter(AnimationSpec spec, SurfaceAnimationRunner animator) {
        mSpec = spec;
        mAnimator = animator;
    }

    @Override
    public void startAnimation(SurfaceControl animationLeash, Transaction t,
            @AnimationType int type, @NonNull OnAnimationFinishedCallback finishCallback) {
        //窗口动画执行完毕会回调这里OnAnimationFinishedCallback的onAnimationFinished方法
        mAnimator.startAnimation(mSpec, animationLeash, t,
                () -> finishCallback.onAnimationFinished(type, this));
    }
} 

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

   final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;

  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;
        ...代码省略...
        //LocalAnimationAdapter的startAnimation方法最早是在这里传入的
        mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
    }
    
    SurfaceAnimator(Animatable animatable,
            @Nullable OnAnimationFinishedCallback staticAnimationFinishedCallback,
            WindowManagerService service) {
 		//mInnerAnimationFinishedCallback是在构造方法中被赋值的
        mInnerAnimationFinishedCallback = getFinishedCallback(staticAnimationFinishedCallback);
    }

	//动画结束会触发这里的回调
    private OnAnimationFinishedCallback getFinishedCallback(
            @Nullable OnAnimationFinishedCallback staticAnimationFinishedCallback) {
        return (type, anim) -> {
            synchronized (mService.mGlobalLock) {
            		...代码省略...
                    reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
                 	...代码省略...               
              }
        };
    }


    private void reset(Transaction t, boolean destroyLeash) {
     	...代码省略...
        SurfaceControl leash = mLeash;
        mLeash = null;
        //调用removeLeash方法
        final boolean scheduleAnim = removeLeash(t, mAnimatable, leash, destroyLeash);
        if (scheduleAnim) {
            mService.scheduleAnimationLocked();
        }
    }
    
    static boolean removeLeash(Transaction t, Animatable animatable, @NonNull SurfaceControl leash, boolean destroy) {
    	...代码省略...
        if (destroy) {
        	//调用SurfaceControl$Transaction的remove方法
            t.remove(leash);
            scheduleAnim = true;
        }
    	...代码省略...        
	}
}
//frameworks/base/core/java/android/view/SurfaceControl.java
public final class SurfaceControl implements Parcelable {
	public static class Transaction implements Closeable, Parcelable {
			//将leash图层移除
	        public Transaction remove(@NonNull SurfaceControl sc) {
	            reparent(sc, null);//将当前Surface的父亲设置为空
	            sc.release();//释放
	            return this;
	        }
	 }
}

3.2.3 时序图

时序图


网站公告

今日签到

点亮在社区的每一天
去签到