接着上一篇继续分析:
最终根据调用链路追踪到了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