WindowManagerService(WMS)窗口显示流程分析之完成窗口绘制

266 阅读22分钟

在上篇文章中分析了窗口显示逻辑中的布局窗口, 执行 relayoutWindow 后 View 就可以绘制了,绘制完成后就要通知 SurfaceFlinger 进行合成了。
本文以android 13代码为例进行分析。

1,在frameworks/base/core/java/android/view/ViewRootImpl.java中

private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
	private void performTraversals() {
	    // cache mView since it is used so much below...
	    final View host = mView; // 获取根视图(mView)并存储在局部变量host中
		
		// 调用relayoutWindow方法,传入参数、视图可见性和是否需要处理insets(内部空间),返回重新布局的结果。
	    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); //内部会将经过WMS计算后的窗口尺寸给mWinFrame,经过relayoutWindow 后就 View 就可以绘制了
		
		int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width,lp.privateFlags);
		int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height,lp.privateFlags);
		
		// 调用performMeasure方法,根据新的测量规格(childWidthMeasureSpec和childHeightMeasureSpec)来测量视图的大小。
		performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); 
		
		layoutRequested = true;
		final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
		
		if (didLayout) { // 如果请求了布局(layoutRequested为true)且视图没有被停止(mStopped为false)或报告下一个绘制(mReportNextDraw为true),则执行布局(performLayout)
			//调用performLayout函数
	        performLayout(lp, mWidth, mHeight); 
		}
		
		boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw();
		if (!cancelAndRedraw) {
		    createSyncIfNeeded(); //设置了回调,等时机到了就会触发执行,而这个时机就是 View 绘制完成后,在 markSyncReady 触发,开始finish drawing流程
		}

		// 调用performDraw()尝试绘制,如果绘制失败且存在同步回调,则调用回调。
	    if (!performDraw() && mSyncBufferCallback != null) {
	        mSyncBufferCallback.onBufferReady(null);
	    }
		
		if (!cancelAndRedraw) {
		    mReportNextDraw = false;
		    mSyncBufferCallback = null;
		    mSyncBuffer = false;
		    if (isInLocalSync()) {
		        mSurfaceSyncer.markSyncReady(mSyncId); //触发绘制完成回调,markSyncReady 方法,最终会触发 ViewRootImpl::createSyncIfNeeded 方法下的 ViewRootImpl::reportDrawFinished 来真正 finishDrawingWindow 流程。
		        mSyncId = UNSET_SYNC_ID;
		    }
		}
	
	}

在 performTraversals 函数中分别执行了 relayoutWindow,performMeasure,performLayout,performDraw 等函数。并执行 markSyncReady 函数触发 createSyncIfNeeded 函数执行完成绘制。
从上面的代码可以看到 relayoutWindow 方法执行后,会触发View的三个绘制的方法,也就是常说的 View 绘制三部曲,其中 createSyncIfNeeded 方法是触发 finishDrawingWindow 的,但是这个方法在 performDraw 的上面。 这是因为代码的顺序不代表真正的执行顺序,这里的 createSyncIfNeeded 只是设置了回调,等时机到了就会触发执行,而这个时机就是 View 绘制完成后,在 markSyncReady 触发。也就是在 markSyncReady 触发,进而在 createSyncIfNeeded 执行。
在方法 createSyncIfNeeded 中通过 ViewRootImpl::reportDrawFinished 执行 finishDrawingWindow 流程。
首先看下 ViewRootImpl::createSyncIfNeeded 函数。

private int mSyncId = UNSET_SYNC_ID;
private final Transaction mSurfaceChangedTransaction = new Transaction(); // 其中 Transaction 是定义在类 SurfaceControl 中的静态内部类,即 public static class Transaction implements Closeable, Parcelable {...}

private void createSyncIfNeeded() {
    // Started a sync already or there's nothing needing to sync
    if (isInLocalSync() || !mReportNextDraw) {
        return;
    }

    final int seqId = mSyncSeqId; // 获取当前同步序列号
	
    mSyncId = mSurfaceSyncer.setupSync(transaction -> {
        // Callback will be invoked on executor thread so post to main thread.
        mHandler.postAtFrontOfQueue(() -> {
            mSurfaceChangedTransaction.merge(transaction);
		  // 调用reportDrawFinished
            reportDrawFinished(seqId);   
        });
    });
    if (DEBUG_BLAST) {
        Log.d(mTag, "Setup new sync id=" + mSyncId);
    }
    mSurfaceSyncer.addToSync(mSyncId, mSyncTarget);
    notifySurfaceSyncStarted();
}

上面的代码调用了 SurfaceSyncer 类的 setupSync、addToSync、reportDrawFinished 等函数。 在执行 addToSync 函数时,第二个参数是 mSyncTarget。

public final SurfaceSyncer.SyncTarget mSyncTarget = new SurfaceSyncer.SyncTarget() {
    @Override
    public void onReadyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
        readyToSync(syncBufferCallback);
    }

    @Override
    public void onSyncComplete() {
	   // 使用 mHandler.postAtFrontOfQueue 方法将一个 Runnable 对象添加到消息队列的前端。
        mHandler.postAtFrontOfQueue(() -> {
            if (--mNumSyncsInProgress == 0 && mAttachInfo.mThreadedRenderer != null) {
                HardwareRenderer.setRtAnimationsEnabled(true);
            }
        });
    }
};

上面的代码定义了一个名为 mSyncTarget 的成员变量,它是 SurfaceSyncer.SyncTarget 的一个匿名内部类的实例。
SyncTarget 是定义在 SurfaceSyncer类中的一个接口,即

public interface SyncTarget { 
    void onReadyToSync(SyncBufferCallback syncBufferCallback);
    default void onSyncComplete() {}
}

下面首先分析下 SurfaceSyncer 类的 setupSync 函数。

2,在frameworks/base/core/java/android/window/SurfaceSyncer中

private int mIdCounter = 0;
private final SparseArray<SyncSet> mSyncSets = new SparseArray<>();

