Android Systrace Input

围巾🧣 2024年05月13日 255次浏览

1、input事件对应的trace

image

安卓中一个事件的主要流向要经过几个队列,从系统捕捉分发、准备发给应用 、已发送,再到应用处理

• iq(inboundqueue):⽤来标识inputDispatcher收到的InputReader发送的事件
• oq(outboundqueue):队列中即将发给应用的的事件
• wq(wait queue):已经发给应用,等待应用处理反馈后移除的事件
• ap:pending(App pending input )应用需要处理的事件

下面这张图是一个概览图,以滑动桌面为例 (滑动桌面包括一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件,这些事件和事件流都会在 Systrace 上有所体现,这也是我们分析 Systrace 的一个重要的切入点),主要牵扯到的模块是 SystemServer 和 App 模块,其中用蓝色标识的是事件的流动信息,红色的是辅助信息。

img

InputReaderInputDispatcher 是跑在 SystemServer 里面的两个 Native 线程,负责读取和分发 Input 事件,我们分析 Systrace 的 Input 事件流,首先是找到这里。下面针对上图中标号进行简单说明

  1. InputReader 负责从 EventHub 里面把 Input 事件读取出来,然后交给 InputDispatcher 进行事件分发
  2. InputDispatcher 在拿到 InputReader 获取的事件之后,对事件进行包装和分发 (也就是发给对应的)
  3. OutboundQueue 里面放的是即将要被派发给对应 AppConnection 的事件
  4. WaitQueue 里面记录的是已经派发给 AppConnection 但是 App 还在处理没有返回处理成功的事件
  5. PendingInputEventQueue 里面记录的是 App 需要处理的 Input 事件,这里可以看到已经到了应用进程
  6. deliverInputEvent 标识 App UI Thread 被 Input 事件唤醒
  7. InputResponse 标识 Input 事件区域,这里可以看到一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件的处理阶段都被算到了这里
  8. App 响应 Input 事件 : 这里是滑动然后松手,也就是我们熟悉的桌面滑动的操作,桌面随着手指的滑动更新画面,松手后触发 Fling 继续滑动,从 Systrace 就可以看到整个事件的流程

2、事件响应流程

image-20240513111926815

2.1、触控事件的读取

image-20240513112009151

2.2、分发触控事件

dispatcher-touch

flush:遍历事件queue,将事件进⾏分发
notifyMotion:处理home 按键、声⾳键、锁屏键等。将触控事件放⼊iq队列。唤起线程,进⾏
进⾏⼀次分发。
dispatchOnceInnerLocked :找到对应窗⼝,将事件分给对应窗⼝

2.3、寻找窗口

2.4、触控事件发送到目标窗口

image-20240513113135022

prepareDispatchCycled:获取⽬标窗⼝的连接 
prepareDispatchCycleLocked:会检测⼀下链接的状态,将事件放⼊准备给⽬标窗⼝的发送的事
件队列。 
startDispatchCycleLocked:分发事件,发送后将outBundleQueue 队列中移除该事件。 
publishMotionEvent:构建InputMessage,调⽤成员变量InputChannel的sendMessage⽅法 
发送input事件,

2.5、App端监听

app-dispatcher

setView:创建inputChanel,通过bind调⽤传给WMS,创建WindowInputEventReceiver对象,并
将inputChannel 和主线程looper传⼊。 

nativeInit:将java层的inputChannel 和messageQueue转成native 层对应的inputChannel 和
messageQueue 

setFdEvents:将inputChannel 中client 端socket的fd 传⼊looper,收到事件会回调handleEvent 

consumeEvents 处理 输⼊事件,回调java 层的dispatchInputEvent,然后回调onInputEvent 

2.6、UI线程对触控事件的分发处理

image-20240513143957789

enqueueInputEvent: 将事件放⼊ aq:pending 队列  

doProcessInputEvents:从aq:pending 队列中头节点进⾏分发  

deliverInputEvent:处理⼀些按键、输⼊法事件,匹配相应的InputState,并调⽤InputStage的deliver⽅法

deliver:处理⼀些flag,以及判断事件是否该被抛弃  

onProcess:将按键事件和触摸事件分开处理,调⽤processPointEvent  处理view  的触摸事件  

processPointEvent:调⽤DecorView 的 dispatchPointerEvent,dispatchPointerEvent调⽤dispatchTouchEvent