Android 中 KeyEvent keycode 配置 及 转换原理

一、Kernel 修改

1. 修改 input-event-codes.h 添加keycode 定义 (16 进制)

实话说,这个文件具体作用没啥,只是一个头文件定义,起到让程序员更好看代码 和 管理代码的作用,并无其他实质作用。

如果代码没写那么规范,它写在 c 文件中也是可以的。
甚至可以不定义这个 ,直接在上报 键值的地方 用 数字,这样也行,就是不规范而已。

@ input.h

@ \kernel\msm-3.18\include\uapi\linux\input-event-codes.h  
// 

#define KEY_CAMERA_FOCUS	0x210	 // 注意是 16 进制
#define KEY_WPS_BUTTON		0x211	/* WiFi Protected Setup key */ 

2. 修改 msm8909-mtp.dtsi 添加上报 (16 进制)

msm8909-mtp.dtsi

	gpio_keys {
		compatible = "gpio-keys";
		input-name = "gpio-keys";
		pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
		pinctrl-0 = <&gpio_key_active>;
		pinctrl-1 = <&gpio_key_suspend>;

		camera_focus {
			label = "camera_focus";
			gpios = <&msm_gpio 91 0x1>;
			linux,input-type = <1>;
			linux,code = <0x210>;   // 注意是 16 进制
			gpio-key,wakeup;
			debounce-interval = <15>;
		};
	}

二、Android 代码修改

1. 修改 input-event-codes.h (16 进制)

和 Kernel 中定义一样,注意是 16 进制

@\bionic\libc\kernel\uapi\linux\input-event-codes.h

#define KEY_CAMERA_FOCUS	0x210	// 注意是 16 进制
#define KEY_WPS_BUTTON		0x211	/* WiFi Protected Setup key */

2. 修改 kl 文件(十进制)

注意: 此处是配置 十进制。

@\frameworks\base\data\keyboards\Generic.kl
key 528   FOCUS

@ \device\qcom\msm8909\gpio-keys.kl
key 528   FOCUS				

如何确认生效?

修改整编后,看 \out\target\product\msm8937_32go\system\usr\keylayout\gpio-keys.kl 和 Generic.kl 这个 目录下有没有对应的修改。


3. native 层 keycodes 重映射(十进制)

此处主要功能是在 native 层对 input 输入子系统上报的值进行重映射。

3.1 修改 keycodes.h
@ \frameworks\native\include\android\keycodes.h

/**
 * Key codes.
 */
enum {
    AKEYCODE_UNKNOWN         = 0,
    AKEYCODE_SOFT_LEFT       = 1,
    ... 
    AKEYCODE_NUM             = 78,
    /** Headset Hook key.
     * Used to hang up calls and stop media. */
    AKEYCODE_HEADSETHOOK     = 79,
    /** Camera Focus key.
     * Used to focus the camera. */
    AKEYCODE_FOCUS           = 80,
    /** '+' key. */
    AKEYCODE_PLUS            = 81,
    /** Menu key. */
    AKEYCODE_MENU            = 82,
}
3.2 修改 InputEventLabels.h

此时在 InputEventLabels.h 的KEYCODES[] 索引中 通过DEFINE_KEYCODE(FOCUS) ,将 kl 中换 FOCUS 开始绑定在一起了。
你可以发现,其实他的索引,就刚好是 AKEYCODE_FOCUS 的值 ,也就是 80。

@\frameworks\native\include\input\InputEventLabels.h

static const InputEventLabel KEYCODES[] = {
	DEFINE_KEYCODE(UNKNOWN),
    DEFINE_KEYCODE(SOFT_LEFT),
	... 
    DEFINE_KEYCODE(NUM),
    DEFINE_KEYCODE(HEADSETHOOK),
    DEFINE_KEYCODE(FOCUS),   // *Camera* focus
    DEFINE_KEYCODE(PLUS),
    DEFINE_KEYCODE(MENU),
}

struct InputEventLabel {
    const char *literal;	// 字符串
    int value;				// keycode 键值
};

// 宏定义如下:
#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }


解析: DEFINE_KEYCODE(FOCUS) 的意思为生成这样一个结构体
DEFINE_KEYCODE(key) { 528, AKEYCODE_FOCUS }

