Android2.1 输入设备检测BUG修正

重新运行了2.2版本后,发现我这个研究就是笑话,同样的源码在2.2下非常正常,在2.1下却有这个问题,唯一的想法是使用的LINUX内核引发的问题。

原文:

这些天,在盒子上跑Android2.1的时候,经常发生遥控器不可用的问题。刚开始以为是不小心什么地方修改了2.1的源码导致的,只好修改回去重新编译,运行时现象依然存在。无奈只好想到在源码中追加打印,看什么地方键值传递出问题了。

从网上的资料结合源码发现,在窗口服务启动的时候,会开启一个KeyQ的线程去获取键值加入队列。下图是网上的一个Android输入系统的架构图

Android输入系统

从图上可用看出实际上输入设备的管理在EventHub中,打开EventHub的DEBUG开关,运行程序发现虽然虚拟输入驱动已经加载,但是EventHub却并没有打开设备。多次运行,有时候系统能打开虚拟输入设备,有时候却不能打开设备。抽拔USB鼠标,如果USB鼠标已经插上,则可用打开虚拟设备。拔掉鼠标,有提示设备拔掉,再插上鼠标却没有提示打开设备。于是猜测Android只能在第一次系统初始化的时候会找得到输入设备,初始化完毕后,再加入的设备都找不到。果断把输入设备驱动加载放到系统初始化流程靠前的位置,运行多次,遥控器都能正常使用。

下面从EventHub的源码中分析造成BUG的原因。只看了openPlatformInput和getEvent很快就得出了结论。KeyQ线程调用getEvent函数获取键值,该函数会去检测平台输入有没有初始化,没有则调用openPlatformInput完成初始化。初始化完毕后,采用POLL函数循环监控设备Fd和一个特殊的Fd.这个特殊的Fd就是在openPlatformInput生成的,它就是造成BUG的根源。

 

Inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等。您还可以跟踪活动的源头和目标等细节。具体的使用细节都可以在网上查阅到。该源码的意思是使用mFDs[0].fd监控/dev/input目录下的文件变化,IN_DELETE | IN_CREATE指监控文件的删除和创建。结合getEvent,当/dev/input目录下文件有删除和创建时,从mFDs[0].fd读取事件打开或者删除一个设备。这不是很正确么,有什么问题呢,问题就出在IN_CREATE上,这个监控的是文件的创建,但是通过我的测试发现,插USB鼠标生成的/dev/input/event0和/dev/input/mouse0并不属于文件创建,此时Inotify根本就没有发送文件创建事件,期待获取该事件打开设备的动作当然也不能触发了。修正办法如下:

 

使用IN_MOVE_TO属性,同时在read_notify中修改下事件响应。OK,现在任何时候加载虚拟设备驱动和插拔USB鼠标都没有问题了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章