前言
在Android 16系统源码_窗口动画(一)窗口过渡动画层级图分析这篇文章我们有分析过,系统触发窗口显示动画的过程中,会创建一个leash图层,本篇文章我们将会结合源码具体来分析下该图层的创建流程。
一 创建Leash图层的代码源头
1.1 查找创建leash图层的代码源头
触发窗口动画时候的SurfaceFlinger图层信息如下所示。
在叶子节点下回多了一个含有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;
}
}
以上代码需要重点关注以下几点
- 在WindowStateAnimator的loadAnimationAttr方法中,会判断使用哪种窗口动画以及进行窗口动画资源的加载。
- 在WindowState的startAnimation方法中,会创建LocalAnimationAdapter本地动画实例对象。
- 在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方法的调用堆栈信息。
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;
}
}
}