startTransition部分
frameworks/base/services/core/java/com/android/server/wm/WindowOrganizerController.java
@Override
public void startTransition(@NonNull IBinder transitionToken,
@Nullable WindowContainerTransaction t) {
startTransition(-1 /* unused type */, transitionToken, t);
}
private IBinder startTransition(@WindowManager.TransitionType int type,
@Nullable IBinder transitionToken, @Nullable WindowContainerTransaction t) {
//省略
Transition transition = Transition.fromBinder(transitionToken);
final WindowContainerTransaction wct =
t != null ? t : new WindowContainerTransaction();
//省略
if (t != null) {
wctApplied = new Transition.ReadyCondition("start WCT applied");
transition.mReadyTracker.add(wctApplied);
} else {
wctApplied = null;
}
if (transition.shouldApplyOnDisplayThread()) {
mService.mH.post(() -> {
synchronized (mService.mGlobalLock) {
transition.start();
applyTransaction(wct, -1 /* syncId */, transition, caller);
if (wctApplied != null) {
wctApplied.meet();
}
}
});
} else {
//调用transition.start方法启动
transition.start();
//再调用的applyTransaction方法
applyTransaction(wct, -1 /* syncId */, transition, caller);
}
//省略
}
下面重点看看transition.start()和applyTransaction方法
frameworks/base/services/core/java/com/android/server/wm/Transition.java
/**
* Formally starts the transition. Participants can be collected before this is started,
* but this won't consider itself ready until started -- even if all the participants have
* drawn.
*/
void start() {
if (mState < STATE_COLLECTING) {
throw new IllegalStateException("Can't start Transition which isn't collecting.");
} else if (mState >= STATE_STARTED) {
Slog.w(TAG, "Transition already started id=" + mSyncId + " state=" + mState);
// The transition may be aborted (STATE_ABORT) or timed out (STATE_PLAYING by
// SyncGroup#finishNow), so do not revert the state to STATE_STARTED.
return;
}
mState = STATE_STARTED;//赋值mState为STATE_STARTED
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
mSyncId);
applyReady();//这里会判断当前是否ready,设置到SyncEngine中
mLogger.mStartTimeNs = SystemClock.elapsedRealtimeNanos();
mController.updateAnimatingState();
}
private void applyReady() {
if (mState < STATE_STARTED) return;
final boolean ready;
if (mController.useFullReadyTracking()) {
ready = mReadyTracker.isReady();
} else {
ready = mReadyTrackerOld.allReady();//获取是否ready值
}
boolean changed = mSyncEngine.setReady(mSyncId, ready);//再对sync进行设置ready
if (changed && ready) {
mLogger.mReadyTimeNs = SystemClock.elapsedRealtimeNanos();
mOnTopTasksAtReady.clear();
for (int i = 0; i < mTargetDisplays.size(); ++i) {
addOnTopTasks(mTargetDisplays.get(i), mOnTopTasksAtReady);
}
mController.onTransitionPopulated(this);
}
}
start干的事情主要有2个:
1、把Transition的mState变成STATE_STARTED
2、调用applyReady方法,主要就是获取一下ready值,再设置,所以这个地方其实并没有说有完全设置read为true,而是根据当前ready值来
再接下来看看applyTransaction(wct, -1 /* syncId */, transition, caller);方法调用
因为wct其实是null传递过来的,但是applyTransaction实现主要又是针对wct有内容的情况,所以applyTransaction基本上啥也没干针对这种启动Activity场景。
那么到这里WMShell -----------------> WMCore这个过程就完成了,接下来的就是WMCore等待收集的WindowContainer完成绘制finish后,再触发onTransactionReady了.
WMCore收集的wc情况
前面Transition收集只讲解最基本的collect打开的ActivityRecord,但是打开一个Activity其实涉及的wc还是很多,比如打开Activity意味者上一Activity要被隐藏,而且隐藏的Activity还可能显示壁纸。
为了更好定位出collect收集了哪些wc,又是在什么时机收集的,这里加入日志打印更加方便定位
简单的桌面打开Activity场景一共有如下6次收集
收集的wc有3个是重复的,都是ActivityRecord,所以最后收集到了4个wc,即Transition的mParticipants集合一共有四个元素,一般对应的SyncGroup的mRootMembers也有四个元素。
第1次collect在startActivityUnchecked
collect ActivityRecord{3762177 u0 com.android.dialer/.main.impl.MainActivity t-1}
java.lang.Exception
at com.android.server.wm.Transition.collect(Transition.java:685)
at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1541)
at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1361)
at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:782)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1312)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1257)
at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1232)
at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:910)
at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5722)
at android.os.Binder.execTransactInternal(Binder.java:1500)
第2次collect,因为Activity要启动肯定需要有对应Task,这里一般会新建一个Task,新建Task一般属于从无到有所以会触发collectExistenceChange进行收集Task并且置位mExistenceChange = true
java.lang.Exception
at com.android.server.wm.Transition.collect(Transition.java:685)
at com.android.server.wm.Transition.collectExistenceChange(Transition.java:795)
at com.android.server.wm.TransitionController.collectExistenceChange(TransitionController.java:810)
at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2932)
at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1829)
at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1544)
at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1361)
at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:782)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1312)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1257)
at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1232)
at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:910)
at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5722)
at android.os.Binder.execTransactInternal(Binder.java:1500)
at android.os.Binder.execTransact(Binder.java:1444)
第3次collect因为要启动Activity在进行handleStartResult时候判断存在性有变化,所以会触发collectExistenceChange方法里面会collect,前面Activity已经收集过,所以这次也属于无效收集
collect ActivityRecord{3762177 u0 com.android.dialer/.main.impl.MainActivity t266}
java.lang.Exception
at com.android.server.wm.Transition.collect(Transition.java:685)
at com.android.server.wm.Transition.collectExistenceChange(Transition.java:795)
at com.android.server.wm.TransitionController.collectExistenceChange(TransitionController.java:810)
at com.android.server.wm.ActivityStarter.handleStartResult(ActivityStarter.java:1652)
at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1551)
at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1361)
at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:782)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1312)
at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1257)
at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1232)
at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:910)
at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5722)
at android.os.Binder.execTransactInternal(Binder.java:1500)
at android.os.Binder.execTransact(Binder.java:1444)
第4次collect,因为Launcher的ActivityPasue后,系统会保证前台Activity显示,所以触发收集,但是因为前面已经收集过了所以这次无效
collect ActivityRecord{3762177 u0 com.android.dialer/.main.impl.MainActivity t266}
java.lang.Exception
at com.android.server.wm.Transition.collect(Transition.java:685)
at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5583)
at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5544)
at com.android.server.wm.EnsureActivitiesVisibleHelper.makeVisibleAndRestartIfNeeded(EnsureActivitiesVisibleHelper.java:238)
at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:181)
at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:130)
at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1332)
at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:5036)
at com.android.server.wm.Task.$r8$lambda$DbhuUlekQ2cVQp1TiLmGb_W7C-g(Task.java:0)
at com.android.server.wm.Task$$ExternalSyntheticLambda2.accept(R8$$SyntheticClass:0)
at com.android.server.wm.Task.forAllLeafTasks(Task.java:3154)
at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:5035)
at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:6549)
at com.android.server.wm.DisplayContent.$r8$lambda$B9Mi2o96X6cYtjvyI8f4PcEeMbM(DisplayContent.java:0)
at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda22.accept(R8$$SyntheticClass:0)
at com.android.server.wm.Task.forAllRootTasks(Task.java:3166)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2206)
at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6548)
at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1913)
at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1896)
at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1987)
at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6599)
at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:231)
at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:698)
at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
at android.os.Binder.execTransactInternal(Binder.java:1500)
at android.os.Binder.execTransact(Binder.java:1444)
第5次collect,因为Launcher要Pasue所以Launcher可见性就变得不可见,不可见设置时候就触发collect收集
collect ActivityRecord{edc7080 u0 com.android.launcher3/.uioverrides.QuickstepLauncher t253}
java.lang.Exception
at com.android.server.wm.Transition.collect(Transition.java:685)
at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5583)
at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5544)
at com.android.server.wm.ActivityRecord.makeInvisible(ActivityRecord.java:6330)
at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:208)
at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:130)
at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1332)
at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:5036)
at com.android.server.wm.Task.$r8$lambda$DbhuUlekQ2cVQp1TiLmGb_W7C-g(Task.java:0)
at com.android.server.wm.Task$$ExternalSyntheticLambda2.accept(R8$$SyntheticClass:0)
at com.android.server.wm.Task.forAllLeafTasks(Task.java:3154)
at com.android.server.wm.Task.forAllLeafTasks(Task.java:3142)
at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:5035)
at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:6549)
at com.android.server.wm.DisplayContent.$r8$lambda$B9Mi2o96X6cYtjvyI8f4PcEeMbM(DisplayContent.java:0)
at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda22.accept(R8$$SyntheticClass:0)
at com.android.server.wm.Task.forAllRootTasks(Task.java:3166)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2206)
at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6548)
at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1913)
at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1896)
at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1987)
at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6599)
at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:231)
at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:698)
at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
at android.os.Binder.execTransactInternal(Binder.java:1500)
at android.os.Binder.execTransact(Binder.java:1444)
第6次collect的是ImageWallpaper,触发时机本质就是Launcher隐藏了,Launcher显示Wallpaper的,所以Launcher隐藏自然Wallpaper也要隐藏
12-17 11:18:13.227 544 562 I lsm888888: collect Window{7198a68 u0 com.android.systemui.wallpapers.ImageWallpaper}
12-17 11:18:13.227 544 562 I lsm888888: java.lang.Exception
at com.android.server.wm.Transition.collect(Transition.java:685)
at com.android.server.wm.WallpaperController.collectTopWallpapers(WallpaperController.java:771)
at com.android.server.wm.Transition.collect(Transition.java:711)
at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5583)
at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5544)
at com.android.server.wm.ActivityRecord.makeInvisible(ActivityRecord.java:6330)
at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:208)
at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:130)
at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1332)
at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:5036)
at com.android.server.wm.Task.$r8$lambda$DbhuUlekQ2cVQp1TiLmGb_W7C-g(Task.java:0)
at com.android.server.wm.Task$$ExternalSyntheticLambda2.accept(R8$$SyntheticClass:0)
at com.android.server.wm.Task.forAllLeafTasks(Task.java:3154)
at com.android.server.wm.Task.forAllLeafTasks(Task.java:3142)
at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:5035)
at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:6549)
at com.android.server.wm.DisplayContent.$r8$lambda$B9Mi2o96X6cYtjvyI8f4PcEeMbM(DisplayContent.java:0)
at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda22.accept(R8$$SyntheticClass:0)
at com.android.server.wm.Task.forAllRootTasks(Task.java:3166)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2206)
at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6548)
at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1913)
at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1896)
at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1987)
at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6599)
at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:231)
at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:698)
at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
at android.os.Binder.execTransactInternal(Binder.java:1500)
at android.os.Binder.execTransact(Binder.java:1444)
进入SyncGroup等待期间
上面收集到了4个wc,那么Transition要可以进入下一个环节就必须要保证,4个wc都已经进行FinishSync才可以进入到Finished。
要进入Finished需要满足下面两个条件:
1、Transition处于ready = true状态,因为只有属于ready后,才会触发wc的是否finish检测
2、挨个遍历SyncGroup的mRootMember是否都进行finish,只要有一个没有就不可以
那么是什么时机设置ready为true呢?
堆栈可以看出来是在ActivityRecord.onStartingWindowDrawn会触发executeAppTransition调用到TransitionController.setReady
frameworks/base/services/core/java/com/android/server/wm/Transition.java
void setReady(WindowContainer wc, boolean ready) {
android.util.Log.i("lsm888888","call setReady "+ready,new Exception());
if (!isCollecting() || mSyncId < 0) return;
mReadyTrackerOld.setReadyFrom(wc, ready);
applyReady();
}
private void applyReady() {
if (mState < STATE_STARTED) return;
final boolean ready;
if (mController.useFullReadyTracking()) {
ready = mReadyTracker.isReady();
} else {
ready = mReadyTrackerOld.allReady();
}
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
"Set transition ready=%b %d", ready, mSyncId);
boolean changed = mSyncEngine.setReady(mSyncId, ready);//根据当前mSyncId调用到SyncGroup的
}
frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java
boolean setReady(int id, boolean ready) {
return getSyncGroup(id).setReady(ready);
}
/** returns true if readiness changed. */
private boolean setReady(boolean ready) {
if (mReady == ready) {
return false;
}
ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready %b", mSyncId, ready);
mReady = ready;//就是让mReady为true
if (ready) {
mWm.mWindowPlacerLocked.requestTraversal();
}
return true;
}
相关堆栈
call setReady true
java.lang.Exception
at com.android.server.wm.Transition.setReady(Transition.java:943)
at com.android.server.wm.TransitionController.setReady(TransitionController.java:894)
at com.android.server.wm.TransitionController.setReady(TransitionController.java:899)
at com.android.server.wm.DisplayContent.executeAppTransition(DisplayContent.java:5690)
at com.android.server.wm.ActivityRecord.onStartingWindowDrawn(ActivityRecord.java:7012)
at com.android.server.wm.WindowState.performShowLocked(WindowState.java:4431)
at com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked(WindowStateAnimator.java:259)
at com.android.server.wm.DisplayContent.lambda$new$8(DisplayContent.java:1016)
at com.android.server.wm.DisplayContent.$r8$lambda$-dBz3LtsWovWVT0SE5m__EwNfT4(DisplayContent.java:0)
at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda32.accept(R8$$SyntheticClass:0)
at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2833)
at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2823)
at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4663)
at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4528)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1816)
at com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:5047)
at com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:985)
at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:785)
at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:751)
at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)
at com.android.server.ServiceThread.run(ServiceThread.java:46)
wc的Finished检测
检测触发函数是performSurfacePlacementNoTrace
具体检测逻辑代码
void onSurfacePlacement() {
if (mActiveSyncs.isEmpty()) return;
while (!mTmpFinishQueue.isEmpty()) {
if (visitBounds <= 0) {
Slog.e(TAG, "Trying to finish more syncs than theoretically possible. This "
+ "should never happen. Most likely a dependency cycle wasn't detected.");
}
--visitBounds;
final SyncGroup group = mTmpFinishQueue.remove(0);
final int grpIdx = mActiveSyncs.indexOf(group);
// Skip if it's already finished:
if (grpIdx < 0) continue;
if (!group.tryFinish()) continue;//这里会调用到SyncGroup的
}
}
这里onSurfacePlacement主要就是调用SyncGroup的tryFinish方法
/** @return `true` if it finished. */
private boolean tryFinish() {
if (!mReady) {//这里注意如果mReady为false就会直接返回
Log.i("WindowManager"," tryFinish "+mReady);
return false;
}
ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: onSurfacePlacement checking %s",
mSyncId, mRootMembers);
if (!mDependencies.isEmpty()) {
ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Unfinished dependencies: %s",
mSyncId, mDependencies);
return false;
}
for (int i = mRootMembers.size() - 1; i >= 0; --i) {//遍历mRootMembers的每个wc
final WindowContainer wc = mRootMembers.valueAt(i);
if (!wc.isSyncFinished(this)) {//如果有一个没有完成就会中断
ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Unfinished container: %s",
mSyncId, wc);
return false;
}
}
finishNow();
return true;
}
重点看看wc.isSyncFinished方法,这里isSyncFinished重载比较多,重点判断还是WindowContainer为最重要
boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
if (!isVisibleRequested()) {
return true;
}
if (mSyncState == SYNC_STATE_NONE && getSyncGroup() != null) {
prepareSync();
}
//如果WindowState还没绘制完成就是这个状态,其他非WindowState一般都不是这个SYNC_STATE_WAITING_FOR_DRAW
if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW) {
return false;
}
// READY
// Loop from top-down.
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer child = mChildren.get(i);
//这里会遍历每个child是否isSyncFinished为true
final boolean childFinished = group.isIgnoring(child) || child.isSyncFinished(group);
if (childFinished && child.isVisibleRequested() && child.fillsParent()) {
// Any lower children will be covered-up, so we can consider this finished.
return true;
}
if (!childFinished) {
return false;
}
}
return true;
}
上面可以看出其实遍历ActivityRecord的isSyncFinished其实就会遍历到它对应的WindowState的isSyncFinished。
所以核心看看WindowState相关的设置情况:
正常情况下只有WindowState会把mSyncState设置成SYNC_STATE_WAITING_FOR_DRAW
注意这里的prepareSync其实在前面的SyncGroup的addToSync时候调用的
在finishDraw时候才会设置的
onSyncFinishedDrawing调用堆栈情况
onSyncFinishedDrawing:3929, WindowContainer (com.android.server.wm)
finishDrawing:5874, WindowState (com.android.server.wm)
finishDrawingWindow:2857, WindowManagerService (com.android.server.wm)
finishDrawing:350, Session (com.android.server.wm)
onTransact:815, IWindowSession$Stub (android.view)
onTransact:206, Session (com.android.server.wm)
execTransactInternal:1505, Binder (android.os)
execTransact:1444, Binder (android.os)