在上一节中,我们知道Reader线程主要是通过EventHub读取事件,他的核心类就是EventHub这个类,我们在来回顾一下EventHub有哪些内容。 Read线程核心类EventHub 创建一个mEventHub,他负责的是多个设备,其中存在成员KeyedVector mDevices,存放的都是输入设备的相关信息,int32_t为设备的编号,Device*为表示一个设备的指针。我们查看一下Device中包含了那些东西,其中有fd,记录我们打开设备的文件描述符,还有一些标志信息,我们称为identify,其中包括了name,bus,vid,pid等。Device中还包括了一些映射信息,暂时没有了解过,后续为大家讲解,框图如下: 其中EventHub.cpp中EventHub简单包含成员如下:
前面已经提高,其中的mDevice用来表示多个输入设备,int32_t,代表编号,Device代表输入设备,从这里我们可以想象得到,在EventHub中open打开一个设备的时候,肯定会构造一个Device结构体,其简单结构如下:
可以看到,其中存在成员identifier,其简单结构如下:
name代表输入设备的名字,bus代表他是是不是usb设备或者其他的设备,以及厂家VID,PID等,这行信息都是通过ioctrl访问硬件信息得来的,以后会根据这些信息打开某些配置文件,那么他存在哪些配置文件呢?
他存在3中配置文件: 1.IDC:input Device config 2.keylayout:键盘布局 3.kcm:key character map(键盘映射) 其中的3有什么作用呢?比如,美国人与中国人按下同一个按键,中国现实的可能是一,美国显示的可能是A。在比如,我们在键盘上想按下*,需要shift+8键,但是我们在手机上直接按*键就可以了,那么在android系统中,是怎么对其进行处理的呢?我们从按键的源头开始讲解: 在上图,输入驱动发送一个KEY_1(发送按键)其宏定义如下:
#define KEY_1 2
我们在查看android系统系统中,对于KEY_1的定义:
AKEYCODE_1 = 8,
可以明显看到驱动底层和android系统的是不一样的,andriod系统在从驱动采集到2时,还需要把他转换成8,那么他们转换的时候涉及一个文件,这个文件就是keylayout文件。
那么大家肯定有一个疑问,android系统为什么不直接使用驱动提供的值,而是要去再进行一次转换呢?为了就是把驱动程序和android系统进行分离,驱动的更改不对android上层产生影响。在中间引入一个配置文件,当你的驱动修改时,只需要修改一下配置文件就可以了。
对于android系统的输入设备,其使用哪个配置文件,他是有一套规则的(keylayout), 如果提供了pid,vid他们就是使用1,2路径的配置文件,如果没有就继续往下查找,配置和输入设备name一样的设备文件,这样逐渐在上图的几个路径中进行查找。
下面是.kcm:key character map(键盘映射)配置文件的查找路径: 查看system/usr/keylayout/Generic.kl文件,可以看到如下:
key B {
label: 'B' //打印在按键上的文字,仅仅是提示作用
base: 'b' //如果没有其他的按键(shift,ctrl等)同时按下,这对应'b'
shift, capslock: 'B'//如果按下capslock再加B键,这对应为'B'
}
其中key B表示按键B(AKETYCODE_B),内部详细已经注释。 所以这个按键决定了,当我们按下的时候会得到什么字符。
小节结语现在我们对上述的中配置文件进行一下总结: 1.keylaout:只是用来表示驱动上报的scancode对应那一个android按键(AKEYCODE_X),仅仅是表示已经按下了。他对应那一个字符,由Kcm文件决定 2.kcm:用来表示android按键(AKEYCODE_X)对应哪个字符,表示同时按下其他按键之后,对应哪个字符。 下小节讲解,应用程序是怎么去解析这些配置文件的 。