WMS 系统窗口添加流程
文章目录
- WMS 系统窗口添加流程
- 一. addView
- 二. addView代码分析
- 2.1 应用端调用WindowManager的addView
- 2.2 WindowManager的实现类是WindowManagerImpl
- 2.3 WindowManagerGlobal
- 2.4 setView
- 2.4 addToDisplayAsUser(Session.java)
- 2.5 addWindow(WindowManagerService.java)
- 2.6 WindowToken的创建
- 三. relayout
- 3.1 TraversalRunnable
- 3.2 doTraversal
- 3.3 performTraversals
- 3.4 relayoutWindow
- 3.4.1 relayout(Session)
- 3.4.1.1 relayoutWindow(WindowManagerService)
- 3.4.1.2 createSurfaceControl
- 3.4.2 performSurfacePlacement 强制布局
- 四. finishDraw
- 4.1 reportDrawFinished
- 4.2 finishDrawing(Session.java)
- 4.3 finishDrawingWindow(WindowManagerService.java)
- 4.4 WindowState.finishDraw
- 4.5 finishDrawingLocked(WindowStateAnimation.java)
- 4.6 requestTraversal(Windowurfaceplacer.java)
- 4.7 mPerformSurfacePlacement
- 4.8. performSurfacePlacement(WindowSurfacePlacer.java)
- 4.9 performSurfacePlacement
- 4.10 performSurfacePlacementLoop
- 4.11 mRoot.performSurfacePlacement
- 4.12 performSurfacePlacementNoTrace
- 4.13 applySurfaceChangesTransaction
- 4.14 applySurfaceChangesTransaction(DisplayContent)
- 4.15 mApplySurfaceChangesTransaction
- 4.16 commitFinishDrawingLocked(WindowAnimator)
- 4.17 performShowLocked
- 五. prepareSurface
- 5.1 prepareSurfaces
- 5.1.1 prepareSurfaces
- 5.1.2 prepareSurfaces(WindowContainer)
- 5.1.3 prepareSurfaces(WindowState)
- 5.1.4 mWinAnimator.prepareSurfaceLocked
- 5.1.5 showSurfaceRobustlyLocked
- 5.1.6 showRobustly
- 5.1.7 closeSurfaceTransaction
- 六. 高清大图
千里马framework学习笔记
环境: android 13
分析系统窗口添加流程,以悬浮窗为例
整体步骤分为四个,如下:
- addView
- relayout
- finishraw
- prepareurfaces
一. addView
主要流程如下:
先说结论:addView主要做了什么?
addView 创建了WindowToken以及WindowState
其中也包括InputChannel的创建(事件相关)
二. addView代码分析
2.1 应用端调用WindowManager的addView
WindowManager mWindowManager;
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(mLayout, mLayoutParams);
2.2 WindowManager的实现类是WindowManagerImpl
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyTokens(params);
// 这里又调用了WindowManagerGlobal的addview
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId());
}
2.3 WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
// ... 省略若干容错代码
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
// 一些参数调整
parentWindow.adjustLayoutParamsForSubWindow(wparams);
}
// ... 省略一些代码
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// ... 仅保留主要代码
IWindowSession windowlessSession = null;
if (windowlessSession == null) {
// 创建ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
}
// 设置View的参数
view.setLayoutParams(wparams);
// 将view保存到一个集合中 ArrayList<View> mViews = new ArrayList<View>();
mViews.add(view);
// 将 root 也添加到集合中 ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
mRoots.add(root);
// 将参数也添加到集合中 ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.LayoutParams>();
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
// TODO 重点,这里就是将view添加到WMS中的入口
root.setView(view, wparams, panelParentView, userId);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
2.4 setView
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
synchronized (this) {
// 这里view是不为null的一般
if (mView == null) {
mView = view;
// ... 省略部分非主体代码
// 下面就是InputChannel的创建了,这个和事件相关,不在这里分析
InputChannel inputChannel = null;
if ((mWindowAttributes.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
inputChannel = new InputChannel();
}
try {
// 调用session的addToDisplayAsUser将window添加到wms
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId,
mInsetsController.getRequestedVisibilities(), inputChannel, mTempInsets,
mTempControls);
}catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
attrs.restore();
}
}
// ... 省略非主体代码
2.4 addToDisplayAsUser(Session.java)
public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, int userId, InsetsVisibilities requestedVisibilities,
InputChannel outInputChannel, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls) {
// 这里直接调用了WMS的addWindow,Session只是一个代理罢了(binder通信)
return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
requestedVisibilities, outInputChannel, outInsetsState, outActiveControls);
}
2.5 addWindow(WindowManagerService.java)
public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
int displayId, int requestUserId, InsetsVisibilities requestedVisibilities,
InputChannel outInputChannel, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls) {
WindowState parentWindow = null;
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
final int type = attrs.type;
synchronized (mGlobalLock) {
// 根据displayId获取displayContent,一般为0,手机一般一个屏幕
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);
// ... 省略容错代码
ActivityRecord activity = null;
final boolean hasParent = parentWindow != null;
// 窗口不存在的时候这里是获取不到的
WindowToken token = displayContent.getWindowToken(
hasParent ? parentWindow.mAttrs.token : attrs.token);
// If this is a child window, we want to apply the same type checking rules as the
// parent window type.
final int rootType = hasParent ? parentWindow.mAttrs.type : type;
boolean addToastWindowRequiresToken = false;
final IBinder windowContextToken = attrs.mWindowContextToken;
// 这里一般为null
if (token == null) {
// token的创建,在创建的时候就将它挂载到层级结构树上了
token = new WindowToken.Builder(this, binder, type)
.setDisplayContent(displayContent)
.setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow)
.setRoundedCornerOverlay(isRoundedCornerOverlay)
.build();
}
// windowState的创建
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], attrs, viewVisibility, session.mUid, userId,
session.mCanAddInternalSystemWindow);
res = ADD_OKAY;
win.attach();
// 保存window 方便查找 StateHashMap<IBinder, WindowState> mWindowMap = new HashMap<>();
mWindowMap.put(client.asBinder(), win);
// 将windowState添加到windowToken下面
win.mToken.addWindow(win);
}
// ... 省略非主体部分
return res;
}
2.6 WindowToken的创建
protected WindowToken(WindowManagerService service, IBinder _token, int type,
boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens,
boolean roundedCornerOverlay, boolean fromClientToken, @Nullable Bundle options) {
super(service);
token = _token;
windowType = type;
mOptions = options;
mPersistOnEmpty = persistOnEmpty;
mOwnerCanManageAppTokens = ownerCanManageAppTokens;
mRoundedCornerOverlay = roundedCornerOverlay;
mFromClientToken = fromClientToken;
if (dc != null) {
// 这里,将windowToken添加到层级结构树上
dc.addWindowToken(token, this);
}
}
到此为止,addView部分,流程结束
三. relayout
主要流程如下图:
在收到Vsync信号时会执行ViewRootImpl中的TraversalRunnable方法
3.1 TraversalRunnable
// 这是一个runnable,会执行其中的run方法
final class TraversalRunnable implements Runnable {
@Override
public void run() {
// 如上图,执行doTraversal
doTraversal();
}
}
3.2 doTraversal
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = fals;
// 紧接着执行performTraversals,这些方法都是一路调下去的,也没啥好解释的
performTraversals();
}
}
3.3 performTraversals
// 这个方法太长,删除了部分不重要的
private void performTraversals() {
// ... 省略部分代码
// 对window进行布局
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
final boolean dragResizing = mPendingDragResizing;
if (mSyncSeqId > mLastSyncSeqId) {
mLastSyncSeqId = mSyncSeqId;
if (DEBUG_BLAST) {
Log.d(mTag, "Relayout called with blastSync");
}
reportNextDraw();
mSyncBuffer = true;
}
// ... 省略部分代码
}
3.4 relayoutWindow
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
int relayoutResult = 0;
// 获取窗口配置
WindowConfiguration winConfig = getConfiguration().windowConfiguration;
// 根据参数对window布局
relayoutResult = mWindowSession.relayout(mWindow, params,
requestedWidth, requestedHeight, viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mRelayoutBundle);
final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
if (maybeSyncSeqId > 0) {
mSyncSeqId = maybeSyncSeqId;
}
if (mTranslator != null) {
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
}
mInsetsController.onStateChanged(mTempInsets);
mInsetsController.onControlsChanged(mTempControls);
mPendingAlwaysConsumeSystemBars =
(relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
final int transformHint = SurfaceControl.rotationToBufferTransform(
(mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
return relayoutResult;
}
3.4.1 relayout(Session)
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncSeqIdBundle) {
// 这里又调用到了WMS中的relayoutWindow
int res = mService.relayoutWindow(this, window, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
outActiveControls, outSyncSeqIdBundle);
return res;
}
3.4.1.1 relayoutWindow(WindowManagerService)
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {
synchronized (mGlobalLock) {
// 获取windowState,这就是前面保存起来的windowState
final WindowState win = windowForClientLocked(session, client, false);
final DisplayContent displayContent = win.getDisplayContent();
final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
WindowStateAnimator winAnimator = win.mWinAnimator;
if (shouldRelayout) {
// TODO: 重点,创建SrufaceControl
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
}
// 强制布局
mWindowPlacerLocked.performSurfacePlacement(true /* force */);
return result;
}
3.4.1.2 createSurfaceControl
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
// 声明一个本地的变量
WindowSurfaceController surfaceController;
// 开始创建
surfaceController = winAnimator.createSurfaceLocked();
// 如果不为null则创建成功
if (surfaceController != null) {
// 赋值给outSurfaceControl,这个是传出参数,传进来是空的,这里就将重新指向了新创建的surfaceControl
surfaceController.getSurfaceControl(outSurfaceControl);
ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
}
return result;
}
这个函数执行完,SurfaceControl就创建好了,接着我们往回退
3.4.2 performSurfacePlacement 强制布局
final void performSurfacePlacement(boolean force) {
int loopCount = 6;
do {
mTraversalScheduled = false;
// 这里调用栈很深,可以跟着上面的流程图走一遍
performSurfacePlacementLoop();
mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
loopCount--;
} while (mTraversalScheduled && loopCount > 0);
mService.mRoot.mWallpaperActionPending = false;
}
到此,relayout也结束了
四. finishDraw
主流程图如下:
当layout完成之后,wms会通知应用开始绘制,应用端绘制完成之后会告知wms已经绘制完成,wms会将根据状态将surface提交给surfaceflinger进行合成。
其中,绘制状态如下:
没有surface的时候,处于NO_SURFACE状态,经过relayout后,创建了surfaceControl,就变成了DRAW_PENDING
上面的流程图,其中reportDrawFinished是回调方法,当绘制完成之后会回调到这里,看流程图的时候需要注意,并不是顺序往下调用的。
这段代码着重说明一下, 通过 mSurfaceSyncer.setupSync() 方法将transaction添加到 mSurfaceSyncer 中进行同步。还会设置一个回调函数,该回调函数会在 SurfaceSync 对象完成同步后被调用。
在回调函数中,首先将当前的绘制操作合并到 mSurfaceChangedTransaction 中,然后调用 reportDrawFinished() 方法通知主线程界面绘制完成。最后,在创建 SurfaceSync 对象后,还会将其添加到 mSyncTarget 中,以进行同步。
这段代码的作用是为界面绘制操作创建一个 SurfaceSync 对象,并将其添加到同步队列中进行同步,以保证多个 Surface 的同步更新。
TODO: 这里容易忽略这个回调。就会认为没有绘制就走了finishDraw的流程,所以一定记得是绘制完成了才走的这里
4.1 reportDrawFinished
private void reportDrawFinished(int seqId) {
// 调用session的finishDrawing
mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction, seqId);
}
4.2 finishDrawing(Session.java)
public void finishDrawing(IWindow window,
@Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
// 这里又直接调用了wms的finishDrawingWindow,和上面一样,其实就可以看出来了,Session其实就是应用端和WMS沟通的代理
mService.finishDrawingWindow(this, window, postDrawTransaction, seqId);
}
4.3 finishDrawingWindow(WindowManagerService.java)
void finishDrawingWindow(Session session, IWindow client,
@Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
synchronized (mGlobalLock) {
// 获得windowstate
WindowState win = windowForClientLocked(session, client, false);
// 调用windowState的finishDrawing
if (win != null && win.finishDrawing(postDrawTransaction, seqId)) {
win.setDisplayLayoutNeeded();
mWindowPlacerLocked.requestTraversal();
}
}
}
4.4 WindowState.finishDraw
boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
if (mOrientationChangeRedrawRequestTime > 0) {
// ... 省略
final boolean layoutNeeded =
mWinAnimator.finishDrawingLocked(postDrawTransaction, mClientWasDrawingForSync);
mClientWasDrawingForSync = false;
// We always want to force a traversal after a finish draw for blast sync.
return !skipLayout && (hasSyncHandlers || layoutNeeded);
}
4.5 finishDrawingLocked(WindowStateAnimation.java)
boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction,
boolean forceApplyNow) {
// 前面就知道,当创建完成SurfaceControl之后,DrawState就会变成DRAW_PENDING,这里符合条件
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);
}
// 这里直接赋值为COMMIT_DRAW_PENDING
mDrawState = COMMIT_DRAW_PENDING;
layoutNeeded = true;
}
return layoutNeeded;
}
根据流程图,回到wms
4.6 requestTraversal(Windowurfaceplacer.java)
void requestTraversal() {
// 接下来执行mPerformSurfacePlacement
mService.mAnimationHandler.post(mPerformSurfacePlacement);
}
源码就是这样的,一层一层的,我们只需要关注重点就行,主体流程不需要记忆,这里仅仅是按照源码分析,因为不同的版本,源码会有不同的差异,但主体思想一般不会有大改动。
4.7 mPerformSurfacePlacement
private class Traverser implements Runnable {
@Override
public void run() {
synchronized (mService.mGlobalLock) {
// 执行这个方法
performSurfacePlacement();
}
}
}
4.8. performSurfacePlacement(WindowSurfacePlacer.java)
final void performSurfacePlacement() {
performSurfacePlacement(false /* force */);
}
4.9 performSurfacePlacement
final void performSurfacePlacement(boolean force) {
if (mDeferDepth > 0 && !force) {
mDeferredRequests++;
return;
}
int loopCount = 6;
do {
mTraversalScheduled = false;
// 执行这个,其实和前面都一样了
performSurfacePlacementLoop();
mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
loopCount--;
} while (mTraversalScheduled && loopCount > 0);
mService.mRoot.mWallpaperActionPending = false;
}
4.10 performSurfacePlacementLoop
private void performSurfacePlacementLoop() {
mService.mRoot.performSurfacePlacement();
}
4.11 mRoot.performSurfacePlacement
void performSurfacePlacement() {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
try {
// 继续执行这里
performSurfacePlacementNoTrace();
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
4.12 performSurfacePlacementNoTrace
void performSurfacePlacementNoTrace() {
// 打开一个事物
mWmService.openSurfaceTransaction();
try {
// 执行这个函数
applySurfaceChangesTransaction();
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
// 关闭一个事物
mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
}
}
4.13 applySurfaceChangesTransaction
private void applySurfaceChangesTransaction() {
final int count = mChildren.size();
for (int j = 0; j < count; ++j) {
final DisplayContent dc = mChildren.get(j);
// 执行这里
dc.applySurfaceChangesTransaction();
}
}
4.14 applySurfaceChangesTransaction(DisplayContent)
void applySurfaceChangesTransaction() {
// 执行 mApplySurfaceChangesTransaction
forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
}
4.15 mApplySurfaceChangesTransaction
private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
// 执行这里
final boolean committed = winAnimator.commitFinishDrawingLocked();
};
4.16 commitFinishDrawingLocked(WindowAnimator)
boolean commitFinishDrawingLocked() {
// TODO 这里将状态修改为READY_TO_SHOW
mDrawState = READY_TO_SHOW;
boolean result = false;
final ActivityRecord activity = mWin.mActivityRecord;
if (activity == null || activity.canShowWindows()
|| mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
// 对于系统窗口来讲,会走这里
result = mWin.performShowLocked();
}
return result;
}
4.17 performShowLocked
boolean performShowLocked() {
// 赋值状态为HAS_DRAWN
mWinAnimator.mDrawState = HAS_DRAWN;
return true;
}
其中,在上面的分析中,有一点需要注意,commitfinishDrawing之后,会将mdrawState设置为READY_TO_SHOW,然后就又设置为HAS_DRAW,这个时候HAS_DRAW并非代表已经显示出来了,窗口内容仅仅是被绘制到了表面缓冲区,只有prepareSurface执行完成之后,才会告知系统surface缓冲区可以进行后续操作。
五. prepareSurface
主流程如下图:
5.1 prepareSurfaces
在HAS_DRAW之后,回到前面的commitfinishDrawing之后的逻辑
void prepareSurfaces() {
try {
final Transaction transaction = getPendingTransaction();
// 执行父类的prepareSurfaces
super.prepareSurfaces();
// TODO: Once we totally eliminate global transaction we will pass transaction in here
// rather than merging to global.
SurfaceControl.mergeToGlobalTransaction(transaction);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
5.1.1 prepareSurfaces
void prepareSurfaces() {
mDimmer.resetDimStates();
// 继续prepareSurfaces
super.prepareSurfaces();
}
5.1.2 prepareSurfaces(WindowContainer)
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的prepareSurfaces
mChildren.get(i).prepareSurfaces();
}
}
5.1.3 prepareSurfaces(WindowState)
void prepareSurfaces() {
// 执行这里
mWinAnimator.prepareSurfaceLocked(getSyncTransaction());
super.prepareSurfaces();
}
5.1.4 mWinAnimator.prepareSurfaceLocked
void prepareSurfaceLocked(SurfaceControl.Transaction t) {
final WindowState w = mWin;
if (!hasSurface()) {
// There is no need to wait for an animation change if our window is gone for layout
// already as we'll never be visible.
if (w.getOrientationChanging() && w.isGoneForLayout()) {
ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change skips hidden %s", w);
w.setOrientationChanging(false);
}
return;
}
computeShownFrameLocked();
if (w.isParentWindowHidden() || !w.isOnScreen()) {
hide(t, "prepareSurfaceLocked");
mWallpaperControllerLocked.hideWallpapers(w);
// If we are waiting for this window to handle an orientation change. If this window is
// really hidden (gone for layout), there is no point in still waiting for it.
// Note that this does introduce a potential glitch if the window becomes unhidden
// before it has drawn for the new orientation.
if (w.getOrientationChanging() && w.isGoneForLayout()) {
w.setOrientationChanging(false);
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Orientation change skips hidden %s", w);
}
} else if (mLastAlpha != mShownAlpha
|| mLastHidden) { // 窗口在没有显示之前都是隐藏的,创建surface的时候置位true
mLastAlpha = mShownAlpha;
ProtoLog.i(WM_SHOW_TRANSACTIONS,
"SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s",
mSurfaceController, mShownAlpha, w.mHScale, w.mVScale, w);
boolean prepared =
mSurfaceController.prepareToShowInTransaction(t, mShownAlpha); // 设置一下alpha
if (prepared && mDrawState == HAS_DRAWN) {
if (mLastHidden) {
// 执行这里
if (showSurfaceRobustlyLocked(t))
}
}
}
5.1.5 showSurfaceRobustlyLocked
private boolean showSurfaceRobustlyLocked(SurfaceControl.Transaction t) {
// 执行showRobustly
boolean shown = mSurfaceController.showRobustly(t);
}
5.1.6 showRobustly
boolean showRobustly(SurfaceControl.Transaction t) {
// 这里就告诉系统我们已经可以显示了
t.show(mSurfaceControl);
return true;
}
5.1.7 closeSurfaceTransaction
关闭事物