performSurfacePlacement和updateFocusedWindow流程

正常的流程应用的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中就获取一个有焦点的窗口

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值