一、简介
WMS中的窗口绘制与显示的载体是Surface,而Surface在底层SurfaceFlinger中的存在形式为Layer,Layer的显示受到上层Surface状态的影响:当Surface被设为可见、且alpha不为0、没有被hidden时,底层Layer才会被判断为可见、进而参与Layer合成流程并在下一帧显示在屏幕上;当上层Surface被销毁时,底层Layer也会从SurfaceFlinger所维护的Layer列表中移除。而上层WMS需要实时的、通过binder通信跨进程将Surface信息更新至SurfaceFlinger进程。而Surface相关的信息载体,便是Transaction,上层可以通过Transaction来实现对Surface的一系列操作,比如显示、隐藏、销毁、设置alpha、设置父节点等。WMS并不是在app刷新的每一帧都涉及对Transaction的操作,而是会在窗口首帧、或者窗口信息发生变化、或者app设置了syncNextTransaction callback等特殊时机会通过Transaction向SurfaceFlinger更新Surface信息,这些信息的更新,直接影响到窗口的显示/隐藏、buffer的流转与处理等。
谈到Transaction,离不开BLASTSyncEngine机制,很多时候界面刷新时会触发BLASTSyncEngine机制,该机制中对于Transaction的处理过程略显繁琐,因此在梳理WMS中对于transaction的处理流程时需要单独拿出来说一说。
本文相关流程的梳理基于android14代码。
二、BLASTSyncEngine机制
1.介绍
谷歌原生代码对于BLASTSyncEngine机制的注释比较晦涩难懂,个人对于该机制的总体理解是:在触发过渡动画的场景(比如task切换、activity切换、屏幕旋转等),会导致相关windowContainer(activityRecord及以上级别)发生变化,这时通过BLASTSyncEngine机制去实时监控windowContainer的变化,并等待绘制完成时去收集相关windowContainer及其child的syncTransaction,并在适当时机对收集起来的transaction进行merge以及apply。该机制会影响到参与过渡动画的窗口的可见性,从而引发黑屏、anr等问题。因此有必要对该机制的发起与结束时机、涉及对象、具体作用等进行梳理。
2.发起sync流程
通过addToSyncSet把需要参与sync流程的windowContainer收集起来。而参与sync流程的窗口是在sync流程发起时、在BLASTSyncEngine.addToSync方法中会执windowContainer.prepareSync方法,这里的windowContainer为task或activityRecord级别,会遍历其child执行到windowState这一级别的prepareSync方法,此时windowState会将mSyncState置为SYNC_STATE_WAITING_FOR_DRAW,表示等待窗口绘制完成。
frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java
475 void addToSyncSet(int id, WindowContainer wc) {
>>通过id获取对应的syncGroup
476 getSyncGroup(id).addToSync(wc);
477 }
304 private void addToSync(WindowContainer wc) {
>>如果当前windowContainer已经添加至mRootMembers,则直接return
305 if (mRootMembers.contains(wc)) {
306 return;
307 }
308 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Adding to group: %s", mSyncId, wc);
309 final SyncGroup dependency = wc.getSyncGroup();
310 if (dependency != null && dependency != this && !dependency.isIgnoring(wc)) {
...
335 } else {
>>将windowContainer添加至mRootMembers
336 mRootMembers.add(wc);
337 wc.setSyncGroup(this);
338 }
>>触发windowContainer的prepareSync流程
339 wc.prepareSync();
340 if (mReady) {
341 mWm.mWindowPlacerLocked.requestTraversal();
342 }
/frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
3865 boolean prepareSync() {
3866 if (mSyncState != SYNC_STATE_NONE) {
3867 // Already part of sync
3868 return false;
3869 }
3870 for (int i = getChildCount() - 1; i >= 0; --i) {
>>循环遍历child,执行child对应的prepareSync方法
>>由于发起sync流程的是task或者activityRecord级别的windowContainer,所以对应child为activityRecord或者windowState
3871 final WindowContainer child = getChildAt(i);
3872 child.prepareSync();
3873 }
>>切换syncState为SYNC_STATE_READY
3874 mSyncState = SYNC_STATE_READY;
3875 return true;
3876 }
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
5655 @Override
5656 boolean prepareSync() {
5657 if (!mDrawHandlers.isEmpty()) {
5658 Slog.w(TAG, "prepareSync with mDrawHandlers, " + this + ", " + Debug.getCallers(8));
5659 }
...
5667 // In the WindowContainer implementation we immediately mark ready
5668 // since a generic WindowContainer only needs to wait for its
5669 // children to finish and is immediately ready from its own
5670 // perspective but at the WindowState level we need to wait for ourselves
5671 // to draw even if the children draw first or don't need to sync, so we start
5672 // in WAITING state rather than READY.
>>最终遍历child会执行到WindowState.prepareSync方法,将syncState切换为SYNC_STATE_WAITING_FOR_DRAW
>>表示等待窗口绘制完成
5673 mSyncState = SYNC_STATE_WAITING_FOR_DRAW;
以桌面热启动Settins为例,此场景会通过三个不同的路径向BLASTSyncEngine添加将要参加sync流程的windowContainer,这些windowContainer在冷/热启动场景是activityRecord或者task级别,并将这些windowContainer添加至对应syncGroup中的列表mRootMembers中,为后续流程做准备。
1)ATMS.startActivityAsUser->ActivityStarter.execute->executeRequest
->startActivityUnchecked->TransitionController.collect->Transition.collect->BLASTSyncEngine.addToSyncSet
2)RootWindowContainer.resumeFocusedTasksTopActivities->Task.resumeTopActivityUncheckedLocked->resumeTopActivityInnerLocked->TaskFragment.resumeTopActivity->ActivityRecord.setVisibility->TransitionController.collect->Transition.collect->BLASTSyncEngine.addToSyncSet
3)TaskFragment.updateActivityVisibilities->EnsureActivitiesVisibleHelper.process->setActivityVisibilityState->ActivityRecord.makeInvisible->setVisibility->TransitionController.collect->Transition.collect->BLASTSyncEngine.addToSyncSet
3.sync对象
真正参与sync流程的windowContainer除了前面提到的mRootMembers中的,还有这些windowContainer自身的child(比如mainWindow、childWindow、startingWindow、activityRecord等)。主要体现在如下几个方面:
1)在执行finishSync流程时,会依次递归遍历mRootMembers中的每一个windowContainer及其child,并把每一个windowContainer对应的mSyncTransaction给merge到outMergedTransaction中;
2)在执行waitForSyncTransactionCommit方法时会遍历mRootMembers把所有windowContainer收集起来并添加到wcAwaitingCommit集合中,同时再递归遍历child windowContainer并加入到wcAwaitingCommit中,为后续执行CommitCallback中的逻辑做准备。
/frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java
206 private void finishNow() {
207 if (mTraceName != null) {
208 Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, mTraceName, mSyncId);
209 }
210 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Finished!", mSyncId);
>>新建Transaction类型的临时变量merged
211 SurfaceControl.Transaction merged = mWm.mTransactionFactory.get();
212 if (mOrphanTransaction != null) {
213 merged.merge(mOrphanTransaction);
214 }
215 for (WindowContainer wc : mRootMembers) {
>>遍历mRootMembers执行finishSync流程,将windowContainer对应的mSyncTransaction给merge到merged中
216 wc.finishSync(merged, this, false /* cancel */);
217 }
218
>>新建临时变量wcAwaitingCommit
219 final ArraySet<WindowContainer> wcAwaitingCommit = new ArraySet<>();
220 for (WindowContainer wc : mRootMembers) {
>>遍历mRootMembers将所有参与sync流程的windowContainer收集起来并保存在wcAwaitingCommit
221 wc.waitForSyncTransactionCommit(wcAwaitingCommit);
222 }
/frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
3889 void finishSync(Transaction outMergedTransaction, BLASTSyncEngine.SyncGroup group,
3890 boolean cancel) {
3891 if (mSyncState == SYNC_STATE_NONE) return;
3892 final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
3893 // If it's null, then we need to clean-up anyways.
3894 if (syncGroup != null && group != syncGroup) return;
3895 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "finishSync cancel=%b for %s", cancel, this);
>>将mSyncTransaction给merge到outMergedTransaction中
3896 outMergedTransaction.merge(mSyncTransaction);
3897 for (int i = mChildren.size() - 1; i >= 0; --i) {
3898 mChildren.get(i).finishSync(outMergedTransaction, group, cancel);
3899 }
3900 if (cancel && mSyncGroup != null) mSyncGroup.onCancelSync(this);
>>切换syncState为SYNC_STATE_NONE
3901 mSyncState = SYNC_STATE_NONE;
3902 mSyncMethodOverride = BLASTSyncEngine.METHOD_UNDEFINED;
3903
4222 void waitForSyncTransactionCommit(ArraySet<WindowContainer> wcAwaitingCommit) {
4223 if (wcAwaitingCommit.contains(this)) {
4224 return;
4225 }
>>mSyncTransactionCommitCallbackDepth加1
4226 mSyncTransactionCommitCallbackDepth++;
>>将windowContainer添加到wcAwaitingCommit
4227 wcAwaitingCommit.add(this);
4228
4229 for (int i = mChildren.size() - 1; i >= 0; --i) {
>>递归遍历child执行waitForSyncTransactionCommit流程
4230 mChildren.get(i).waitForSyncTransactionCommit(wcAwaitingCommit);
4231 }
4232 }
4233
4.检查sync流程
当WMS中每次刷新时,会检查所有参与sync流程的windowContainer(主要是windowState这一层级)是否都绘制完成,若是,则会触发finishNow流程,相关代码流程如下:
WindowSurfacePlacer.performSurfacePlacement->performSurfacePlacementLoop->RootWindowContainer.performSurfacePlacement->performSurfacePlacementNoTrace->BLASTSyncEngine.onSurfacePlacement->BLASTSyncEngine.SyncGroup.tryFinish->finishNow
检查sync流程是否满足结束的条件,主要逻辑在BLASTSyncEngine.tryFinish和windowContainer.isSyncFinished方法中,首先会去遍历mRootMembers中的每一个rootMember,并判断是否均已达到要求,只要有一个不满足要求,便会返回false。
/frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java
184 /** @return `true` if it finished. */
185 private boolean tryFinish() {
186 if (!mReady) return false;
187 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: onSurfacePlacement checking %s",
188 mSyncId, mRootMembers);
189 if (!mDependencies.isEmpty()) {
190 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Unfinished dependencies: %s",
191 mSyncId, mDependencies);
192 return false;
193 }
194 for (int i = mRootMembers.size() - 1; i >= 0; --i) {
195 final WindowContainer wc = mRootMembers.valueAt(i);
>>遍历mRootMembers,只要有一个rootMember没有达到完成sync流程的条件就会return
196 if (!wc.isSyncFinished(this)) {
197 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Unfinished container: %s",
198 mSyncId, wc);
199 return false;
200 }
201 }
>>执行finishNow方法,准备结束sync流程
202 finishNow();
203 return true;
204 }
判断sync是否达到结束的条件,本质上是判断所有参与sync流程的windowContainer是否完成绘制。比如,当launcher参与sync时,需要其两个窗口(一个mainWindow,一个childWindow)均完成绘制时才满足要求。但如果某一个rootMember的startingWindow完成绘制,此时startingWindow满足child.fillsParent这个条件,所以即使该rootMember对应的mainWindow尚未完成绘制,也会判断
为该rootMember完成了绘制、已达到要求。所以,冷/热启动场景mainWindow一般不会实际参与sync流程(即对应transaction不会在BLASTSyncEngine中进行merge)。
frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
3913 boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
3914 if (!isVisibleRequested()) {
3915 return true;
3916 }
3917 if (mSyncState == SYNC_STATE_NONE) {
3918 prepareSync();
3919 }
>>如果window没有绘制完成,此时满足mSyncState = SYNC_STATE_WAITING_FOR_DRAW, 会被return false
3920 if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW) {
3921 return false;
3922 }
3923 // READY
3924 // Loop from top-down.
>>从上往下、递归遍历判断每一个child是否完成sync
3925 for (int i = mChildren.size() - 1; i >= 0; --i) {
3926 final WindowContainer child = mChildren.get(i);
3927 final boolean childFinished = group.isIgnoring(child) || child.isSyncFinished(group);
>>如果当前child已经完成sync且child为startingWindow(满足fillsParent条件)则返回true
>>否则需要所有child完成sync时,当前rootMember才算是做好结束sync流程的准备
3928 if (childFinished && child.isVisibleRequested() && child.fillsParent()) {
3929 // Any lower children will be covered-up, so we can consider this finished.
3930 return true;
3931 }
>>有child没有完成sync则返回false
3932 if (!childFinished) {
3933 return false;
3934 }
3935 }
>>如果遍历到windowState级别的child,且已经绘制完成、没有子窗口,那么此时windowState对应的isSyncFinished方法返回true
3936 return true;
3937 }
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
5794 boolean fillsParent() {
>>若当前窗口为startingWindow则满足fillsParent、返回true
5795 return mAttrs.type == TYPE_APPLICATION_STARTING;
5796 }
5.结束sync流程
窗口绘制完成,一般有两种说法:一种是,窗口第一帧绘制完成底层回调onFrameAvailable、app侧调用reportDrawFinished方法通知WMS,WMS随即将对应窗口状态从draw_pending切换为commit_draw_pending;另一种是WMS将对应窗口状态在前面流程的基础上从draw_pending逐步切换到has_drawn(最终状态)。像亮屏、应用启动等场景采取第二种标准,而此处sync流程则对应第一种标准。
当app第一帧绘制完成并通知到WMS后,会执行windowState.finishDrawing方法,相关代码流程如下:
ViewRootImpl.reportDrawFinished->Session.finishDrawing->WMS.finishDrawingWindow->WindowState.finishDrawing
当判断到"else if (useBLASTSync())"条件成立,会调用执行onSyncFinishedDrawing方法,将mSyncState由原来的状态SYNC_STATE_WAITING_FOR_DRAW更新为SYNC_STATE_READY,即当前窗口对于sync流程来说已经绘制完成了,待后面WMS刷新、检测到mSyncState为SYNC_STATE_READY时会尝试走finishNow逻辑去结束sync流程。
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
5725 boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
...
>>如果当前正处于sync流程,则执行onSyncFinishedDrawing方法切换syncState
5777 } else if (useBLASTSync()) {
5778 // Sync that is not using BLAST
5779 layoutNeeded = onSyncFinishedDrawing();
5780 }
5781
5782 layoutNeeded |= mWinAnimator.finishDrawingLocked(postDrawTransaction);
5783 // We always want to force a traversal after a finish draw for blast sync.
5784 return !skipLayout && (hasSyncHandlers || layoutNeeded);
frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
3878 boolean useBLASTSync() {
>>若syncState不为SYNC_STATE_NONE则说明当前处于sync流程
3879 return mSyncState != SYNC_STATE_NONE;
3880 }
3832 boolean onSyncFinishedDrawing() {
3833 if (mSyncState == SYNC_STATE_NONE) return false;
>>切换syncState为SYNC_STATE_READY
3834 mSyncState = SYNC_STATE_READY;
3835 mSyncMethodOverride = BLASTSyncEngine.METHOD_UNDEFINED;
3836 ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "onSyncFinishedDrawing %s", this);
3837 return true;
3838 }
6.完成sync流程
当sync流程完成时,merge之后的transaction会在随后的过渡动画开始前进行apply,在SurfaceFlinger处理此transaction时会回调CommitCallback.onCommitted方法,此时那些参与sync流程的windowContainer所对应的mSyncTransaction才会被运行去apply,避免后续的transaction对前面在BLASTSyncEngine中进行merge之后的transaction的apply产生影响,即确保transaction的apply顺序。
这里还有一个超时机制,即当transaction对应的callback超过5s(BLAST_TIMEOUT_DURATION)未回调时,会去强制回调callback去执行相关transaction的apply。
/frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java
206 private void finishNow() {
...
219 final ArraySet<WindowContainer> wcAwaitingCommit = new ArraySet<>();
220 for (WindowContainer wc : mRootMembers) {
221 wc.waitForSyncTransactionCommit(wcAwaitingCommit);
222 }
>>实现CommitCallback逻辑,当transaction提交后或者超时后触发此逻辑
223 class CommitCallback implements Runnable {
224 // Can run a second time if the action completes after the timeout.
225 boolean ran = false;
>>当transaction完成提交后会执行onCommitted方法
>>若超时未回调callback执行onCommitted方法,则会触发超时逻辑执行callback.run方法,最终还说会执行onCommitted方法
226 public void onCommitted(SurfaceControl.Transaction t) {
227 synchronized (mWm.mGlobalLock) {
228 if (ran) {
229 return;
230 }
>>移除callback
231 mHandler.removeCallbacks(this);
232 ran = true;
>>收集wcAwaitingCommit所有windowContainer中待提交的mSyncTransaction,并merge到t中
233 for (WindowContainer wc : wcAwaitingCommit) {
234 wc.onSyncTransactionCommitted(t);
235 }
>>提交transaction
236 t.apply();
237 wcAwaitingCommit.clear();
238 }
239 }
240
241 // Called in timeout
242 @Override
>>若超时未回调callback,则触发此逻辑执行run方法
243 public void run() {
244 // Sometimes we get a trace, sometimes we get a bugreport without
245 // a trace. Since these kind of ANRs can trigger such an issue,
246 // try and ensure we will have some visibility in both cases.
247 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionCommitTimeout");
248 Slog.e(TAG, "WM sent Transaction to organized, but never received" +
249 " commit callback. Application ANR likely to follow.");
250 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
251 synchronized (mWm.mGlobalLock) {
>>超时后执行onCommitted方法
252 onCommitted(merged.mNativeObject != 0
253 ? merged : mWm.mTransactionFactory.get());
254 }
255 }
256 };
257 CommitCallback callback = new CommitCallback();
>>向transaction注册对应的listener,待提交后触发listener的回调
258 merged.addTransactionCommittedListener(Runnable::run,
259 () -> callback.onCommitted(new SurfaceControl.Transaction()));
>>延时执行callback.run,超时时间为BLAST_TIMEOUT_DURATION
260 mHandler.postDelayed(callback, BLAST_TIMEOUT_DURATION);
sync流程真正结束的时机是CommitCallback.onCommitted回调的时候,此时调用WindowContainer.onSyncTransactionCommitted方法去收集所有windowContainer对应的mSyncTransaction并进行apply。
7.syncState状态切换
sync流程中,windowContainer对应的syncState状态生命周期如下:
SYNC_STATE_NONE->SYNC_STATE_WAITING_FOR_DRAW->SYNC_STATE_READY->SYNC_STATE_NONE
结合前面流程可知,syncState初始状态为SYNC_STATE_NONE,当通过addToSync发起sync流程后,通过BLASTSyncEngine.addToSync->WindowContainer.prepareSyncs 流程将syncState切换为SYNC_STATE_WAITING_FOR_DRAW,等待窗口绘制完成。当窗口绘制完成后,会通过WindowState.finishDrawing->windowContainer.onSyncFinishedDrawing流程将syncState切换为SYNC_STATE_READY。最后,sync流程准备结束时,会通过BLASTSyncEngine.finishNow->WindowContainer.finishSync流程将syncState重置为SYNC_STATE_NONE。
三、Transaction处理流程
前面对WMS中的BLASTSyncEngine机制进行了介绍,下面将梳理在app->WMS->SurfaceFlinger链路上各个关键节点对transaction的处理情况,其中sync流程与非sync流程对于transaction的处理有很大不同、且sync流程中对于transaction的处理比较复杂,因此这里先介绍sync流程中对于transaction的处理、再介绍非sync流程对于transaction的处理。
1.ViewRootImpl
当app第一帧绘制完成时会通知到WMS,后续WMS会更新app对应窗口的状态并将相关窗口信息更新到SurfaceFlinger,为后续窗口在屏幕上显示出来做准备。而app是在ViewRootImpl.reportDrawFinished方法,通过binder通信来通知WMS,这时会把app侧的transaction发送到WMS。当app侧向BLASTBufferQueue设置了syncNextTransaction callback时,该transaction中会包含底层传上来的、与当前帧相关的buffer,即底层把该buffer的提交权交给上层。
/frameworks/base/core/java/android/view/ViewRootImpl.java
4519 private void reportDrawFinished(@Nullable Transaction t, int seqId) {
4520 if (DEBUG_BLAST) {
4521 Log.d(mTag, "reportDrawFinished");
4522 }
4523
4524 if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
4525 Trace.instant(Trace.TRACE_TAG_VIEW, "reportDrawFinished " + mTag + " seqId=" + seqId);
4526 }
4527 try {
>>通过Session把transaction从app端发送到server端
4528 mWindowSession.finishDrawing(mWindow, t, seqId);
4529 } catch (RemoteException e) {
4530 Log.e(mTag, "Unable to report draw finished", e);
4531 if (t != null) {
4532 t.apply();
4533 }
4534 } finally {
4535 if (t != null) {
4536 t.clear();
4537 }
4538 }
4539 }
2.WindowStateAnimator
当app端的transaction发送到system_server中后,transaction处理的第一站是WindowStateAnimator.finishDrawingLocked。对应代码流程如下:
ViewRootImpl.reportDrawFinished->Session.finishDrawing->WMS.finishDrawinigWindow->WindowState.finishDrawing->WindowStateAnimator.finishDrawingLocked
在这里将实现server端transaction第一次merge操作,其中postDrawTransaction为app端发来的transaction,syncTransaction为app对应窗口的transaction,通过WindowContainer.getSyncTransaction方法获取。
frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
208 boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
...
218 if (mDrawState == DRAW_PENDING) {
219 ProtoLog.v(WM_DEBUG_DRAW,
220 "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin,
221 mSurfaceController);
222 if (startingWindow) {
223 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin);
224 }
225 mDrawState = COMMIT_DRAW_PENDING;
226 layoutNeeded = true;
227 }
228
229 if (postDrawTransaction != null) {
>>将app侧的transaction给merge到syncTransaction中
230 mWin.getSyncTransaction().merge(postDrawTransaction);
231 layoutNeeded = true;
232 }
233
234 return layoutNeeded;
235 }
WindowState继承了WindowContainer,属于是WindowContainer中的一种,所以最终的逻辑实际上是在WindowContainer中实现。可以看到,若当前处于sync流程,则返回mSyncTransaction;若不处于sync流程中,则返回DisplayContent对应的mPendingTransaction。这里说明一下,每一个WindowContainer都有自身所对应的mPendingTransaction和mSyncTransaction。前面提到的DisplayContent本身也是一种WindowContainer。
以app冷/热启动为例,startingWindow对应的postDrawTransaction最终会merge到startingWindow所对应的mSyncTransaction中,而mainWindow对应的postDrawTransaction最终一般会merge到DisplayContent所对应的mPendingTransaction中。具体可参考前面对于BLASTSyncEngine机制的介绍。
frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
2841 public Transaction getSyncTransaction() {
>>前面两个判断条件都是用于判断当前是否处于sync流程中
>>如果是则直接返回mSyncTransaction
>>如果不是,则通过getPendingTransaction方法去获取对应的mPendingTransaction
2842 if (mSyncTransactionCommitCallbackDepth > 0) {
2843 return mSyncTransaction;
2844 }
2845 if (mSyncState != SYNC_STATE_NONE) {
2846 return mSyncTransaction;
2847 }
2848
>>如果不处于sync流程,则返回通过getPendingTransaction方法获取的transaction
2849 return getPendingTransaction();
2850 }
2852 @Override
2853 public Transaction getPendingTransaction() {
2854 final DisplayContent displayContent = getDisplayContent();
>>一般情况下,这里的if条件都会满足(也很容易理解,毕竟这里的this是WindowState级别、不同于DisplayContent)
>>因此getPendingTransaction方法最终返回的是DisplayContent这种级别的windowContainer所对应的mPendingTransaction
2855 if (displayContent != null && displayContent != this) {
2856 return displayContent.getPendingTransaction();
2857 }
2858 // This WindowContainer has not attached to a display yet or this is a DisplayContent, so we
2859 // let the caller to save the surface operations within the local mPendingTransaction.
2860 // If this is not a DisplayContent, we will merge it to the pending transaction of its
2861 // display once it attaches to it.
2862 return mPendingTransaction;
2863 }
3.BLASTSyncEngine
当WMS中每次刷新时,会检查所有参与sync流程的窗口是否都绘制完成,若是则会触发finishNow流程,相关代码流程如下:
WindowSurfacePlacer.performSurfacePlacement->performSurfacePlacmentLoop->RootWindowContainer.performSurfacePlacement->performSurfacePlacementNoTrace->BLASTSyncEngine.onSurfacePlacement->SyncGroup.tryFinish->finishNow
finishNow流程主要完成:
1)将所有参与sync流程的windowContainer的mSyncTransaction给merge到临时的transaction中(即代码中的merged),这里是WMS中第二次merge;
2)保存当前参与sync流程的windowContainer列表;
3)创建CommitCallback,用于在前面经过merge之后的transaction提交后回调此callback;
4)将merge后的transaction通过回调onTransactionReady传送至Transition中。
frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java
206 private void finishNow() {
...
211 SurfaceControl.Transaction merged = mWm.mTransactionFactory.get();
212 if (mOrphanTransaction != null) {
213 merged.merge(mOrphanTransaction);
214 }
215 for (WindowContainer wc : mRootMembers) {
>>将mRootMembers中的所有windowContainer及其child对应的mSyncTransaction全部merge到merged中
216 wc.finishSync(merged, this, false /* cancel */);
217 }
218
219 final ArraySet<WindowContainer> wcAwaitingCommit = new ArraySet<>();
220 for (WindowContainer wc : mRootMembers) {
>>将mRootMembers中的所有windowContainer及其child保存到wcAwaitingCommit集合中
221 wc.waitForSyncTransactionCommit(wcAwaitingCommit);
222 }
223 class CommitCallback implements Runnable {
...
>>创建CommitCallback
257 CommitCallback callback = new CommitCallback();
>>向transaction注册对应的listener: callback.onCommitted
258 merged.addTransactionCommittedListener(Runnable::run,
259 () -> callback.onCommitted(new SurfaceControl.Transaction()));
>>超时后(BLAST_TIMEOUT_DURATION)会强制执行callback.run方法,进而执行onCommitted方法
260 mHandler.postDelayed(callback, BLAST_TIMEOUT_DURATION);
261
262 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady");
>>将merged发送至Transition中,为后续过渡动画做准备
263 mListener.onTransactionReady(mSyncId, merged);
223 class CommitCallback implements Runnable {
224 // Can run a second time if the action completes after the timeout.
225 boolean ran = false;
>>前面merged在提交到SurfaceFlinger后回调onCommitted方法,通知处理wcAwaitingCommit中所有windowContainer
>>后续的mSyncTransaction
226 public void onCommitted(SurfaceControl.Transaction t) {
227 synchronized (mWm.mGlobalLock) {
228 if (ran) {
229 return;
230 }
231 mHandler.removeCallbacks(this);
232 ran = true;
233 for (WindowContainer wc : wcAwaitingCommit) {
234 wc.onSyncTransactionCommitted(t);
235 }
>>将后续的mSyncTransatcion进行apply,sync流程真正结束
236 t.apply();
237 wcAwaitingCommit.clear();
238 }
239 }
4.Transition
第二次merge之后的transaction传递至Transition之后,主要完成如下(仅从transaction处理的角度出发):
1)通过Transaction.show将startingWindow对应的surface设为可见;
2)分别创建mStartTransaction和mFinishTransaction;
3)将这两个transaction通过回调TransitionPlayer.onTransitionReady传递给wm shell端。
可以看到mStartTransaction就是之前第二次merge后的、从BLASTSyncEngine传递而来的trnsaction,而mFinishTransaction是新创建的,并通过buildFinishTransaction方法设置mFinishTransaction将要做的事情或者将要设置的属性。而这两个transaction的最终处理不在wm core,而在wm shell。
frameworks/base/services/core/java/com/android/server/wm/Transition.java
1409 @Override
1410 public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) {
...
>>将参与sync的窗口对应的surface设为可见
1420 commitVisibleActivities(transaction);
1421 commitVisibleWallpapers();
...
1436 mState = STATE_PLAYING;
>>将由BLASTSyncEngine传来的transaction赋值给mStartTransaction
1437 mStartTransaction = transaction;
>>新创建transaction并赋值给mFinishTransaction
1438 mFinishTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
...
1452 // Resolve the animating targets from the participants.
1453 mTargets = calculateTargets(mParticipants, mChanges);
1454
1455 // Check whether the participants were animated from back navigation.
1456 mController.mAtm.mBackNavigationController.onTransactionReady(this, mTargets);
>>计算transitionInfo
1457 final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, transaction);
...
>>设置mFinishTransaction相关属性值
1565 buildFinishTransaction(mFinishTransaction, info);
1566 mCleanupTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
1567 buildCleanupTransaction(mCleanupTransaction, info);
1568 if (mController.getTransitionPlayer() != null && mIsPlayerEnabled) {
1569 mController.dispatchLegacyAppTransitionStarting(info, mStatusBarTransitionDelay);
1570 try {
1571 ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
1572 "Calling onTransitionReady: %s", info);
1573 mLogger.mSendTimeNs = SystemClock.elapsedRealtimeNanos();
1574 mLogger.mInfo = info;
>>将transaction、mFinishTransaction发送至wm shell
1575 mController.getTransitionPlayer().onTransitionReady(
1576 mToken, info, transaction, mFinishTransaction);
4.1 show
将窗口对应surface设为可见的代码流程如下,主要分为两步:先是将窗口状态由commit_draw_pending逐步切换为ready_to_show、has_drawn,然后再通过Transaction.show方法设置surface为可见,而这里的transaction正是前面的mStartTransaction。
Transition.onTransactionReady->commitVisibleActivities->ActivityRecord.commitFinishDrawing->WindowState.commitFinishDrawing
->1)WindowStateAnimator.commitFinishDrawingLocked(ready_to_show)->WindowState.performShowLocked(has_drawn);
->2)WindowStateAnimator.prepareSurfaceLocked->WindowSurfaceController.showRobustly->Transaction.show
frameworks/base/services/core/java/com/android/server/wm/Transition.java
1721 /** The transition is ready to play. Make the start transaction show the surfaces. */
1722 private void commitVisibleActivities(SurfaceControl.Transaction transaction) {
1723 for (int i = mParticipants.size() - 1; i >= 0; --i) {
1724 final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
1725 if (ar == null || ar.getTask() == null) {
1726 continue;
1727 }
1728 if (ar.isVisibleRequested()) {
1729 ar.commitVisibility(true /* visible */, false /* performLayout */,
1730 true /* fromTransition */);
>>执行activityReocrd对应的commitFinishDrawing方法
>>这里传入的transaction即为前面的mStartTransaction
1731 ar.commitFinishDrawing(transaction);
1732 }
1733 ar.getTask().setDeferTaskAppear(false);
1734 }
1735 }
frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
5683 /** Updates draw state and shows drawn windows. */
5684 void commitFinishDrawing(SurfaceControl.Transaction t) {
5685 boolean committed = false;
5686 for (int i = mChildren.size() - 1; i >= 0; i--) {
>>执行child(WindowState)对应的commitFinishDrawing方法
5687 committed |= mChildren.get(i).commitFinishDrawing(t);
5688 }
5689 if (committed) {
5690 requestUpdateWallpaperIfNeeded();
5691 }
5692 }
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
4344 /** Makes the surface of drawn window (COMMIT_DRAW_PENDING) to be visible. */
4345 boolean commitFinishDrawing(SurfaceControl.Transaction t) {
>>先执行WindowStateAnimator.commitFinishDrawingLocked方法,将窗口状态依次切换为ready_to_show、has_drawn
4346 boolean committed = mWinAnimator.commitFinishDrawingLocked();
4347 if (committed) {
4348 // Ensure that the visibility of buffer layer is set.
>>通过WindowStateAnimator.prepareSurfaceLocked方法设置窗口对应surface可见
4349 mWinAnimator.prepareSurfaceLocked(t);
4350 }
4351 for (int i = mChildren.size() - 1; i >= 0; i--) {
4352 committed |= mChildren.get(i).commitFinishDrawing(t);
4353 }
4354 return committed;
4355 }
frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
237 // This must be called while inside a transaction.
238 boolean commitFinishDrawingLocked() {
239 if (DEBUG_STARTING_WINDOW_VERBOSE &&
240 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
241 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
242 + drawStateToString());
243 }
244 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
245 return false;
246 }
247 ProtoLog.i(WM_DEBUG_ANIM, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW %s",
248 mSurfaceController);
>>设置窗口状态为READY_TO_SHOW
249 mDrawState = READY_TO_SHOW;
250 boolean result = false;
251 final ActivityRecord activity = mWin.mActivityRecord;
252 if (activity == null || activity.canShowWindows()
253 || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
>>在WindowState.performShowLocked方法中设置窗口状态为has_drawn
254 result = mWin.performShowLocked();
255 }
256 return result;
257 }
411 void prepareSurfaceLocked(SurfaceControl.Transaction t) {
...
439 } else if (mLastAlpha != mShownAlpha
440 || mLastHidden) {
441 mLastAlpha = mShownAlpha;
442 ProtoLog.i(WM_SHOW_TRANSACTIONS,
443 "SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s",
444 mSurfaceController, mShownAlpha, w.mHScale, w.mVScale, w);
445
446 boolean prepared =
447 mSurfaceController.prepareToShowInTransaction(t, mShownAlpha);
448
449 if (prepared && mDrawState == HAS_DRAWN) {
450 if (mLastHidden) {
>>在窗口状态切换为has_drawn后通过WindowSurfaceController.showRobustly方法设置对应surface可见
451 mSurfaceController.showRobustly(t);
452 mLastHidden = false;
4.2 buildFinishTransaction
先是初始化了mFinishTransaction,然后再通过buildFinishTransaction方法设置mFinishTransaction的相关属性或者对surface的相关操作,比如设置父节点、layer等。
frameworks/base/services/core/java/com/android/server/wm/Transition.java
877 private void buildFinishTransaction(SurfaceControl.Transaction t, TransitionInfo info) {
878 final Point tmpPos = new Point();
879 // usually only size 1
880 final ArraySet<DisplayContent> displays = new ArraySet<>();
881 for (int i = mTargets.size() - 1; i >= 0; --i) {
882 final WindowContainer target = mTargets.get(i).mContainer;
883 if (target.getParent() != null) {
884 final SurfaceControl targetLeash = getLeashSurface(target, null /* t */);
885 final SurfaceControl origParent = getOrigParentSurface(target);
886 // Ensure surfaceControls are re-parented back into the hierarchy.
>>过渡动画结束后,将过渡动画对象的父节点由leash图层重置为原始的父节点
887 t.reparent(targetLeash, origParent);
888 t.setLayer(targetLeash, target.getLastLayer());
...
930 for (int i = 0; i < info.getRootCount(); ++i) {
>>过渡动画结束后,销毁对应leash图层
931 t.reparent(info.getRoot(i).getLeash(), null);
932 }
5.Transitions
通过调用执行TransitionPlayerImpl.onTransitionReady, wm core会通过binder通信将transaction等信息从system_server进程传递到wm shell端(SystemUI进程),为shell端后续执行过渡动画做准备。
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
1347 @BinderThread
1348 private class TransitionPlayerImpl extends ITransitionPlayer.Stub {
1349 @Override
1350 public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo,
1351 SurfaceControl.Transaction t, SurfaceControl.Transaction finishT)
1352 throws RemoteException {
>>切换线程执行后续任务
1353 mMainExecutor.execute(() -> Transitions.this.onTransitionReady(
1354 iBinder, transitionInfo, t, finishT));
1355 }
645 void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
646 @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
...
657 // Move from pending to ready
>>将server端传来的mStartTransaction、mFinishTransaction、transitionInfo赋值给ActiveTransition
658 final ActiveTransition active = mPendingTransitions.remove(activeIdx);
659 active.mInfo = info;
660 active.mStartT = t;
661 active.mFinishT = finishT;
662 if (activeIdx > 0) {
663 Log.i(TAG, "Transition might be ready out-of-order " + activeIdx + " for " + active
664 + ". This is ok if it's on a different track.");
665 }
666 if (!mReadyDuringSync.isEmpty()) {
667 mReadyDuringSync.add(active);
668 } else {
>>根据active,执行过渡动画后续流程
669 dispatchReady(active);
670 }
671 }
然后,通过如下代码流程,最终通过playTransition方法去确认执行动画发handler。
Transitions.onTransitionReady->dispatchReady->processReadyQueue->playTransition->dispatchTransition
873 private void playTransition(@NonNull ActiveTransition active) {
874 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Playing animation for %s", active);
875 for (int i = 0; i < mObservers.size(); ++i) {
876 mObservers.get(i).onTransitionStarting(active.mToken);
877 }
878
879 setupAnimHierarchy(active.mInfo, active.mStartT, active.mFinishT);
880
881 // If a handler already chose to run this animation, try delegating to it first.
>>如果ActiveTransition中的handler已经指定,则直接执行对应的startAnimation方法开始执行过渡动画
882 if (active.mHandler != null) {
883 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try firstHandler %s",
884 active.mHandler);
885 boolean consumed = active.mHandler.startAnimation(active.mToken, active.mInfo,
886 active.mStartT, active.mFinishT, (wct, cb) -> onFinish(active, wct, cb));
887 if (consumed) {
888 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by firstHandler");
889 mTracer.logDispatched(active.mInfo.getDebugId(), active.mHandler);
890 return;
891 }
892 }
>>否则,则遍历确认适合执行动画的handler
893 // Otherwise give every other handler a chance
894 active.mHandler = dispatchTransition(active.mToken, active.mInfo, active.mStartT,
895 active.mFinishT, (wct, cb) -> onFinish(active, wct, cb), active.mHandler);
896 }
902 TransitionHandler dispatchTransition(@NonNull IBinder transition, @NonNull TransitionInfo info,
903 @NonNull SurfaceControl.Transaction startT, @NonNull SurfaceControl.Transaction finishT,
904 @NonNull TransitionFinishCallback finishCB, @Nullable TransitionHandler skip) {
905 for (int i = mHandlers.size() - 1; i >= 0; --i) {
906 if (mHandlers.get(i) == skip) continue;
>>遍历mHandlers中的所有handler,只要有一个执行了,便不再继续遍历后面的handler
907 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try handler %s",
908 mHandlers.get(i));
>>执行对应handler对应的startAnimation方法
909 boolean consumed = mHandlers.get(i).startAnimation(transition, info, startT, finishT,
910 finishCB);
911 if (consumed) {
912 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by %s",
913 mHandlers.get(i));
914 mTracer.logDispatched(info.getDebugId(), mHandlers.get(i));
915 return mHandlers.get(i);
916 }
917 }
6.DefaultTransitionHandler
执行不同类型的动画时会有对应的handler去执行动画,比如执行keyguard相关动画时,会由KeyguardTransitionHandler执行;执行recent相关动画时,会由RecentsTransitionHandler去执行。而对于一般的activity/task切换的过渡动画,一般会由DefaultTransitionHandler来执行对应过渡动画。
这里以app冷/热启动场景为例,在执行startAnimation方法时,也就是过渡动画开始前,便会执行startTransaction的apply,这里的startTransaction包含了前面设置窗口对应surface可见的信息,因此窗口对应layer将在SurfaceFlinger中设为可见。
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
292 @Override
293 public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
294 @NonNull SurfaceControl.Transaction startTransaction,
295 @NonNull SurfaceControl.Transaction finishTransaction,
296 @NonNull Transitions.TransitionFinishCallback finishCallback) {
297 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
298 "start default transition animation, info = %s", info);
...
>>对startTransaction执行apply,此时窗口对应layer将变为可见
533 startTransaction.apply();
534
535 // now start animations. they are started on another thread, so we have to post them
536 // *after* applying the startTransaction
537 mAnimExecutor.execute(() -> {
538 for (int i = 0; i < animations.size(); ++i) {
539 animations.get(i).start();
540 }
541 });
动画结束后,将回调onFinish方法,做动画结束后的收尾工作,其中最重要的便是对finishTransaction的apply。
783 private void onFinish() {
784 if (mFinished) return;
785 mFinished = true;
>>执行finisher
786 finisher.run();
736 /** Builds an animator for the surface and adds it to the `animations` list. */
737 static void buildSurfaceAnimation(@NonNull ArrayList<Animator> animations,
...
757 final Runnable finisher = () -> {
758 applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix,
759 position, cornerRadius, clipRect);
760
761 pool.release(transaction);
762 mainExecutor.execute(() -> {
763 animations.remove(va);
>>回调finishCallback
764 finishCallback.run();
765 });
766 };
而DefaultTransitionHandler中的finishCallback正是Transitions.onFinish,在这里执行finishTransaction的apply。
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
971 private void onFinish(ActiveTransition active,
972 @Nullable WindowContainerTransaction wct,
973 @Nullable WindowContainerTransactionCallback wctCB) {
974 final Track track = mTracks.get(active.getTrack());
...
986 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition animation finished "
987 + "(aborted=%b), notifying core %s", active.mAborted, active);
...
993 // Merge all associated transactions together
>>将finishTransaction赋值给fullFinish
994 SurfaceControl.Transaction fullFinish = active.mFinishT;
...
1016 if (fullFinish != null) {
>>执行fullFinish的apply,实现相关windowContainer对应父节点的重置,即恢复为动画前的夫节点,动画中的父节点为leash图层
1017 fullFinish.apply();
1018 }
动画执行过程中,每一帧的更新将由applyTransformation来实现,每一帧对应的alpha、matrix等信息将在这里更新。
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
915 private static void applyTransformation(long time, SurfaceControl.Transaction t,
916 SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix,
917 Point position, float cornerRadius, @Nullable Rect immutableClipRect) {
918 tmpTransformation.clear();
919 anim.getTransformation(time, tmpTransformation);
...
923 t.setMatrix(leash, tmpTransformation.getMatrix(), matrix);
924 t.setAlpha(leash, tmpTransformation.getAlpha());
...
940 t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
941 t.apply();
7. sync流程结束后的transaction处理流程
在app冷/热启动过程中,当mainWindow绘制完成时,sync流程一般已经结束了,此时mainWindow对应的transaction会被merge到displayContent对应的mPendingTransaction中。前面提到的transaction流程适用于所有实际参与sync流程的windowContainer,而这里的流程适用于所有不实际参与sync流程的windowContainer。
frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
208 boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
...
218 if (mDrawState == DRAW_PENDING) {
219 ProtoLog.v(WM_DEBUG_DRAW,
220 "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin,
221 mSurfaceController);
222 if (startingWindow) {
223 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin);
224 }
225 mDrawState = COMMIT_DRAW_PENDING;
226 layoutNeeded = true;
227 }
228
229 if (postDrawTransaction != null) {
>>将app侧的transaction给merge到displayContent对应的mPendingTransaction中
230 mWin.getSyncTransaction().merge(postDrawTransaction);
231 layoutNeeded = true;
232 }
233
234 return layoutNeeded;
235 }
在WMS中刷新时会执行整个窗口树的prepareSurfaces流程。到displayContent这一层级时,会把包含了mainWindow对应的transaction的mPendingTransaction再次merge到globalTransaction中,这是mainWindow对应的transaction在WMS中的第二次merge。
/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
5491 @Override
5492 void prepareSurfaces() {
5493 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces");
5494 try {
5495 final Transaction transaction = getPendingTransaction();
5496 super.prepareSurfaces();
5497
5498 // TODO: Once we totally eliminate global transaction we will pass transaction in here
5499 // rather than merging to global.
>>将displayContent对应的mPendingTransaction给merge到globalTransaction中
5500 SurfaceControl.mergeToGlobalTransaction(transaction);
5501 } finally {
5502 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
5503 }
5504 }
当设置mainWindow对应surface可见时,此时对应的transaction是displayContent对应的mPendiingTransaction。
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
5198 @Override
5199 void prepareSurfaces() {
5200 mIsDimming = false;
5201 if (mHasSurface) {
5202 applyDims();
5203 updateSurfacePositionNonOrganized();
5204 // Send information to SurfaceFlinger about the priority of the current window.
5205 updateFrameRateSelectionPriorityIfNeeded();
5206 updateScaleIfNeeded();
>>此时getSyncTransaction方法返回的是displayContent对应的mPendingTransaction
5207 mWinAnimator.prepareSurfaceLocked(getSyncTransaction());
5208 }
5209 super.prepareSurfaces();
5210 }
frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
411 void prepareSurfaceLocked(SurfaceControl.Transaction t) {
412 final WindowState w = mWin;
...
439 } else if (mLastAlpha != mShownAlpha
440 || mLastHidden) {
441 mLastAlpha = mShownAlpha;
442 ProtoLog.i(WM_SHOW_TRANSACTIONS,
443 "SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s",
444 mSurfaceController, mShownAlpha, w.mHScale, w.mVScale, w);
445
446 boolean prepared =
447 mSurfaceController.prepareToShowInTransaction(t, mShownAlpha);
448
449 if (prepared && mDrawState == HAS_DRAWN) {
450 if (mLastHidden) {
>>这里的showRobustly方法传入的参数正是displayContent.mPendingTransaction
>>如果是startingWindow,这里的transaction就是在BLASTSyncEngine中将相关windowContainer的mSyncTransaction进行merge之后的transaction
451 mSurfaceController.showRobustly(t);
452 mLastHidden = false;
WMS中的核心刷新逻辑为如下代码,即WMS先开启openSurfaceTransaction,然后提交更新所有surface信息,最终再关闭closeSurfaceTransaction。
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
764 void performSurfacePlacementNoTrace() {
...
792 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
793 mWmService.openSurfaceTransaction();
794 try {
795 applySurfaceChangesTransaction();
796 } catch (RuntimeException e) {
797 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
798 } finally {
799 mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
在WMS中所有surface更新完毕后,将会对globalTransaction进行最终的apply,此时包含设置mainWindow对应surface可见的信息就包含在globalTransaction中,这一次apply之后,一般很快SurfaceFlinger会设置mainWindow对应layer为可见状态。
WindowManagerService.closeSurfaceTransaction->SurfaceControl.closeTransaction->GlobalTransactionWrapper.applyGlobalTransaction->SurfaceControl.nativeApplyTransaction
4273 private static class GlobalTransactionWrapper extends SurfaceControl.Transaction {
4274 void applyGlobalTransaction(boolean sync) {
4275 applyResizedSurfaces();
4276 notifyReparentedSurfaces();
>>对globalTransaction进行apply,从而将surface信息更新至SurfaceFlinger
4277 nativeApplyTransaction(mNativeObject, sync);
4278 }