InputManagerService浅析

概述

InputManagerService构造时会构造naive的binder server inputManager。此处会创建inputReader和inputDispatcher两条死循环线程。
inputReader利用inotify机制监听/dev/input下的设备节点增删(最终也是 通过将inotify创建的fd挂到epoll下实现的),获取到新增的节点后,利用epoll监听这些设备节点的rawEvent。
监听到这些rawEvent后会通过xxxMapper将其加工为xxxArgs,再转发给监听者inputDispatcher。
inputDispatcher收到后只是做完简单的事件有效性判断后就往mInboundQueue中塞。
inputDispatcher线程就是循环读取mInboundQueue看是否有数据,有数据则开始分发。分发时先找到事件可以派发的窗口,该过程会涉及anr的判断,再将事件塞到connection.outboundqueue中,再通过socket传给app,再将事件塞到waitQueue中,等app处理完事件回调过来再将waitQueue中的事件删除。

代码分析的入口在InputManagerService#start


Image.png

一些重要的类和概念

InputReader
https://blog.csdn.net/zhzhangnews/article/details/91490097

InputDispatcher
https://blog.csdn.net/zhzhangnews/article/details/106795348

InputDispatcher的实现主要涉及3个Queue: 1. InboundQueue: 这个队列里面存储的是从InputReader送来到输入事件 2. OutboundQueue:这个队列里面存储的是即将要发送给应用的输入事件 3. WaitQueue:这个队列里面存储的是已经发给应用的事件,但应用还未处理完成。(OutboundQueue和WaitQueue在存在于Connection中)

InputChannel:本质上是一对SocketPair


image.png

ACTION_CANCEL

case1:

viewGroup中有一个btn,在viewGroup中拦截第一次move事件。btn会收到一个CANCEL事件且不会收到后续事件.

如果某一个子View处理了Down事件(此时 mFirstTouchTarget不为null),那么随之而来的Move和Up事件也会交给它处理。但是交给它处理之前,父View还是可以拦截事件的,如果拦截了事件,那么子View就会收到一个Cancel事件,并且不会收到后续的Move和Up事件

https://blog.csdn.net/cufelsd/article/details/89471402

case2:

正在往window1不断派发事件如MOVE事件,此时按home键,window1会受到CANCEL事件。

原因:当焦点窗口变化时surfaceFlinger会调用到InputDispatcher::setInputWindowsLocked

Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容