public int setupSync(@NonNull Consumer<Transaction> syncRequestComplete) {
    synchronized (mSyncSetLock) {
        final int syncId = mIdCounter++; // mIdCounter用于生成唯一的同步操作ID。
        if (DEBUG) {
            Log.d(TAG, "setupSync " + syncId);
        }
		 // 创建了一个SyncSet对象,构造函数的第一个参数是同步操作的ID,第二个参数是一个lambda表达式,用于定义当同步操作完成时应该执行的操作。
        SyncSet syncSet = new SyncSet(syncId, transaction -> {
            synchronized (mSyncSetLock) {
                mSyncSets.remove(syncId); // 从mSyncSets集合中移除与syncId对应的syncSet对象。
            }
		  // 调用syncRequestComplete的accept方法,将transaction作为参数传递。这通常意味着通知调用者同步操作已完成,并传递相关的transaction对象。
            syncRequestComplete.accept(transaction);
        });
		 // 将新创建的syncSet对象添加到mSyncSets集合中,以syncId为键。
        mSyncSets.put(syncId, syncSet);
        return syncId;
    }
}

上面的代码中通过 new SyncSet 创建了 SyncSet 对象,SyncSet类是定义在 SurfaceSyncer 类中的静态类。

private static class SyncSet {
    private final Object mLock = new Object();
	private final int mSyncId;
	private Consumer<Transaction> mSyncRequestCompleteCallback;
	private final Transaction mTransaction = sTransactionFactory.get();
	private boolean mSyncReady;
	private final Set<SyncTarget> mSyncTargets = new ArraySet<>();
	
	private SyncSet(int syncId, Consumer<Transaction> syncRequestComplete) {
        mSyncId = syncId;
        mSyncRequestCompleteCallback = syncRequestComplete;
    }
}

上面的代码中创建的 syncSet 对象加入到了 mSyncSets 集合中,在调用 mSurfaceSyncer.markSyncReady(mSyncId) 时会用到。

public void markSyncReady(int syncId) {
    SyncSet syncSet;
    synchronized (mSyncSetLock) {
        syncSet = mSyncSets.get(syncId);
    }
    if (syncSet == null) {
        Log.e(TAG, "Failed to find syncSet for syncId=" + syncId);
        return;
    }
    syncSet.markSyncReady();
}

上面的代码调用SyncSet类的 markSyncReady 函数,该 markSyncReady 函数定义在 静态内部类 SyncSet 中。

void markSyncReady() {
    synchronized (mLock) {
        mSyncReady = true;
        checkIfSyncIsComplete();
    }
}

上面的函数调用 checkIfSyncIsComplete 函数。

private Consumer<Transaction> mSyncRequestCompleteCallback;
@GuardedBy("mLock")
private void checkIfSyncIsComplete() {
    if (!mSyncReady || !mPendingSyncs.isEmpty() || !mMergedSyncSets.isEmpty()) {
        if (DEBUG) {
            Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady
                    + " mPendingSyncs=" + mPendingSyncs.size() + " mergedSyncs="
                    + mMergedSyncSets.size());
        }
        return;
    }

    if (DEBUG) {
        Log.d(TAG, "Successfully finished sync id=" + mSyncId);
    }

	 // 遍历 mSyncTargets(同步目标列表),对每个同步目标调用 onSyncComplete 方法,通知它们同步已完成。
    for (SyncTarget syncTarget : mSyncTargets) {
        syncTarget.onSyncComplete();
    }
    mSyncTargets.clear();
	 // 调用 mSyncRequestCompleteCallback 回调,传入 mTransaction 参数,通知外部同步请求已完成。
    mSyncRequestCompleteCallback.accept(mTransaction);
    mFinished = true;
}

上面分析了 setupSync 函数,下面接着分析下 SurfaceSyncer 类的 addToSync 函数。

public boolean addToSync(int syncId, SurfaceView surfaceView,
        Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) { // Consumer 是一个函数式接口,这里它用于接收一个 SurfaceViewFrameCallback 类型的回调
    return addToSync(syncId, new SurfaceViewSyncTarget(surfaceView, frameCallbackConsumer));
}

上面代码中的 SurfaceViewSyncTarget 是一个定义在 SurfaceSyncer 类中的静态内部类,它实现 SyncTarget 接口。即如下代码:

private static class SurfaceViewSyncTarget implements SyncTarget {
    private final SurfaceView mSurfaceView;
    private final Consumer<SurfaceViewFrameCallback> mFrameCallbackConsumer;

    SurfaceViewSyncTarget(SurfaceView surfaceView,
            Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
        mSurfaceView = surfaceView;
        mFrameCallbackConsumer = frameCallbackConsumer;
    }

    @Override
    public void onReadyToSync(SyncBufferCallback syncBufferCallback) {
        mFrameCallbackConsumer.accept(
                () -> mSurfaceView.syncNextFrame(syncBufferCallback::onBufferReady));
    }
}

接着继续看 addToSync 函数。

public boolean addToSync(int syncId, @NonNull View view) {
    ViewRootImpl viewRoot = view.getViewRootImpl();
    if (viewRoot == null) {
        return false;
    }
    return addToSync(syncId, viewRoot.mSyncTarget);
}

public boolean addToSync(int syncId, @NonNull SyncTarget syncTarget) {
	 // 调用 getAndValidateSyncSet(syncId) 方法来获取与 syncId 相关联的 SyncSet 对象
    SyncSet syncSet = getAndValidateSyncSet(syncId);
    if (syncSet == null) {
        return false;
    }
    if (DEBUG) {
        Log.d(TAG, "addToSync id=" + syncId);
    }
	 // 将 syncTarget 添加到 syncSet 中。这个方法返回一个布尔值,表示添加操作是否成功。
    return syncSet.addSyncableSurface(syncTarget);
}

上面的函数调用了 addSyncableSurface 函数,在SurfaceSyncer类中的静态类 SyncSet 中

