WMS中BLASTSyncEngine机制与Transaction处理流程

一、简介

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          }

  • 19
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值