这样,就相当于,定义一个名字:  “FOCUS” <---> AKEYCODE_FOCUS (80static const InputEventLabel KEYCODES[] = {
	{"FOCUS", 80}	
}
此入的 "FOCUS" 就是 在gpio-keys.kl中定义的。

4. 修改 attrs.xml(十进制)

其实,getevent 之所显示 KEYCODE_FOCUS 就是在这里定义的。
将 前面换 AKEYCODE_FOCUS = 80 索引号,转的换为 name = “KEYCODE_FOCUS”

注意: getevent -l 中显示的名字就是从这获取的。

@ \frameworks\base\core\res\res\values\attrs.xml

    <!-- This enum provides the same keycode values as can be found in
        {@link android.view.KeyEvent}. -->
    <attr name="keycode">
        <enum name="KEYCODE_UNKNOWN" value="0" />
        <enum name="KEYCODE_SOFT_LEFT" value="1" />
        ... 
		<enum name="KEYCODE_NUM" value="78" />
        <enum name="KEYCODE_HEADSETHOOK" value="79" />
        <enum name="KEYCODE_FOCUS" value="80" />
        <enum name="KEYCODE_PLUS" value="81" />
        <enum name="KEYCODE_MENU" value="82" />

5. 修改 KeyEvent.java

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

public class KeyEvent extends InputEvent implements Parcelable {
    public static final int KEYCODE_UNKNOWN         = 0;
    public static final int KEYCODE_SOFT_LEFT       = 1;
    ... 
    public static final int KEYCODE_NUM             = 78;
    public static final int KEYCODE_HEADSETHOOK     = 79;
    /** Key code constant: Camera Focus key.
     * Used to focus the camera. */
    public static final int KEYCODE_FOCUS           = 80;   // *Camera* focus
    public static final int KEYCODE_PLUS            = 81;
    public static final int KEYCODE_MENU            = 82;

上层监听的其实并不是 keycode = 528 ,而是该keycode=528 在kl 中的别名 FOCUS 在 KEYCODES[ ] 数组中的索引号。
因此,在 上层定义 KEYCODE_FOCUS = 80 ,它就是用于监听的,因此上层监听的就是 80。


三、小结

可以这样理解:

  1. 在驱动层定义 上报的是0x210
    #define KEY_CAMERA_FOCUS 0x210 // 注意是 16 进制

  2. 通过 gpio-keys.kl 文件 将驱动的 528(0x210) 和 FOCUS 这个名字绑定在一起
    key 528 FOCUS

  3. 在native 层将定义 AKEYCODE_FOCUS = 80
    注意,后面 AKEYCODE_FOCUS 这个名 和 前面 kl 中的FOCUS 有没有很像,后面有关联的。

  4. 在 InputEventLabels.h 通过 DEFINE_KEYCODE(FOCUS) 和 kl 文件中的FOCUS 绑定在一起了,其数组索引号就是 AKEYCODE_FOCUS = 80
    这样,会生成一个数组,{“FOCUS”, 80} ,通过查 kl 的 获得的 FOCUS 就是用于此处的,
    当输入子系统中,接收到键值时,通过这个数组,就能知道它的索引号。

  5. 在attrs.xml ,将索引号 和 name 绑定在一起,显示对应的名字

  6. 修改 KeyEvent.java,最终,上层接收到的键值,其实是它的索引号,也就是80

这样,就完成了,键值转换,

驱动上报 0x210,在native 层查表得到它的索引号,上层获得 和 使用 的就是它的索引号,包括,显示keyevent名字

整个转换过程为:

(kernel)0x210 
	------>  528 
		------>(gpio-keys.kl) FOCUS 
			------> (InputEventLabels.h)KEYCODES[]={"FOCUS", 80}
				------> 80
				|	如果要处理键值的话
				|	------>(KeyEvent.java) public static final int KEYCODE_FOCUS = 80;
				|		------> onXXXXevent(){  case KEYCODE_FOCUS: xxxxxxx; break; }
				|	
				|	如果是 getevent -l 显示名字的话
				|	------> (attrs.xml)  <enum name="KEYCODE_FOCUS" value="80" />
						------> 最终显示 "KEYCODE_FOCUS"

Date: 2019/09/25 - 21:25
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馋喵星人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值