boolean addSyncableSurface(SyncTarget syncTarget) {
    SyncBufferCallback syncBufferCallback = new SyncBufferCallback() {
        @Override
        public void onBufferReady(Transaction t) {
            synchronized (mLock) {
                if (t != null) {
                    mTransaction.merge(t);
                }
                mPendingSyncs.remove(hashCode());
                checkIfSyncIsComplete();
            }
        }
    };

    synchronized (mLock) {
        if (mSyncReady) {
            Log.e(TAG, "Sync " + mSyncId + " was already marked as ready. No more "
                    + "SyncTargets can be added.");
            return false;
        }
        mPendingSyncs.add(syncBufferCallback.hashCode());
        mSyncTargets.add(syncTarget);
    }
    syncTarget.onReadyToSync(syncBufferCallback);
    return true;
}

分析完上面的 setupSync 和 addToSync 函数,接着分析下 reportDrawFinished 函数。

3,在frameworks/base/core/java/android/view/ViewRootImpl中

final IWindowSession mWindowSession; // 其初始化是在ViewRootImpl的构造函数中由传入的参数进行赋值
final W mWindow; // 在ViewRootImpl的构造函数中进行初始化,即 mWindow = new W(this);

private void reportDrawFinished(int seqId) {
    if (DEBUG_BLAST) {
        Log.d(mTag, "reportDrawFinished " + Debug.getCallers(5));
    }

    try {
        mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction, seqId); // 调用finishDrawing
    } catch (RemoteException e) {
        Log.e(mTag, "Unable to report draw finished", e);
        mSurfaceChangedTransaction.apply();
    } finally {
        mSurfaceChangedTransaction.clear();
    }
}

上面的代码通过 IWindowSession 对象 mWindowSession 调用 finishDrawing 函数, 其中Session类继承自IWindowSession.Stub,代码会走到Session.java中的 finishDrawing 函数。

4,在frameworks/base/services/core/java/com/android/server/wm/Session.java中

class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    final WindowManagerService mService;
    final IWindowSessionCallback mCallback;
	SurfaceSession mSurfaceSession;
	
	@Override
    public void finishDrawing(IWindow window,
            @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
        if (DEBUG) Slog.v(TAG_WM, "IWindow finishDrawing called for " + window);
        mService.finishDrawingWindow(this, window, postDrawTransaction, seqId);
    }
}

上面的代码调用WMS的 finishDrawingWindow 函数。

5,在frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java中

final WindowSurfacePlacer mWindowPlacerLocked; //在WMS的构造函数中进行初始化,即 mWindowPlacerLocked = new WindowSurfacePlacer(this);

void finishDrawingWindow(Session session, IWindow client,
        @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
    if (postDrawTransaction != null) {
        postDrawTransaction.sanitize(); // sanitize方法通常用于校验和准备事务,确保事务在提交前处于有效状态。
    }

    final long origId = Binder.clearCallingIdentity();// 调用Binder.clearCallingIdentity()来清除当前线程的调用者身份。这是在执行可能涉及安全敏感操作的代码前的一种常见做法,目的是防止调用者利用特权访问敏感资源。
    try {
        synchronized (mGlobalLock) {
            WindowState win = windowForClientLocked(session, client, false); // 调用windowForClientLocked方法,根据session和client参数获取对应的WindowState对象
            ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s",
                    win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));
			  // 调用WindowState类的 finishDrawing 函数。
            if (win != null && win.finishDrawing(postDrawTransaction, seqId)) { // 如果找到了对应的WindowState对象(win不为null),并且win.finishDrawing方法返回true(表示绘制成功完成)
                if (win.hasWallpaper()) { // 如果该窗口有壁纸(win.hasWallpaper()返回true),则更新其显示内容的待处理布局变化标志,以包括重新绘制壁纸的需求
                    win.getDisplayContent().pendingLayoutChanges |=
                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                }
                win.setDisplayLayoutNeeded(); // 调用setDisplayLayoutNeeded方法标记窗口的布局需要重新计算,最终会走到 DisplayContent.java类中的 setLayoutNeeded 函数,设置 mLayoutNeeded = true;
		     // 触发layout
                mWindowPlacerLocked.requestTraversal(); // 调用mWindowPlacerLocked.requestTraversal方法请求重新遍历窗口树,以应用任何必要的布局或绘制更新
            }
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
}

上面的 WindowManagerService::finishDrawingWindow 函数主要内容是:
通过 WindowState::finishDrawing 将 Surface 状态设置为 COMMIT_DRAW_PENDING;
并通过 WindowSurfacePlacer::requestTraversal 框架层的 layout ,将状态设置为 READY_TO_SHOW ,HAS_DRAWN ,然后通知到 SurfaceFlinger。
在上面的函数代码中,分别调用了 windowForClientLocked、finishDrawing、requestTraversal等函数。
首先看下 windowForClientLocked 函数。

final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) {
    return windowForClientLocked(session, client.asBinder(), throwOnError);
}

final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
    WindowState win = mWindowMap.get(client);
    if (DEBUG) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
    if (win == null) {
        if (throwOnError) {
            throw new IllegalArgumentException(
                    "Requested window " + client + " does not exist");
        }
        ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
                Debug.getCallers(3));
        return null;
    }
    if (session != null && win.mSession != session) {
        if (throwOnError) {
            throw new IllegalArgumentException("Requested window " + client + " is in session "
                    + win.mSession + ", not " + session);
        }
        ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
                Debug.getCallers(3));
        return null;
    }

    return win;
}

上面函数返回一个 WindowState 类型的对象。
下面看下WindowState类的 finishDrawing 函数。

6,在frameworks/base/services/core/java/com/android/server/wm/WindowState.java中

final WindowStateAnimator mWinAnimator; //在WindowState的构造函数中通过 mWinAnimator = new WindowStateAnimator(this);进行初始化。

boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
	...
	final boolean layoutNeeded =
            mWinAnimator.finishDrawingLocked(postDrawTransaction, mClientWasDrawingForSync); // 调用finishDrawingLocked函数
	...
}

上面的函数调用 WindowStateAnimator 类的 finishDrawingLocked 函数。

7,在frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java中

boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction,
        boolean forceApplyNow) {
	 // 初始化一个布尔变量startingWindow,用于判断当前窗口是否为应用启动窗口(TYPE_APPLICATION_STARTING)。
    final boolean startingWindow =
            mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
    if (startingWindow) {
        ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finishing drawing window %s: mDrawState=%s",
                mWin, drawStateToString());
    }

    boolean layoutNeeded = false; // 声明一个布尔变量layoutNeeded,初始化为false,用于标记是否需要布局更新。

	 // 如果当前绘制状态(mDrawState)为DRAW_PENDING,则记录日志,并更新绘制状态为COMMIT_DRAW_PENDING,同时设置layoutNeeded为true,表示需要布局更新。
    if (mDrawState == DRAW_PENDING) {
        ProtoLog.v(WM_DEBUG_DRAW,
                "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin,
                mSurfaceController);
        if (startingWindow) {
            ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin);
        }
        mDrawState = COMMIT_DRAW_PENDING;
        layoutNeeded = true;
    }

    if (postDrawTransaction != null) {
        // If there is no surface, the last draw was for the previous surface. We don't want to
        // wait until the new surface is shown and instead just apply the transaction right
        // away.
        if (mLastHidden && mDrawState != NO_SURFACE && !forceApplyNow) {
            mPostDrawTransaction.merge(postDrawTransaction);
        } else {
            mWin.getSyncTransaction().merge(postDrawTransaction);
        }
        layoutNeeded = true;
    }

    return layoutNeeded;
}

上面的代码将 Surface 状态设置为 COMMIT_DRAW_PENDING,下一个状态是 READY_TO_SHOW,下面分析下 WindowSurfacePlacer::requestTraversal 函数。

8,在frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java中

class WindowSurfacePlacer {
	private final WindowManagerService mService; //在 WindowSurfacePlacer 构造函数中通过参数进行初始化
	private boolean mTraversalScheduled;

	void requestTraversal() {
        if (mTraversalScheduled) {
            return;
        }
    
        // Set as scheduled even the request will be deferred because mDeferredRequests is also
        // increased, then the end of deferring will perform the request.
        mTraversalScheduled = true;
        if (mDeferDepth > 0) {
            mDeferredRequests++;
            if (DEBUG) Slog.i(TAG, "Defer requestTraversal " + Debug.getCallers(3));
            return;
        }
        mService.mAnimationHandler.post(mPerformSurfacePlacement); // 通过Handler触发
    }
	
}

在上面的代码中,变量 mPerformSurfacePlacement 是一个 Runnable,其定义如下:

private class Traverser implements Runnable {
    @Override
    public void run() {
        synchronized (mService.mGlobalLock) {
            performSurfacePlacement();
        }
    }
}

private final Traverser mPerformSurfacePlacement = new Traverser();

在上面Runnable中,运行时调用 performSurfacePlacement 函数。

final void performSurfacePlacement() {
    performSurfacePlacement(false /* force */);
}

final void performSurfacePlacement(boolean force) {
    if (mDeferDepth > 0 && !force) {
        mDeferredRequests++;
        return;
    }
    int loopCount = 6; // // 最大次数循环为6次
    do {
        mTraversalScheduled = false;
        performSurfacePlacementLoop(); // 调用 performSurfacePlacementLoop 函数
        mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
        loopCount--;
    } while (mTraversalScheduled && loopCount > 0);
    mService.mRoot.mWallpaperActionPending = false;
}

上面的代码调用 performSurfacePlacementLoop 函数。

private void performSurfacePlacementLoop() {
    if (mInLayout) {
        if (DEBUG) {
            throw new RuntimeException("Recursive call!");
        }
        Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
                + Debug.getCallers(3));
        return;
    }
	mInLayout = true;
	try {
    	 // 执行 RootWindowContainer::performSurfacePlacement 这个代表对屏幕进行一次 layout
    	 //在WMS中有 RootWindowContainer mRoot; // The root of the device window hierarchy.
        mService.mRoot.performSurfacePlacement(); // 对所有窗口执行布局操作
    
        mInLayout = false; // 布局完成
    
        if (mService.mRoot.isLayoutNeeded()) {
            if (++mLayoutRepeatCount < 6) {
                requestTraversal();
            } else {
                Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
                mLayoutRepeatCount = 0;
            }
        } else {
            mLayoutRepeatCount = 0;
        }
    
        if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
            mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
            mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
        }
    } catch (RuntimeException e) {
        mInLayout = false;
        Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
    }
}

上面的代码调用 RootWindowContainer类的 performSurfacePlacement 函数。

9,在frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java中

