Bootstrap

Android5.1红外及蓝牙遥控器适配流程

Android5.1红外及蓝牙遥控器适配流程

1.前置工作

1.1 getevent -l

无论是蓝牙遥控器还是红外遥控器,都需要确定其使用的kl (KeyLayoutFile)文件。在安卓shell 环境执行命令确认kl 文件:getevent -l (getevent -v)。

以下三行表示按键(HID键值码 0x0024)被按下

    /dev/input/event3: EV_MSC       MSC_SCAN             00070024
     
    /dev/input/event3: EV_KEY       KEY_UP               DOWN
     
    /dev/input/event3: EV_SYN       SYN_REPORT           00000000

以下三行表示按键(HID键值码 0x0024)被释放

    /dev/input/event3: EV_MSC       MSC_SCAN             00070024
     
    /dev/input/event3: EV_KEY       KEY_UP               UP
     
    /dev/input/event3: EV_SYN       SYN_REPORT           00000000

    EV_SYN: 用作分隔事件的标记。 事件可以在时间或空间上分开,例如使用多点触控协议。
    EV_KEY: 用于描述键盘,按钮或其他类似键的设备的状态更改。
    EV_MSC: 用于描述不适合其他类型的杂项输入数据。


1.2 dumpsys input

在安卓shell 环境下执行 dumpsys input ,可以根据所连接的遥控器的名称找到遥控器对应的kl文件。

这里所用到的Android层映射文件为/system/usr/keylayout/Generic.kl(各个项目使用的kl文件可能不一样,Generic.kl为默认的;.kl文件代码路径:/framework/base/data/keyboards;盒子路径:/system/usr/keylayout)。

如果hid-input.c中获取到的值为unk,从Generic.kl(项目具体使用的kl文件)下找到对应功能的值,填到hid-input.c中对应的位置。

2. 红外遥控器适配

2.1 适配流程

按下遥控器的一个按键后,在系统中的逻辑过程:遥控器的物理键值——>Linux的标准键值——>自定义的字符串——>定义这个字符串——>android标准键值——>android键值上报——>所有上报表中键值判断是否为全局——>(上报成功)。

1)getevent -v 或者dumpsys input 确认设备使用的 kl 文件,该命令显示值代表内核中的值。

该款红外遥控使用 kl 文件名称为 Vendor_0001_Product_0001.kl,矩芯平台上,该配置文件位于 android/frameworks/base/data/keyboards/目录。

2)最终映射到 android 键值层

Android应用层在onKeyUp,onKeyDown 中识别的就是keyCode。android 键值定义文件如下:

android5.1 版 本 及 以 上 :

frameworks/native/include/android/keycodes.h

frameworks/native/include/input/InputEventLabels.h

frameworks/base/core/java/android/view/KeyEvent.java

frameworks/base/core/res/res/values/attrs.xml

android4.4 版 本 :

frameworks/base/include/androidfw/KeycodeLabels.h

frameworks/base/core/java/android/view/KeyEvent.java

frameworks/base/core/res/res/values/attrs.xml

android4.0 版 本 :

frameworks/base/include/ui/KeycodeLabels.h

frameworks/base/core/java/android/view\KeyEvent.java

frameworks/base/core/res/res/values/attrs.xml


总结:getevent -l 显示出来的值为dts中ir_code(遥控器键值)映射的key_code的值,该值要在android/frameworks/base/data/keyboards/Generic.kl中定义一个字符串,这个字符串也要在frameworks/native/include/android/keycodes.h frameworks/native/include/input/InputEventLabels.h frameworks/base/core/java/android/view/KeyEvent.java frameworks/base/core/res/res/values/attrs.xml中声明或定义一个数值。

input keyevent xxx 的值是在frameworks/native/include/android/keycodes.h中定义的。

3. 蓝牙键值适配

3.1 蓝牙遥控器适配流程

Hisi 、Amlogic以及Mstar的蓝牙遥控器是同样的流程。

1)确认各个按键 HID 值。可以找遥控器厂家或者局方咨询。

2)按键 HID 值与 linux 键值之间映射关系。

Hisi:device/hisilicon/bigfish/sdk/…/drivers/hid/hid-input.c

AMLOGIC:common/drivers/hid/hid-input.c

Mstar:platform/android/vendor/mstar/kernel/tegra/drivers/hid/hid-input.c

HID键码值表即为蓝牙键值,其中usage page为键值类型(07代表普通键值、0c代表多媒体键值)、usage ID为蓝牙键值。我们需要根据键值类型来修改hid-input.c。

