滑鼠和按鍵在android 上的識別和區別
阿新 • • 發佈:2019-01-06
引子:
拿到一個藍芽遙控器,連上後,按確認(OK)鍵的時候顯示滑鼠。導致遙控器不能正常使用。
測試過程:
1 換此藍芽遙控器在其他產品上,並沒出現滑鼠。(由此richard 幫忙找到rk 程式碼加的東西,導致滑鼠彈出)
2 借另外的藍芽遙控器,在我們現有的遙控器上,也沒出現滑鼠。
3. 確認 OK 鍵的按鍵值(28, 232).分析徐工指出的 rk 的程式碼,發現在 28 和 232 鍵值的時候,應該都會彈出滑鼠。然而,在其他遙控器上也出現了 232 鍵值後,並未彈出滑鼠。
4. 嘗試修改自己的紅外遙控器的驅動。把上報的鍵值改為 28 232 也沒有出現滑鼠。
5. getevent 命令的時候看不到任何不一樣的地方。
分析:
應該是註冊了成了滑鼠。某個按鍵值觸發後就改變為滑鼠。
再分析 frameworks/native/services/inputflinger/EventHub.cpp 和 frameworks/native/services/inputflinger/InputReader.cpp
發現
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask);
ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask);
後
1174 // See if this is a cursor device such as a trackball or mouse.
1175 if (test_bit(BTN_MOUSE, device->keyBitmask)
1176 && test_bit(REL_X, device->relBitmask)
1177 && test_bit(REL_Y, device->relBitmask)) {
1178 device->classes |= INPUT_DEVICE_CLASS_CURSOR;
1179 ALOGV("device->keyBitmask have INPUT_DEVICE_CLASS_CURSOR");
1180 }else
1181 ALOGV("device->keyBitmask not have INPUT_DEVICE_CLASS_CURSOR");
也就是是否顯示滑鼠,是由 relbitmask 的 EV_KEY EV_REL
以及 和 keybitmask 的 BTN_MOUSE確定的。
修改測試,把紅外遙控也改到能顯示出滑鼠:
16 --- a/kernel/drivers/input/evdev.c
17 +++ b/kernel/drivers/input/evdev.c
18 @@ -568,12 +568,11 @@ static int handle_eviocgbit(struct input_dev *dev,
19 static unsigned long keymax_warn_time;
20 unsigned long *bits;
21 int len;
22 -
23 switch (type) {
24
25 case 0: bits = dev->evbit; len = EV_MAX; break;
26 - case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
27 - case EV_REL: bits = dev->relbit; len = REL_MAX; break;
28 + case EV_KEY: bits = dev->keybit; len = KEY_MAX; printk("%s EV_KEY %d\n", dev->name, test_bit(BTN_MOUSE,
bits)); break;
29 + case EV_REL: bits = dev->relbit; len = REL_MAX; printk("%s REL_X %d, REL_Y %d\n", dev->name, test_bit(REL_X,
bits), test_bit(REL_Y, bits)); break; 43 --- a/kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c
44 +++ b/kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c 90 ret = input_register_device(input);
91 if (ret)
92 pr_err("remotectl: register input device err, ret: %d\n", ret);
93 input_set_capability(input, EV_KEY, KEY_WAKEUP);
94 + input_set_capability(input, EV_MSC, 0x4);
95 + input_set_capability(input, EV_REL, 0x2);
96 + input_set_capability(input, EV_REL, REL_X);
97 + input_set_capability(input, EV_REL, REL_Y);
98 device_init_wakeup(&pdev->dev, 1); 3 --- a/kernel/arch/arm/boot/dts/rk3288-box.dts
4 +++ b/kernel/arch/arm/boot/dts/rk3288-box.dts
5 @@ -1003,7 +1003,7 @@
6 ir_key1{
7 rockchip,usercode = <0xf708>;
8 rockchip,key_table =
9 - <0xfd KEY_REPLY>,
10 + <0xfd 0x0110>,
11 <0xe5 KEY_BACK>,
12 <0xbc KEY_UP>,
13 <0xf5 KEY_DOWN>,
經測試,當鍵值是 rk 加的 (28 232) 以及本身的 BTN_LEFT(0x0110) BTN_MIDDLE(0x112) 等都會出現滑鼠和實現滑鼠的功能。(AMOTION_EVENT_BUTTON_PRIMARY ,AMOTION_EVENT_BUTTON_BACK) 結論: 目前這個藍芽滑鼠可以方法有兩個 1. 直接修改 rk 程式碼,把加的 28 232 等鍵值去掉。但是,如果我們要求其改的其他按鍵和現有的(BTN_LEFT等)衝突了,就又會出現滑鼠了。 2 要求遙控器廠家把滑鼠功能去掉。但是對 usb 的,我不知道怎麼改,我有驅動的程式碼是類似: input_set_capability(input, EV_REL, REL_Y); 去掉 EV_REL bit 的 REL_Y(0000) 和 REL_X(0001) ,同時去掉 input_set_capability(input, EV_KEY, BTN_MOUSE); BTN_MOUSE(0x0110) 可以用 getevent看 add device 5: /dev/input/event0
name: "ff680000.pwm"
events:
KEY (0001): 0000 0001 0002 0003 0004 0005 0006 0007
0008 0009 000a 000b 000e 001c 0066 0067
0069 006a 006c 006f 0071 0072 0073 0074
008b 008f 009e 00b7 00b8 00b9 00ba 00d9
00e8 0110 0184 0191 0192
REL (0002): 0000 0001 0002
MSC (0004): 0004
紅色的幾個不存在,就不會有滑鼠了。。
1175 if (test_bit(BTN_MOUSE, device->keyBitmask)
1176 && test_bit(REL_X, device->relBitmask)
1177 && test_bit(REL_Y, device->relBitmask)) {
1178 device->classes |= INPUT_DEVICE_CLASS_CURSOR;
1179 ALOGV("device->keyBitmask have INPUT_DEVICE_CLASS_CURSOR");
1180 }else
1181 ALOGV("device->keyBitmask not have INPUT_DEVICE_CLASS_CURSOR");
18 @@ -568,12 +568,11 @@ static int handle_eviocgbit(struct input_dev *dev,
19 static unsigned long keymax_warn_time;
20 unsigned long *bits;
21 int len;
22 -
23 switch (type) {
24
25 case 0: bits = dev->evbit; len = EV_MAX; break;
26 - case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
27 - case EV_REL: bits = dev->relbit; len = REL_MAX; break;
28 + case EV_KEY: bits = dev->keybit; len = KEY_MAX; printk("%s EV_KEY %d\n", dev->name, test_bit(BTN_MOUSE,
bits)); break;
29 + case EV_REL: bits = dev->relbit; len = REL_MAX; printk("%s REL_X %d, REL_Y %d\n", dev->name, test_bit(REL_X,
bits), test_bit(REL_Y, bits)); break; 43 --- a/kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c
44 +++ b/kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c 90 ret = input_register_device(input);
91 if (ret)
92 pr_err("remotectl: register input device err, ret: %d\n", ret);
93 input_set_capability(input, EV_KEY, KEY_WAKEUP);
94 + input_set_capability(input, EV_MSC, 0x4);
95 + input_set_capability(input, EV_REL, 0x2);
96 + input_set_capability(input, EV_REL, REL_X);
97 + input_set_capability(input, EV_REL, REL_Y);
98 device_init_wakeup(&pdev->dev, 1); 3 --- a/kernel/arch/arm/boot/dts/rk3288-box.dts
4 +++ b/kernel/arch/arm/boot/dts/rk3288-box.dts
5 @@ -1003,7 +1003,7 @@
6 ir_key1{
7 rockchip,usercode = <0xf708>;
8 rockchip,key_table =
9 - <0xfd KEY_REPLY>,
10 + <0xfd 0x0110>,
11 <0xe5 KEY_BACK>,
12 <0xbc KEY_UP>,
13 <0xf5 KEY_DOWN>,
經測試,當鍵值是 rk 加的 (28 232) 以及本身的 BTN_LEFT(0x0110) BTN_MIDDLE(0x112) 等都會出現滑鼠和實現滑鼠的功能。(AMOTION_EVENT_BUTTON_PRIMARY ,AMOTION_EVENT_BUTTON_BACK) 結論: 目前這個藍芽滑鼠可以方法有兩個 1. 直接修改 rk 程式碼,把加的 28 232 等鍵值去掉。但是,如果我們要求其改的其他按鍵和現有的(BTN_LEFT等)衝突了,就又會出現滑鼠了。 2 要求遙控器廠家把滑鼠功能去掉。但是對 usb 的,我不知道怎麼改,我有驅動的程式碼是類似: input_set_capability(input, EV_REL, REL_Y); 去掉 EV_REL bit 的 REL_Y(0000) 和 REL_X(0001) ,同時去掉 input_set_capability(input, EV_KEY, BTN_MOUSE); BTN_MOUSE(0x0110) 可以用 getevent看 add device 5: /dev/input/event0
name: "ff680000.pwm"
events:
KEY (0001): 0000 0001 0002 0003 0004 0005 0006 0007
0008 0009 000a 000b 000e 001c 0066 0067
0069 006a 006c 006f 0071 0072 0073 0074
008b 008f 009e 00b7 00b8 00b9 00ba 00d9
00e8 0110 0184 0191 0192
REL (0002): 0000 0001 0002
MSC (0004): 0004
紅色的幾個不存在,就不會有滑鼠了。。