void performSurfacePlacement() {
    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
    try {
        performSurfacePlacementNoTrace();
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}

上面的代码调用了 performSurfacePlacementNoTrace 这个重要方法。

void performSurfacePlacementNoTrace() {
	...
	Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
    // 开启事务
    mWmService.openSurfaceTransaction();
    try {
    	 // 处理事务(执行窗口尺寸计算,surface状态变更等操作)
        applySurfaceChangesTransaction();
    } catch (RuntimeException e) {
        Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
    } finally {
    	 // 关闭事务,做事务提交
        mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        if (SHOW_LIGHT_TRANSACTIONS) {
            Slog.i(TAG,
                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
        }
    }
	...
	checkAppTransitionReady(surfacePlacer); // Activity 切换事务处理,条件满足也会将窗口状态设置为HAS_DRAW 流程
	...
}

上面的代码中分别调用了 openSurfaceTransaction、applySurfaceChangesTransaction、closeSurfaceTransaction、checkAppTransitionReady等函数。
上面的代码中 mWmService 变量定义在 WindowContainer.java中并在构造函数中初始化,即 protected final WindowManagerService mWmService;
另外由于 RootWindowContainer 继承自 WindowContainer,即 class RootWindowContainer extends WindowContainer implements DisplayManager.DisplayListener 所以对于 openSurfaceTransaction 和 closeSurfaceTransaction 会走到WMS类文件中。

void openSurfaceTransaction() {
    try {
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
        SurfaceControl.openTransaction();
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}

上面的代码分别调用 SurfaceControl 类的函数 openTransaction。

10,在frameworks/base/core/java/android/view/SurfaceControl.java中

static GlobalTransactionWrapper sGlobalTransaction;

public static void openTransaction() {
    synchronized (SurfaceControl.class) {
        if (sGlobalTransaction == null) {
            sGlobalTransaction = new GlobalTransactionWrapper();
        }
        synchronized(SurfaceControl.class) {
            sTransactionNestCount++;
        }
    }
}

上面分析了 openTransaction 相关的执行,下面分析下 applySurfaceChangesTransaction 函数。 11,在frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java中

private void applySurfaceChangesTransaction() {
	final int count = mChildren.size(); // 正常情况就一个屏幕
    for (int j = 0; j < count; ++j) { // 遍历每个屏幕执行 DisplayContent::applySurfaceChangesTransaction
        final DisplayContent dc = mChildren.get(j);
        dc.applySurfaceChangesTransaction();
    }
}

上面的代码调用 DisplayContent 类的 applySurfaceChangesTransaction 函数。

12,在frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java中

void applySurfaceChangesTransaction() {
	mTmpUpdateAllDrawn.clear(); // 置空
	
	// Perform a layout, if needed.
    performLayout(true /* initial */, false /* updateInputWindows */); // 执行布局,该方法最终会调用performLayoutNoTrace,计算窗口的布局参数
	
	try {
    	  // 遍历所有窗口,主要是改变窗口状态设置为READY_TO_SHOW,当前逻辑不满足,不会执行最终设置
        forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
	
	// finishDrawing()流程,条件满足触发提交Surface到SurfaceFlinger
    prepareSurfaces();
}

上面的代码中 forAllWindows 语句,会从上到下遍历每个窗口,然后执行 mApplySurfaceChangesTransaction 这个 lambda 表达式。

private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
	...
	if (w.mHasSurface) { // 判断当前是否有Surface
        // Take care of the window being ready to display.
    	 // 主流程设置为 READY_TO_SHOW 和 HAS_DRAWN
        final boolean committed = winAnimator.commitFinishDrawingLocked(); // 调用commitFinishDrawingLocked
	}
	...
	// allDrawn相关逻辑
    final ActivityRecord activity = w.mActivityRecord;
	if (activity != null && activity.isVisibleRequested()) {
        activity.updateLetterboxSurface(w);
    	  // 更新绘制状态
        final boolean updateAllDrawn = activity.updateDrawnWindowStates(w);
        if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(activity)) {
            mTmpUpdateAllDrawn.add(activity); // 加入集合
        }
    }
	w.updateResizingWindowIfNeeded();
}

在上面的代码中,mHasSurface 在 relayoutWindow 流程创建 Surface 时设置为 true ,表示当前 WindowState 的已经有 Surface, 然后就调用其 WindowStateAnimator::commitFinishDrawingLocked。

13,在frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java中

boolean commitFinishDrawingLocked() {
    if (DEBUG_STARTING_WINDOW_VERBOSE &&
            mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
        Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
                + drawStateToString());
    }
	 // 当前状态的判断,不满足则return。这个方法每次 layout 的时候都可能会执行过来,所以要判断当前窗口的状态是否符合条件执行后面的逻辑
    if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
        return false;
    }
    ProtoLog.i(WM_DEBUG_ANIM, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW %s",
            mSurfaceController); // 这个日志是上层分析黑屏问题看状态状态的关键表示已经把窗口状态设置为 READY_TO_SHOW
			
	 // 设置状态
    mDrawState = READY_TO_SHOW;
	
    boolean result = false;
    final ActivityRecord activity = mWin.mActivityRecord;
	 // 系统Window或者StartWindow则会走后续流程设置为 HAS_DRAW
    if (activity == null || activity.canShowWindows()
            || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
        result = mWin.performShowLocked();
    }
    return result;
}

上面的代码中将窗口状态设置成 READY_TO_SHOW,这是重要的一步,如果满足if语句中的三个条件之一,则设置窗口类型为HAS_DRWA。即调用WindowState类的 performShowLocked 函数进行状态设置。

14,在frameworks/base/services/core/java/com/android/server/wm/WindowState.java中

boolean performShowLocked() {
		final int drawState = mWinAnimator.mDrawState; // 获取到当前状态
	    if ((drawState == HAS_DRAWN || drawState == READY_TO_SHOW) && mActivityRecord != null) {
	        if (mAttrs.type != TYPE_APPLICATION_STARTING) { // 窗口类型不为启动窗口
	            mActivityRecord.onFirstWindowDrawn(this);
	        } else {
	            mActivityRecord.onStartingWindowDrawn();
	        }
	    }
	
		if (mWinAnimator.mDrawState != READY_TO_SHOW || !isReadyForDisplay()) {
	        return false;
	    }
		
		// 状态为HAS_DRAWN
	    mWinAnimator.mDrawState = HAS_DRAWN;
	    mWmService.scheduleAnimationLocked();
		return true;
	}

到这里状态状态已经是 HAS_DRAWN 了,现在需要真正的将窗口显示事务提交到 SurfaceFlinger。
上面的代码中,函数 performShowLocked 对当前窗口状态做检查,只有满足条件才会将状态设为 HAS_DRAWN。
上面的代码主要是设置状态,还没有实际显示 surface 的代码,具体的 surface 显示逻辑在 prepareSurfaces()函数中。

15,在frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java中

