Input ANR處理流程

ANR時間區別即是指當前此次的事件dispatch過程當中執行findFocusedWindowTargetsLocked()方法到下一次執行resetANRTimeoutsLocked()的時間區間. 如下5個時機會reset. 都位於InputDispatcher.cpp文件:shell

  • resetAndDropEverythingLocked
  • releasePendingEventLocked
  • setFocusedApplication
  • dispatchOnceInnerLocked
  • setInputDispatchMode

簡單來講, 上面方法主要是對應如下4個場景,會有機會執行resetANRTimeoutsLocked重置timeout時間:app

  • 解凍屏幕, 系統開/關機的時刻點 (thawInputDispatchingLw, setEventDispatchingLw)
  • wms聚焦app的改變 (WMS.setFocusedApp, WMS.removeAppToken)
  • 設置input filter的過程 (IMS.setInputFilter)
  • 再次分發事件的過程(dispatchOnceInnerLocked)

當InputDispatcher線程 findFocusedWindowTargetsLocked()過程調用到handleTargetsNotReadyLocked,且知足超時5s的狀況則會調用onANRLocked().spa

經過將InputManagerService加入到Watchdog的monitor隊列,定時監測是否發生死鎖. 整個監測過涉及EventHub, InputReader, InputDispatcher, InputManagerService的死鎖監測. 監測的原理很簡單,經過嘗試獲取鎖並釋放鎖的方式.線程

可經過adb shell dumpsys input來查看手機當前的input狀態, 輸出內容分別爲EventHub.dump(), InputReader.dump(),InputDispatcher.dump()這3類,另外若是發生過input ANR,那麼也會輸出上一個ANR的狀態.code

其中mPendingEvent表明的當下正在處理的事件.隊列

ANR分類

由小節[3.5] InputMonitor.notifyANR完成, 當發生ANR時system log中會出現如下信息, 而且TAG=WindowManager:事件

Input event dispatching timed out xxx. Reason: + reason, 其中xxx取值:rem

  • 窗口類型: sending to windowState.mAttrs.getTitle()
  • 應用類型: sending to application appWindowToken.stringName
  • 其餘類型: 則爲空.

至於Reason主要有如下類型:get

5.1.1 reason類型

由checkWindowReadyForMoreInputLocked完成, ANR reason主要有如下幾類:input

  1. 無窗口, 有應用:Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.
  2. 窗口暫停: Waiting because the [targetType] window is paused.
  3. 窗口未鏈接: Waiting because the [targetType] window’s input channel is not registered with the input dispatcher. The window may be in the process of being removed.
  4. 窗口鏈接已死亡:Waiting because the [targetType] window’s input connection is [Connection.Status]. The window may be in the process of being removed.
  5. 窗口鏈接已滿:Waiting because the [targetType] window’s input channel is full. Outbound queue length: [outboundQueue長度]. Wait queue length: [waitQueue長度].
  6. 按鍵事件,輸出隊列或事件等待隊列不爲空:Waiting to send key event because the [targetType] window has not finished processing all of the input events that were previously delivered to it. Outbound queue length: [outboundQueue長度]. Wait queue length: [waitQueue長度].
  7. 非按鍵事件,事件等待隊列不爲空且頭事件分發超時500ms:Waiting to send non-key event because the [targetType] window has not finished processing certain input events that were delivered to it over 500ms ago. Wait queue length: [waitQueue長度]. Wait queue head age: [等待時長].

其中

  • targetType: 取值爲」focused」或者」touched」
  • Connection.Status: 取值爲」NORMAL」,」BROKEN」,」ZOMBIE」

另外, findFocusedWindowTargetsLocked, findTouchedWindowTargetsLocked這兩個方法中能夠經過實現 updateDispatchStatisticsLocked()來分析anr問題.

drop事件分類

由dropInboundEventLocked完成,輸出事件丟棄的緣由:

  1. DROP_REASON_POLICY: 「inbound event was dropped because the policy consumed it」;
  2. DROP_REASON_DISABLED: 「inbound event was dropped because input dispatch is disabled」;
  3. DROP_REASON_APP_SWITCH: 「inbound event was dropped because of pending overdue app switch」;
  4. DROP_REASON_BLOCKED: 「inbound event was dropped because the current application is not responding and the user has started interacting with a different application」」;
  5. DROP_REASON_STALE: 「inbound event was dropped because it is stale」;

其餘:

  • doDispatchCycleFinishedLockedInterruptible的過程, 會記錄分發時間超過2s的事件,
  • findFocusedWindowTargetsLocked的過程, 能夠統計等待時長信息.
相關文章
相關標籤/搜索