一、Android按键流程
1.首先我们需要搞清的是当我们按下按键时发生了什么(如下图):

根据如上流程图,从下往上看,当我们按键时,
1)linux内核通过扫码,将硬件上按键按下电压变换为数字电压并映射到数组下标
2)通过数组关系转化将按键映射到内核中预定义的键值
3)linux内核上报给上层的就是这个整型值(内核扫描标准值体现在kernel/uapi/linux/input.h)
如下input.h代码部分截图:

linux内核上报按键值后又会发生什么呢,这里就要讲到Android kl文件了。Android kl文件是标准linux与android的键值映射文件,kl文件可以有很多个,我们怎么知道当前设备用的是哪个kl文件呢?
可以通过如下两个命令查看:
1.dumpsys input
2.cat /proc/bus/input/devices (输入命令后如下截图)

可以查看设备当前所使用的kl文件,kl文件代码部分如下:

key后面的数字就是kernel上报的按键码,后面的字符标签就是该按键码对应的android中的按键标签,当用户按下按键后,kernel会上报对应按键的按键码,然后上层根据正确的kl文件中的对应关系,将按键对应到上层的按键标签上来。
按键标签其实对应的也是一个按键码。与kernel上报的按键码不同,按键标签所对应的按键码就是我们在上层代码逻辑中使用的按键码。我们可以在如下文件中看到:
/frameworks/native/include/input/InputEventLabels.h
/frameworks/native/include/android/Keycodes.h
其中,在InputEventLabels.h中,这里通过宏定义将标签字符与上层按键码对应起来,上层按键码又是在Keycodes.h中枚举的,如下代码截图片段。


这样的话就将物理按键、kernel、上层之间的映射关系确定了,点击某个物理按键,上层就知道哪个按键被点击了。
上面是Android实体按键的流程
下面介绍的是Amlogic平台配置遥控器的流程
二、遥控器配置及其解析流程
代码位置:/device/customer/xxxx/init.amlogic.rc
/device/customer/xxxx/device.mk


编译时,将ir_active.sh拷贝到system/bin下,在init.rc中,通过service ir_active /system/bin/ir_active.sh在开机阶段将ir_active.sh中的配置通过ioctl赋值到ir驱动的变量中(用户控件->内核空间)
代码位置: /device/customer/xxxx/files/ir_active.sh

ir_active.sh中具体通过remotecfg将遥控器的配置赋值到ir驱动变量中,
三、红外驱动
remotecfg程序代码目录:
/vendor/amlogic/frameworks/services/remoteconf/
Linux irremote driver将依照红外驱动配置文件,将红外键值ircode映射为 Linux标准键盘扫描码scancode。这个过程即将红外遥控器的按键事件转换为Linux的标准input event。
红外驱动配置文件/factory/customer/rc_user_cnc.ini,/factory/customer/rc_user_cnc.cfg
标准键盘扫描码/kernel/uapi/linux/input.h中

其中custom_code为遥控器头码,用以区分各种遥控器的
key_begin:按键映射开始
key_end:按键映射结束
0x1b 113 //#MUTE //0x1b为红外键值 113标准扫描码
(PS:多个键值可以对应一个扫描码)
Android层:
Windows manager从irremote driver中读出key event,再通过/system/usr/keylayout/xxx.kl文件,将标准input设备的scan code映射为Andriod API按键KEYCODE字符串。最终scancode和keycode被window manager发送到应用程序,被相关View消化处理
以Aml 920平台一个设备为例:使用的是system/usr/keylayout/Vendor_0001_Product_0001.kl(dumpsys input),该kl文件将scancode映射为Android API识别的KEYCODE字串.
/device/custom/xxxx/files/Vendor_0001_Product_0001.kl

其中113为scancode VOLUME_MUTE为Android API按键keycode字符串
四、Android层新增按键
代码位置:
1:/frameworks/native/include/input/InputEventLabels.h
2:/frameworks/native/include/android/keycodes.h
3:/frameworks/base/core/java/android/view/KeyEvent.java
若是要新增按键,还要修改如上文件
a).在InputEventLabels.h中KEYCODES[]数组后面顺序添加。
例如: ...
{ "RED", 141},
{ NULL, 0 }
注意:1.追加的按键须在末行的{ NULL, 0 }前面,该文件会将这些字符串转换成数值、键值,传送到KeyEvent.java中
2. RED后面的数值,需要与客户协商,客户APK应该专门处理这个新建的141值。
3.141的值不应与其他keycode重复,建议新增键的取值依照上文的值,依次累加。
4.在frameworks/native/include/android/keycodes.h中追加:AKEYCODE_RED = 141
5.在frameworks/base/core/java/android/view/KeyEvent.java中添加:public static final int KEYCODE_RED = 141;
其中KeyEvent.java中添加的数值要与上面keycodes.h中的数值保持一致,如果是在最后面追加的话,需要注意修改LAST_KEYCODE的值为最后一个。
网友评论