@Override
void prepareSurfaces() {
    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces");
    try {
        final Transaction transaction = getPendingTransaction(); // 拿到事务
        super.prepareSurfaces(); // 调用父类方法

        // TODO: Once we totally eliminate global transaction we will pass transaction in here
        //       rather than merging to global.
        SurfaceControl.mergeToGlobalTransaction(transaction); // 把事务merge到全局事务,供后续统一处理
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
} 

上面的代码中,主要流程是 super.prepareSurfaces();,另外看到该语句前后先是获取到了一个事务,然后再把这个事务 merge 到全局事务,这个全局事务就是 SurfaceControl 下面的一个类,也是一个 Surface 事务。那说明这之间的 super.prepareSurfaces() 会有 Surface 事务的处理,才需要把它 merge 到全局事务中。
当前逻辑中 super.prepareSurfaces() 内部对 Surface 的处理就是将目标创建的 Surface 显示的事务统一处理 GlobalTransaction 的时机就是在后面 WindowManagerService::closeSurfaceTransaction 方法处理。
DisplayContent 继承自 RootDisplayArea,RootDisplayArea继承自 DisplayArea.Dimmable,DisplayArea 继承自 WindowContainer 类,可以直接看 WindowContainer 类的 prepareSurfaces 函数。

16,在frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java中

void prepareSurfaces() {
    // If a leash has been set when the transaction was committed, then the leash reparent has
    // been committed.
    mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
    for (int i = 0; i < mChildren.size(); i++) {
        mChildren.get(i).prepareSurfaces();
    }
}

上面代码中,WindowContainer::prepareSurfaces 这个方法被很多子类重写,比如前面提到的 DisplayContent 和 DisplayArea ,另外还有像场景的 Task , ActivityRecord , WindowState 等,但是他们内部重写的逻辑也会再调用 super.prepareSurfaces();来遍历他的孩子,最终会调用到 DisplayContent 每个容器类 当前分析的窗口,所以直接看 WindowState 的实现。

17, 在frameworks/base/services/core/java/com/android/server/wm/WindowState.java中

final WindowStateAnimator mWinAnimator; //在WindowState构造函数中初始化,即mWinAnimator = new WindowStateAnimator(this);
	@Override
    void prepareSurfaces() {
        mIsDimming = false;
        applyDims();
        updateSurfacePositionNonOrganized();
        // Send information to SurfaceFlinger about the priority of the current window.
        updateFrameRateSelectionPriorityIfNeeded();
        updateScaleIfNeeded();
    
        mWinAnimator.prepareSurfaceLocked(getSyncTransaction()); // 调用 prepareSurfaceLocked 函数,参数是获取了一个 Transaction ,说明要开始对 Surface 做操作了
        super.prepareSurfaces();
    }

上面的代码中,调用 prepareSurfaceLocked 函数,参数是是获取了一个 Transaction ,说明要开始对 Surface 做操作了。

18, 在frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java中 class WindowStateAnimator {

WindowSurfaceController mSurfaceController; //在 createSurfaceLocked 函数中,mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,flags, this, attrs.type);

void prepareSurfaceLocked(SurfaceControl.Transaction t) {
	
	if (prepared && mDrawState == HAS_DRAWN) { // 状态是 HAS_DRAWN 才执行
	    if (mLastHidden) {
	        if (showSurfaceRobustlyLocked(t)) { // 调用 showSurfaceRobustlyLocked 函数
	            mAnimator.requestRemovalOfReplacedWindows(w);
	            mLastHidden = false;
	            final DisplayContent displayContent = w.getDisplayContent();
	            if (!displayContent.getLastHasContent()) {
	                // This draw means the difference between unique content and mirroring.
	                // Run another pass through performLayout to set mHasContent in the
	                // LogicalDisplay.
	                displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
	                if (DEBUG_LAYOUT_REPEATS) {
	                    mService.mWindowPlacerLocked.debugLayoutRepeats(
	                            "showSurfaceRobustlyLocked " + w,
	                            displayContent.pendingLayoutChanges);
	                }
	            }
	        } else {
	            w.setOrientationChanging(false);
	        }
	    }
	}
}    

上面的代码调用 showSurfaceRobustlyLocked 函数。

private boolean showSurfaceRobustlyLocked(SurfaceControl.Transaction t) {
	    boolean shown = mSurfaceController.showRobustly(t);	// 调用showRobustly
	    if (!shown)	
	        return false;	
		
	    t.merge(mPostDrawTransaction);	
	    return true;	
	}

上面的函数 showSurfaceRobustlyLocked 调用 showRobustly 函数。
上面的代码中,函数 showSurfaceRobustlyLocked 这里又将 Transaction 交到了 WindowSurfaceController 处理,这个类我们在 relayoutWindow 的时候创建窗口 Surface 的时候提过,Window 的 Surface 创建是在这里类控制的,所以提交的逻辑可以交给它进行处理。

19, 在frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java中

class WindowSurfaceController {
	
		boolean showRobustly(SurfaceControl.Transaction t) {
		    ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);// 关键日志,表示 Framework 已经将 Surface 提交到 SurfaceFlinger 了。(严格来说需要等后面事务的apply)
		    if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
		            + " during relayout");
		
		    if (mSurfaceShown) {
		        return true;
		    }
		
		    setShown(true); // 内部将mSurfaceShown设置为true,将 mSurfaceShown 变量设置为true, 这个也是分析黑屏问题dump要看第一个关键变量,如果为 false 说明窗口并没有显示,可能是被遮挡了
			
		    t.show(mSurfaceControl); // Surface真正的显示,show 就说明需要把 Suface 显示, 也是 finishDrawingWindow 最终的结果.
			
		    if (mAnimator.mIsWallpaper) {
		        EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
		                mAnimator.mWin.getDisplayId(), 1 /* request shown */);
		    }
		    return true;
		}
		
		void setShown(boolean surfaceShown) { // 参数传入true
		    mSurfaceShown = surfaceShown;
		
		    mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mAnimator.mWin, surfaceShown);
		
		    mAnimator.mWin.onSurfaceShownChanged(surfaceShown);
		
		    if (mWindowSession != null) {
		        mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
		    }
		}
}

上面的代码中调用了 Transaction 类的 show 函数。

20, 在frameworks/base/core/java/android/view/SurfaceControl.java中

private static native void nativeSetFlags(long transactionObj, long nativeObject,int flags, int mask);

	public static class Transaction implements Closeable, Parcelable {
	
		@UnsupportedAppUsage
		public Transaction show(SurfaceControl sc) {
		    checkPreconditions(sc);
		    nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN);
		    return this;
		}
	} 

上面的函数调用 nativeSetFlags 函数。

