正常的流程应用的onResume调用完成之后会在eventlog中打印wm_on_resume_called,然后界面进行Relayout Window其中包含了performSurfacePlacement刷新界面和更新焦点updateFocusedWindow(会从top到bottom遍历canReciveKey为true的界面),将焦点切换到新的上面,此时WMS的windowstate已经获取了焦点,将window state状态往surfaceFlinger传递,在surfaceFlinger中传入InputDispatcher将ANR超时时间重置。
WMS -->InputDispatcher的window的传递流程大致如下:
10-29 10:15:26.575 1164 1230 D SurfaceControl: at android.view.SurfaceControl$Transaction.setInputWindowInfo(SurfaceControl.java:2563)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.accept(InputMonitor.java:566)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.accept(InputMonitor.java:429)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2040)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2030)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4742)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4641)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.ActivityRecord.forAllWindowsUnchecked(ActivityRecord.java:3807)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.ActivityRecord.forAllWindows(ActivityRecord.java:3802)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.TaskDisplayArea.forAllWindows(TaskDisplayArea.java:488)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1346)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1363)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.updateInputWindows(InputMonitor.java:466)--->
Trace打印:updateInputWindows
mDisplayContent.forAllWindows(this,true /* traverseTopToBottom */);
遍历动画过程中完成相应的动画切换
mDisplayContent.scheduleAnimation();--> mChoreographer.postFrameCallback(mAnimationFrameCallback)-→
WindowAnimator.animate(Trace打印:wmAnimate)<-->WindowAnimator.scheduleAnimation/* Schedule next frame already such that back-pressure happens continuously*/
在WindowAnimator.animate中updateWindowsForAnimator更新所有window 的动画,最终会执行WindowAnimator.forAllWindows遍历所有。
完成所有的更新提交给SurfaceFlinger,Trace打印closeSurfaceTransaction
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.access$700(InputMonitor.java:429)
10-29 10:15:26.575 1164 1230 D SurfaceControl: at com.android.server.wm.InputMonitor$UpdateInputWindows.run(InputMonitor.java:146)
在如上堆栈在WMS完成遍历后,进入surface层
SurfaceControl.setInputWindowInfo-->
android_view_SurfaceControl.nativeSetInputWindowInfo-->
SurfaceComposerClient.setInputWindowInfo-->
SurfaceFlinger.run-->
surfaceflinger/Scheduler/MessageQueue.waitMessage
MessageQueue.waitMessage -->
MessageQueue.cb_eventReceiver -->
MessageQueue.eventReceiver -->
MessageQueue.dispatchInvalidate--->
mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime)
SurfaceFlinger.onMessageReceived--->
MessageQueue::INVALIDATE -->
SurfaceFlinger.onMessageInvalidate-->
SurfaceFlinger.updateInputFlinger-->
SurfaceFlinger.updateInputWindowInfo -->{
将更新的layer push到inputHandles中
inputHandles.push_back(layer->fillInputInfo());
mInputFlinger->setInputWindows(inputHandles, mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener: nullptr);
}
IInputFlinger.setInputWindows{
remote()->transact(BnInputFlinger::SET_INPUT_WINDOWS_TRANSACTION, data, &reply,IBinder::FLAG_ONEWAY);
}-→
Binder调用到
InputDispatcher.setInputWindows
InputDispatcher接收到符合条件的window做重超时重置
//刷新大致流程
ViewRootImpl.performTraversals -->
ViewRootImpl.scheduleTraversals -->
ViewRootImpl.mTraversalRunnable.run -->
ViewRootImpl.doTraversal -->
ViewRootImpl.performTraversals -->
ViewRootImpl.relayoutWindow -->
Session.relayout -->
WindowManagerService.relayoutWindow{
1.performSurfacePlacement//刷新界面
2.updateFocusedWindowLocked//更新焦点
}
1.performSurfacePlacement打印的堆栈
1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1342)
1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1347)
1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1347)
1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1347)
1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1364)
1228 4460 E WindowManager: at com.android.server.wm.DisplayContent.performLayoutNoTrace(DisplayContent.java:4111)
1228 4460 E WindowManager: at com.android.server.wm.DisplayContent.performLayout(DisplayContent.java:4071)
1228 4460 E WindowManager: at com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:3964)
1228 4460 E WindowManager: at com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:1094)
applySurfaceChangesTransaction中主要执行如下操作
1.performLayout-->Trace打印:performLayout
2.performLayoutNoTrace
{
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
mDisplayPolicy.beginPostLayoutPolicyLw();
forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");
forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
1228 4460 E WindowManager: at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:847)--->
Trace打印:performSurfacePlacement
在performSurfacePlacementNoTrace中主要进行了如下操作
mWmService.openSurfaceTransaction();-->打开事务处理
applySurfaceChangesTransaction();-->遍历所有的mChildren 有状态改变的windowstate通知SurfaceFlinger做更新
mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");--->
Trace打印closeSurfaceTransaction
通知SurfaceControl关闭事务,其中主要是sGlobalTransaction.apply()。对应的是SurfaceComposerClient(其实是 SF 所在进程的代理)中的apply遍历SurfaceControls layer统一提交给SurfaceFlinger。
1228 4460 E WindowManager: at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:804)
1228 4460 E WindowManager: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:178)
1228 4460 E WindowManager: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:127)
1228 4460 E WindowManager: at com.android.server.wm.WindowManagerService.relayoutWindow(WindowManagerService.java:2403)
1228 4460 E WindowManager: at com.android.server.wm.Session.relayout(Session.java:213)
2.updateFocusedWindowLocked打印的堆栈
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1342)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1347)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1347)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1347)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.DisplayContent.findFocusedWindow(DisplayContent.java:3177)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.DisplayContent.findFocusedWindowIfNeeded(DisplayContent.java:3171)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.DisplayContent.updateFocusedWindowLocked(DisplayContent.java:3200)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.RootWindowContainer.updateFocusedWindowLocked(RootWindowContainer.java:456)-->
Trace打印:wmUpdateFocus
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.WindowManagerService.updateFocusedWindowLocked(WindowManagerService.java:5728)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.WindowManagerService.relayoutWindow(WindowManagerService.java:2462)
12-04 07:23:36.205 1228 4460 E WindowManager: at com.android.server.wm.Session.relayout(Session.java:213)
WindowManagerService.updateFocusedWindowLocked-->
RootWindowContainer.updateFocusedWindowLocked-->
//遍历所有mChildren window状态更新焦点
DisplayContent.updateFocusedWindowLocked{
1.DisplayContent.findFocusedWindowIfNeeded 寻找焦点
2.输出focus window log,在WMS测新焦点已获取
Slog.w(TAG_WM, "Changing focus from" + mCurrentFocus + " to " + newFocus+ " displayId=" + getDisplayId() + " Callers=" + Debug.getCallers(4));
}-->
DisplayContent.findFocusedWindowIfNeeded -->
DisplayContent.DisplayContent -->
DisplayContent.forAllWindows -->
从top到bottom开始遍历所有存在的window,首先需要满足有符合条件的window的canReceiveKeys为true即处于可接收输入key事件,再存在如下判断条件。
mFocusedApp为null,则将top的window置为focus window。
focusedApp.windowsAreFocusable为false,则将top的window置为focus window
focusedApp.compareTo(activity) > 0,focusedApp界面和当前的resume显示界面不一致,则焦点置为null
找到新的焦点窗口 mTmpWindow= w
这样正常状态下在findFocusedWindowIfNeeded中就获取一个有焦点的窗口