Android系统–输入系统(九)Reader线程_核心类及配置文件
1. Reader线程核心类–EventHub
1.1 Reader线程核心结构体
-
实例化对象:mEventHub–表示多个输入设备,里面有数组mPendingEventItems存储多个设备
struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS]; -
mDevice–vector,用来表示记录多个输入设备
KeyedVector<int32_t, Device*> mDevices; //int32_t表示编号,Device*表示输入设备
1.2 取出输入设备
-
编号
-
Device*
-
设备描述符fd
-
标志信息identify
-
name : String8
-
bus : uint16_t
-
vendor : uint16_t
-
product : uint16_t
-
version : uint16_t
-
-
映射信息
-
struct Device { Device* next; int fd; // may be -1 if device is virtual const int32_t id; const String8 path; const InputDeviceIdentifier identifier; uint32_t classes; uint8_t keyBitmask[(KEY_MAX + 1) / 8]; uint8_t absBitmask[(ABS_MAX + 1) / 8]; uint8_t relBitmask[(REL_MAX + 1) / 8]; uint8_t swBitmask[(SW_MAX + 1) / 8]; uint8_t ledBitmask[(LED_MAX + 1) / 8]; uint8_t ffBitmask[(FF_MAX + 1) / 8]; uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8]; String8 configurationFile; PropertyMap* configuration; VirtualKeyMap* virtualKeyMap; KeyMap keyMap; sp<KeyCharacterMap> overlayKeyMap; sp<KeyCharacterMap> combinedKeyMap; bool ffEffectPlaying; int16_t ffEffectId; // initially -1 };
1.3 打开配置文件
-
根据编号和Device*找到该输入设备
-
打开一个输入设备结构体时,需要构建一个device结构体
-
根据标志信息打开三种配置文件
-
IDC:input device configuration
-
keylayout
-
KCM:key charactor map
-
2. 详解配置文件
2.1 引入
对于Android系统输入,分为Android输入系统和Linux内核两层,Linux内核提供输入设备驱动程序,主要负责上报输入事件。
输入事件
-
EV_KEY
-
code–KEY_1(2)
-
value
2.2 引入keylayout
Android系统中用AKEYCODE_1(8)来表示内核中KEY_1(2),其中必定涉及转化文件,即.kl文件(keylayout)
(1)转化的原因:为了使得内核的变化不影响系统层键值的改变。
(2)keylayout原则:
Key layout files are located by USB vendor, product (and optionally version) id or by input device name. The following paths are consulted in order:/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl/system/usr/keylayout/DEVICE_NAME.kl/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl/data/system/devices/keylayout/DEVICE_NAME.kl/system/usr/keylayout/Generic.kl/data/system/devices/keylayout/Generic.kl
(3)kl文件格式
key 17 W 内核中的code值 Android:AKEYCODE_W
(4)keyout实验(基于Tiny4412)
在Tiny4412开发板操作
-
su
-
mkdir -p /data/system/devices/keylayout/
-
cp /system/usr/keylayout/Generic.kl /data/system/devices/keylayout/InputEmulatorFromLKQ.kl
-
修改 /data/system/devices/keylayout/InputEmulatorFromLKQ.kl
-
添加这2行:
key 227 STAR //SATR代表Android中*键 key 228 POUND //POUND代表Android中#键 -
修改权限:
busybox chmod 777 /data/system/devices -R
-
重启:reboot
-
insmod InputEmulator.ko
-
打开开发板中浏览器,点击文本输入框
-
发送*键
sendevent /dev/input/event5 1 227 1 sendevent /dev/input/event5 1 227 0 sendevent /dev/input/event5 0 0 0 -
发送#键
sendevent /dev/input/event5 1 228 1 sendevent /dev/input/event5 1 228 0 sendevent /dev/input/event5 0 0 0
(5)实验现象:文本输入框出现 *# 字符
(6)实验结论:用来表示驱动上报的scancode对应哪一个android按键(AKEYCODE_x),它对应哪一个字符,由kcm文件决。
2.3 引入kcm
Android输入系统中,当确定Android keycode之后,需要转化为显示在文本框的字符,这其中的转化则.kcm文件
(1)kcm原则
Key character map files are located by USB vendor, product (and optionally version) id or by input device name.The following paths are consulted in order./system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm/system/usr/keychars/Vendor_XXXX_Product_XXXX.kcm/system/usr/keychars/DEVICE_NAME.kcm/data/system/devices/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm/data/system/devices/keychars/Vendor_XXXX_Product_XXXX.kcm/data/system/devices/keychars/DEVICE_NAME.kcm/system/usr/keychars/Generic.kcm/data/system/devices/keychars/Generic.kcm/system/usr/keychars/Virtual.kcm/data/system/devices/keychars/Virtual.kcm
(2)kcm文件格式:
key B { label: 'B' # 印在按键上的文字
base: 'b' # 如果没有其他按键(shift, ctrl等)同时按下,此按键对应的字符是'b'
shift, capslock: 'B' } B 表示 Android AKEYCODE_B
(3)kcm实验:
-
mkdir -p /data/system/devices/keychars
-
cp /system/usr/keychars/Generic.kcm /data/system/devices/keychars/InputEmulatorFromLKQ.kcm
-
修改:
key STAR { label: '*'
# base: '*'
base: '1'} key POUND { label: '#'
# base: '#'
base: '2'}
-
busybox chmod 777 /data/system/devices -R
-
重启:reboot
-
insmod InputEmulator.ko
-
发送*键, 得到1
sendevent /dev/input/event5 1 227 1 sendevent /dev/input/event5 1 227 0 sendevent /dev/input/event5 0 0 0 -
发送#键, 得到2
sendevent /dev/input/event5 1 228 1 sendevent /dev/input/event5 1 228 0 sendevent /dev/input/event5 0 0 0
补充:
-
也可以用组合键,也可实现
sendevent /dev/input/event5 1 42 1 sendevent /dev/input/event5 1 9 1 sendevent /dev/input/event5 1 9 0sendevent /dev/input/event5 1 42 0 sendevent /dev/input/event5 0 0 0 sendevent /dev/input/event5 1 42 1 sendevent /dev/input/event5 1 4 1 sendevent /dev/input/event5 1 4 0sendevent /dev/input/event5 1 42 0 sendevent /dev/input/event5 0 0 0