21,在frameworks/base/core/jni/android_view_SurfaceControl.cpp中

static const JNINativeMethod sSurfaceControlMethods[] = {
		{"nativeSetFlags", "(JJII)V",(void*)nativeSetFlags },
	}
	
	static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
	        jlong nativeObject, jint flags, jint mask) {	
		 // 使用reinterpret_cast将transactionObj从jlong(即Java层传递的长整型引用)转换为SurfaceComposerClient::Transaction*类型	
	    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);	
		 // 同样使用reinterpret_cast将nativeObject从jlong转换为SurfaceControl*类型。这允许本地代码操作SurfaceControl对象	
	    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);	
	    transaction->setFlags(ctrl, flags, mask);	// 调用SurfaceComposerClient的setFlags函数
	}                                     

上面的代码调用SurfaceComposerClient的setFlags函数。

22,在frameworks/Native/libs/gui/SurfaceComposerClient.cpp中

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
	        const sp<SurfaceControl>& sc, uint32_t flags,	
	        uint32_t mask) { // 第一个参数是一个指向SurfaceControl对象的智能指针(sp是Android系统中用于管理对象生命周期的智能指针)	
		  // 调用getLayerState函数获取与SurfaceControl对象对应的layer_state_t结构体指针。这个结构体包含了图层的各种状态信息	
	    layer_state_t* s = getLayerState(sc);	
		  // 如果getLayerState返回nullptr(即没有找到对应的图层状态),则将mStatus设置为BAD_INDEX(表示索引错误),并返回当前Transaction对象的引用。	
	    if (!s) {	
	        mStatus = BAD_INDEX;	
	        return *this;	
	    }	
	    if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||	
	        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||	
	        (mask & layer_state_t::eEnableBackpressure) ||	
	        (mask & layer_state_t::eLayerIsDisplayDecoration)) {	
	        s->what |= layer_state_t::eFlagsChanged;	
	    }	
	    s->flags &= ~mask; // 使用位运算清除s->flags中mask指定的位。	
	    s->flags |= (flags & mask); // 使用位运算将flags中与mask相对应的位设置到s->flags中	
	    s->mask |= mask; // 将mask设置到s->mask中,表示这些位是有效的	
		
	    registerSurfaceControlForCallback(sc);	// 将一个SurfaceControl对象注册到某个回调机制中,以便在该SurfaceControl对象的状态发生变化时能够接收到通知
	    return *this;	
	}

上面的代码调用 registerSurfaceControlForCallback 函数。

void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback(
            const sp<SurfaceControl>& sc) { // 一个指向SurfaceControl对象的智能指针(sp是Android系统中用于管理对象生命周期的智能指针)。
			
    	  // 通过 mListenerCallbacks 获取与TransactionCompletedListener的实例相关联的回调信息
        auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()];
		
    	  // 将传入的SurfaceControl对象sc插入到回调信息结构体中的surfaceControls集合中
        callbackInfo.surfaceControls.insert(sc);
    
    	  // 首先通过TransactionCompletedListener::getInstance()方法获取TransactionCompletedListener的单例实例,然后调用该实例的 addSurfaceControlToCallbacks 方法。
    	  // 这个方法的作用是将SurfaceControl对象sc和回调信息中的callbackIds关联起来。这样,当SurfaceControl对象的状态发生变化时,系统可以通过这些回调ID通知相应的监听器。
        TransactionCompletedListener::getInstance()
                ->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds);
    }

上面的代码用到了 mListenerCallbacks 变量。

23,在frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h中

class Transaction : public Parcelable {
		// mListenerCallbacks 是一个 std::unordered_map 类型的成员变量,它用于存储与不同监听器相关联的回调信息,这个 std::unordered_map 有三个模板参数:键的类型、值的类型,以及一个自定义的哈希函数类型(TCLHash)。
		std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash> mListenerCallbacks;
	}

上面分析了 applySurfaceChangesTransaction 函数的执行,执行完事务,则需要关闭事务即调用 closeSurfaceTransaction 函数。

24,在frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java中

void closeSurfaceTransaction(String where) {
	    try {
	        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
	        SurfaceControl.closeTransaction(); // 调用closeTransaction
	        mWindowTracing.logState(where);
	    } finally {
	        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
	    }
	}

上面的代码调用 SurfaceControl.closeTransaction();

25,在frameworks/base/core/java/android/view/SurfaceControl.java中

static GlobalTransactionWrapper sGlobalTransaction;

	public static void closeTransaction() {
	    synchronized(SurfaceControl.class) {
	        if (sTransactionNestCount == 0) {
	            Log.e(TAG,
	                    "Call to SurfaceControl.closeTransaction without matching openTransaction");
	        } else if (--sTransactionNestCount > 0) {
	            return;
	        }
            sGlobalTransaction.applyGlobalTransaction(false); // 调用 applyGlobalTransaction
        }
    }

上面的函数调用 GlobalTransactionWrapper 类的 applyGlobalTransaction 函数。

private static class GlobalTransactionWrapper extends SurfaceControl.Transaction { // SurfaceControl.Transaction是一个用于控制屏幕显示内容的类,通常用于在Android系统中进行底层UI操作
	    void applyGlobalTransaction(boolean sync) {
	        applyResizedSurfaces();
	        notifyReparentedSurfaces();
		// 进行apply
	        nativeApplyTransaction(mNativeObject, sync); // 用于实际将事务应用到系统底层
	    }
	
	    @Override
	    public void apply(boolean sync) { // 被重写以抛出一个RuntimeException异常,表明全局事务必须通过closeTransaction方法来应用,而不是直接调用apply方法。
	        throw new RuntimeException("Global transaction must be applied from closeTransaction");
	    }
	}
	
	private static native void nativeApplyTransaction(long transactionObj, boolean sync);

上面的代码中静态类 GlobalTransactionWrapper 继承自 SurfaceControl.Transaction,在 SurfaceControl 中,Transaction 是一个静态类。

public static class Transaction implements Closeable, Parcelable {
	public void apply(boolean sync) {
        applyResizedSurfaces();
        notifyReparentedSurfaces();
        nativeApplyTransaction(mNativeObject, sync);
    }
}

