这段时间,公司在做新的蓝牙遥控器,但在做的过程中,发现以前的RF遥控器空鼠的模式切换是OK的,但蓝牙遥控器,空鼠可以用,却不能实现空鼠和按键模式的切换。
查看设备节点发现
蓝牙遥控器的设备节点
6: BRCM REMOTE
Classes:0x8000000b
Path: /dev/input/event7
Descriptor:4a8adb8b60cce64d7f1b05432f2a5f558096dc81
Location:
UniqueId:
Identifier: bus=0x0005, vendor=0x000f,product=0x3412, version=0x0000
KeyLayoutFile:/system/usr/keylayout/Generic.kl
KeyCharacterMapFile:/system/usr/keychars/Generic.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay:false
7 RF_REMOTE
Classes: 0x80000143
Path: /dev/input/event5
Descriptor:c1702cbf17ef2754c2e22482159cfb73ce5983a8
Location: usb-NT726681-1.3/input5
UniqueId:
Identifier: bus=0x0003,vendor=0x1d5a, product=0xc3b3, version=0x0101
KeyLayoutFile:/system/usr/keylayout/Generic.kl
KeyCharacterMapFile:/system/usr/keychars/Generic.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay:false
检查后发现在处理模式切换数据之前,在InputReader.cpp中有对设备类型的判断和过滤:
if(SENSOR_MOUSE_ID != deviceId && IR_RC_ID != deviceId&& (classes & INPUT_DEVICE_CLASS_CURSOR))
不同的地方在classes 这个变量,经过跟踪INPUT_DEVICE_CLASS_CURSOR的含义知道classes这个变量存储的是标示设备类型的信息,设备类型的具体定义是在
/framework/base/services/input/EventHub.h中。
EventHub.h
/*
* Input device classes.
*/
enum {
/* The input device is a keyboard or has buttons. */
INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001,
/* The input device is an alpha-numeric keyboard (not just a dial pad). */
INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002,
/* The input device is a touchscreen or a touchpad (either single-touch or multi-touch). */
INPUT_DEVICE_CLASS_TOUCH = 0x00000004,
/* The input device is a cursor device such as a trackball or mouse. */
INPUT_DEVICE_CLASS_CURSOR = 0x00000008,
/* The input device is a multi-touch touchscreen. */
INPUT_DEVICE_CLASS_TOUCH_MT = 0x00000010,
/* The input device is a directional pad (implies keyboard, has DPAD keys). */
INPUT_DEVICE_CLASS_DPAD = 0x00000020,
/* The input device is a gamepad (implies keyboard, has BUTTON keys). */
INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040,
/* The input device has switches. */
INPUT_DEVICE_CLASS_SWITCH = 0x00000080,
/* The input device is a joystick (implies gamepad, has joystick absolute axes). */
INPUT_DEVICE_CLASS_JOYSTICK = 0x00000100,
/* The input device has a vibrator (supports FF_RUMBLE). */
INPUT_DEVICE_CLASS_VIBRATOR = 0x00000200,
/* The input device is virtual (not a real device, not part of UI configuration). */
INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000,
/* The input device is external (not built-in). */
INPUT_DEVICE_CLASS_EXTERNAL = 0x80000000,
};
0x80000143表示RF遥控器是拓展的INPUT_DEVICE_CLASS_ALPHAKEY和INPUT_DEVICE_CLASS_KEYBOARD类型的设备
0x8000000b表示蓝牙遥控器是拓展的INPUT_DEVICE_CLASS_KEYBOARD、INPUT_DEVICE_CLASS_ALPHAKEY和INPUT_DEVICE_CLASS_CURSOR类型的设备
这样的话,对比两款遥控器的Classes值就知道蓝牙遥控器被屏蔽掉了。这也提醒做系统外接设备的驱动程序员需要按标准定义好这个设备类型。
按理说两者都是CURSOR设备,但可能因为CURSOR数据都是交给第三方去做算法处理,按键通过自己的设备节点上报,但空鼠数据其实是通过一个节点上报给第三方算法库处理完了之后,再注入到另一个设备节点上报到Android系统的。所以这个地方对类型理解有差异,RF遥控器开发人员认为这不是鼠标设备,导致的两个classes定义不一样。
合理的修改方式是:
两款遥控器统一classes值,然后在InputReader中作统一过滤和处理,当然最后是修改蓝牙遥控器的Classes的设备属性了。