对于普通类型键值(07),只需要修改hid_keyboard数组相应的值即可,其中数组序号代表蓝牙键值,数组里面的值代表对应的linux键值。

 
hid有256个键值保存在device\hisilicon\bigfish\sdk\source\kernel\linux-3.18.y\drivers\hid\hid-input.c定义的数组中,如下图所示,可以看到hid_keyboard[74] = 102,而在linux_key.h(不是在此处定义的)中键值102对应的按键字符串为KEY_HOME。比如确定键,HID键值类型为0x07,键值为0x28(即40,hid_keyboard数组的第3行第9个),则hid_keyboard[40]的值应该为确定键对应的linux键值。

对于多媒体类型键值(0c),修改在case HID_UP_CONSUMER部分进行添加。以设置键为例,0XF6代表蓝牙键值,KEY_BACK(158)代表对应的linux键值(input.h中定义),因此需要在switch (usage->hid & HID_USAGE)语句中添加case 0x224: map_key_clear(KEY_BACK)。


3)确认设备使用的 kl 文件并修改。

确定遥控器(android:/framework/base/data/keyboards)使用哪一个kl文件,可以通过指令getevent-l或者getevent –v,或者在/system/usr/keylayout通过cat /proc/bus/input/devices,根据Vendor,Product,Version确认该遥控器是哪个event事件。

若对应 vendor 和 product 的 kl 文件不存在,如果要新增 kl 配置文件,新增的 kl 文件要添加到frameworks/base/data/keyboards 目录下,命名规则根据查询到的VendorID 和 ProductID。特殊说明:如果不新增设备对应的 kl 文件的话,系统默认会使用 Generic.kl 进行映射处理(frameworks/base/data/keyboards/Generic.kl), 建议尽量不要改动默认的Generic.kl 文件,以免对其他设备产生影响。

确定好遥控器使用哪个kl文件后,需要检查上一步配置的linux键值是否在该kl文件中配置。如果没有,则需要添加到android键值的映射。

4)最终映射到 android 键值层,同红外遥控器。

下面以返回键和设置键蓝牙适配来详细了解流程。


3.2 单板连上蓝牙遥控器后,按返回键无反应,但是getevent有打印

根据遥控器厂商提供的HID键值表,0x0007对应键盘码区。

遥控器按键    蓝牙键值    Android键值
返回        0x29(07)    4        //括号中的07表示普通键值,对应键盘码区hid_keyboard[256]
设置        0xF6(0C)    176        //括号中的0C表示多媒体键值,对应的是HID_UP_CONSUMER区域

代码路径:kernel/drivers/hid/hid-input.c 0x0029就是第3行第10列,对应为1。
static const unsigned char hid_keyboard[256] = {
          0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
         50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
          4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
         27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
         65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
        105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
         72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
        191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
        115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
        122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
        unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
        unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
        unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
        unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
         29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
        150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
};

再查看蓝牙遥控器连接所用的.kl文件, Generic.kl,发现1对应的是ESCAPE,而能实现back功能对应的为158。

所以,在修改键码前,按遥控器实现的功能为ESCAPE,而不是返回。为了减少内核代码的修改,我们不要将hid-input.c中的1修改为158,而是将 key 1 对应的ESCAPE改为BACK。

当然,不会直接在Generic.kl文件中进行修改,可以将Generic.kl复制一份,并将文件名改为与遥控器VID,PID相对应的名字,例如电信BLE语音遥控器的VID,PID为060a,1000,所以将复制出来的kl文件改名为Vendor_060a_Product_1000.kl。遥控器连接后会自动根据其VID,PID加载对应的kl文件。


3.3 单板连上蓝牙遥控器后,按设置键无反应,且getevent无打印

根据遥控器厂商提供的HID键值表,0x0c对应的是HID_UP_CONSUMER区域

从…/kernel/include/uapi/linux/input.h中查到,设置按键对应的key code为 #define KEY_SETUP    141

在(代码路径:.../ kernel/drivers/hid/hid-input.c)如下图框中添加代码
case 0x0f6: map_key_clear(KEY_SETUP);        break;

烧录内核代码后,再次从串口通过getevent获取操作设置键的打印,如果有打印,检查功能是否正常,如果无打印,请重新检查修改是否正确。


综上,蓝牙遥控器按键值适配简要流程如下:由getevent蓝牙按键打印确认是蓝牙键盘类型(0x7)还是自定义类型(0xC),根据不同的类型修改内核和kl文件。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;