上面的代码中执行了本地方法 nativeApplyTransaction,它是在 SurfaceControl.cpp中注册的。

26,在frameworks/base/core/jni/android_view_SurfaceControl.cpp中

static const JNINativeMethod sSurfaceControlMethods[] = {
	{"nativeApplyTransaction", "(JZ)V",
            (void*)nativeApplyTransaction },
}

int register_android_view_SurfaceControl(JNIEnv* env)
{
    int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
            sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
}

static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
	 // 将jlong类型的transactionObj转换为SurfaceComposerClient::Transaction*类型,reinterpret_cast是一种C++强制类型转换,它允许将一种指针类型转换为另一种指针类型,而不进行任何检查。
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
	 // 调用 SurfaceComposerClient::Transaction 对象的 apply 方法,并将sync参数传递给它。执行 SurfaceControl.Transaction::apply 通知 SurfaceFlinger
    transaction->apply(sync);
}

上面的代码调用 SurfaceComposerClient::Transaction对象的 apply 方法。

27,在frameworks/native/libs/gui/SurfaceComposerClient.cpp中

status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {
    if (mStatus != NO_ERROR) { // 检查当前状态,如果mStatus不是NO_ERROR,则直接返回当前状态,表示事务已经因为之前的错误而失效。
        return mStatus;
    }

	 // 通过ComposerService::getComposerService()获取ISurfaceComposer服务的代理,ISurfaceComposer是一个接口,用于与SurfaceFlinger服务进行通信。
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());

    bool hasListenerCallbacks = !mListenerCallbacks.empty(); // 检查是否有注册的监听器回调(mListenerCallbacks不为空)。
    std::vector<ListenerCallbacks> listenerCallbacks; // 定义一个listenerCallbacks向量,用于存储监听器回调信息
    // For every listener with registered callbacks
    for (const auto& [listener, callbackInfo] : mListenerCallbacks) {
        auto& [callbackIds, surfaceControls] = callbackInfo;
        if (callbackIds.empty()) { // 遍历所有注册的监听器回调。如果某个监听器的回调ID列表(callbackIds)为空,则跳过该监听器。
            continue;
        }

        if (surfaceControls.empty()) { // 如果监听器没有关联任何SurfaceControl(表示图层的控制对象),则直接将监听器和回调ID添加到listenerCallbacks向量中。
            listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
        } else { // 如果监听器有关联的SurfaceControl
            // If the listener has any SurfaceControls set on this Transaction update the surface
            // state
            for (const auto& surfaceControl : surfaceControls) {
                layer_state_t* s = getLayerState(surfaceControl); // 通过getLayerState(surfaceControl)获取图层的状态
                if (!s) { // 如果无法获取图层状态,则记录错误日志并继续下一个循环。
                    ALOGE("failed to get layer state");
                    continue;
                }
                std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end()); // 复制回调ID列表。
                s->what |= layer_state_t::eHasListenerCallbacksChanged; // 设置图层状态标志,表示监听器回调已更改。
                s->listeners.emplace_back(IInterface::asBinder(listener), callbacks); // 将监听器和回调ID添加到图层的监听器列表中。
            }
        }
    }

    cacheBuffers();
	
	Vector<ComposerState> composerStates; // 定义一个ComposerState类型的向量composerStates,用于存储图层(Layer)的状态信息。
    Vector<DisplayState> displayStates; // 定义一个DisplayState类型的向量displayStates,用于存储显示设备(Display)的状态信息。
    uint32_t flags = 0; // 定义一个32位无符号整数flags,用于标记事务的各种属性或选项。
    
    mForceSynchronous |= synchronous;
    
     for (auto const& kv : mComposerStates){
         composerStates.add(kv.second);
     }
    
     displayStates = std::move(mDisplayStates); // 使用std::move将mDisplayStates(存储显示设备状态的向量)的内容移动到displayStates向量中。这避免了不必要的复制,并允许mDisplayStates在移动后被重用或清空。
    
     if (mForceSynchronous) {
         flags |= ISurfaceComposer::eSynchronous;
     }
     if (mAnimation) {
         flags |= ISurfaceComposer::eAnimation;
     }
     if (oneWay) {
       if (mForceSynchronous) {
           ALOGE("Transaction attempted to set synchronous and one way at the same time"
                 " this is an invalid request. Synchronous will win for safety");
       } else {
           flags |= ISurfaceComposer::eOneWay;
       }
     }
    
     // If both mEarlyWakeupStart and mEarlyWakeupEnd are set
     // it is equivalent for none
     if (mEarlyWakeupStart && !mEarlyWakeupEnd) {
         flags |= ISurfaceComposer::eEarlyWakeupStart;
     }
     if (mEarlyWakeupEnd && !mEarlyWakeupStart) {
         flags |= ISurfaceComposer::eEarlyWakeupEnd;
     }
	 
	 // 定义了一个指向IBinder接口的智能指针applyToken。它首先检查mApplyToken是否非空(即是否已经设置了一个应用令牌)。
     // 如果mApplyToken非空,则applyToken被设置为mApplyToken的值;如果mApplyToken为空,则applyToken被设置为TransactionCompletedListener单例的IBinder接口。
     sp<IBinder> applyToken = mApplyToken
             ? mApplyToken
             : IInterface::asBinder(TransactionCompletedListener::getIInstance());
     
     // 将事务的状态提交给SurfaceFlinger
     sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
                             mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
                             {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
                             hasListenerCallbacks, listenerCallbacks, mId);
     mId = generateId(); // 生成一个新的ID,并将其赋值给mId。这个新ID可能用于标识下一个事务,或者用于跟踪当前事务的状态。
     
     // Clear the current states and flags
     clear(); // 调用clear方法清除当前事务的所有状态和标志。这是为了准备下一个事务,确保不会重复使用或混淆当前事务的状态。
     
     mStatus = NO_ERROR;
     return NO_ERROR;
}

上面的代码执行了 apply 通知 surfaceFlinger.