Ø1. Input子系统总框图
![](https://img-blog.csdnimg.cn/direct/c907c5caac9244128b8c88cf6aba5e5e.png)
Ø2. Input子系统驱动![](https://img-blog.csdnimg.cn/direct/1fbf88e272014cccbe42b31da3225bb3.png)
驱动层:输入设备具体实现驱动程序,向内核层报告输入内容,每个设备对应一个struct input_dev对象
【/driver/input/mouse&keyboard&&touchscreen->s3c2410ts.c&usbmouse.c&usbkbd.c】
核心层:承上启下,为驱动层提供输入设备注册和操作接口(input_register_device),通知事件层对输入事件进行处理,向下提供驱动层接口(input_dev),向上提供事情层的接口.【 driver/input/input.c】
事件层:主要和用户空间进行交互,将硬件驱动层上传上来的事件报告用户层. 每个input_handler对象处理一类事件【 /driver/input/: evdev.c/tsdev.c/joydev.c/mousedev.c/keyboard.c】
2.1 Input子系统驱动
平台设备机制:
1.申请主设备号
2.创建cdev->将cdev挂载到系统设备哈希表中,生成inode节点
3.创建device->将device与inode节点关联起来,为上层提供调用接口
注册输入子系统设备:
1.创建一个设备类class
2.申请主设备号
3.创建cdev->将cdev挂载到系统设备哈希表中,生成inode节点
4.创建input_device->将input->device与inode节点关联起来,为事件驱动层提供调用接口
<1>注册设备支持输入事件类型/事件编码
<2>生成/dev/input_device
5.当input_device与input_hander匹配成功生成/dev/input*,上层应用通过主设备号打开/dev/input,通过次设备打开/dev/input_device
输入子系统函数:
1.Read读函数
2.Write写函数
3.Event上报事件函数
Note:
在handler的connect中注册了一个字符设备,绑定了一个操作集,当应用使用/dev/input/eventx节点时即调用该操作集。
2.2 Input子系统驱动
Input子系统接口:
<1>. struct input_dev *input_allocate_device(void)//创建对象
<2>.void set_bit(struct input_dev *dev,unsigned long whichbits)//设置事件类型
<3>.void input_set_abs_params(struct input_dev *dev,unsigned int axis,int min,int max,int fuzz,int flat)
<4>.int input_register_device(struct input_dev *dev)//注册input设备到内核
<5>.void input_unregister_device(struct input_dev *dev)void input_free_device(struct input_dev *dev)
<6>.input_set_capability() //设置事件属性
<7>.input_report_abs()//
<8>.input_report_rel()//坐标事件
<9>.input_report_key()//按键事件
<10>.input_event()//上报指定的输入事件及事件值
<11>.input_sync()//上报同步事件
2.3 Input子系统驱动---事件列表
1. EV_SYN:表示同步事件。
2. EV_KEY:表示按键事件,如按下、释放、保持按下等。
3. EV_REL:表示相对坐标事件,如鼠标移动等。
4. EV_ABS:表示绝对坐标事件,如触摸屏事件等。
5. EV_MSC:表示杂项事件,如输入设备的状态信息等。
6. EV_SW:表示开关事件,如开关机事件等。
7. EV_LED:表示LED灯事件。
8. EV_SND:表示声音事件,如按键声音等。
9. EV_REP:表示自动重复事件,如长按事件等。
10. EV_FF:表示力反馈事件,如震动等。
11. EV_PWR:表示电源事件,如电量低等。
12. EV_FF_STATUS:表示力反馈设备的状态信息。
Ø3. Input子系统应用
InputManagerService是java层的一个系统服务,继承IInputManager.Stub,作为binder通信服务端。
(1)InputReader:负责从硬件获取输入,转换成事件传给Input Dispatcher派发线程。
(2)InputDispatcher:将InputReader传送过来的Events分发给合适的窗口,并监控ANR。
(3)InputManagerService: 负责InputReader和InputDispatcher的创建,并提供Policy用于Events的预处理。
(4)WindownManagerService: 管理InputManager与View及ActivityManager之间的通信,中转输入事件。
(5)View and Activity: 接收按键并处理。
(6)ActivityManagerService: ANR处理。
3.1 Input子系统应用---IMS&WMS服务
启动顺序:init 进程 ---> Zygote 进程 ---> SystemServer 进程 ---> 各应用进程
其中SystemServer启动系统总共100多个,分三大类:引导服务,核心服务和其他服务。
Bootstrap | CoreService | OtherService | |||
FileIntegrityService | SystemConfigService | KeyAttestationApplicationIdProviderService | |||
Installer | BatteryService | KeyChainSystemService | |||
DeviceIdentifiersPolicyService | UsageStatsService | SchedulingPolicyService | |||
UriGrantsManagerService | WebViewUpdateService | TelecomLoaderService | |||
ActivityManagerService | CachedDeviceStateService | AccountManagerService | |||
DataLoaderManagerService | BinderCallsStatsService | ContentService | |||
IncrementalService | LooperStatsService | DropBoxManagerService | |||
PowerManagerService | BugreportManagerService | VibratorService | |||
ThermalManagerService | GpuService | DynamicSystemService | |||
PowerManagement | ConsumerIrService | ||||
RecoverySystemService | AlarmManagerService | ||||
LightsService | InputManagerService | ||||
SidekickService | WindowManagerService | ||||
DisplayManagerService | VrManagerService | ||||
PackageManagerService | BluetoothService | ||||
UserManagerService | IpConnectivityMetrics | ||||
OverlayManagerService | NetworkWatchlistService | ||||
SensorPrivacyService | AppIntegrityManagerService | ||||
… |
WMS为窗口管理者。IMS会对input事件进行处理,并合适的窗口来接收信息,因此WMS称为输入系统中转站。
3.2 Input子系统应用--- InputManagerService逻辑
<1>. SystemServer创建并启动InputManagerService
<2>. InputManagerService在native层创建一个NativeInputManager对象
<3>. NativeInputManager内部创建一个InputManager对象
<4>. InputManager启动InputReaderThread和InputDispatcherThread
<5>. 在InputReaderThread线程中调用EventHub的getevents获取设备节点中的输入事件
<6>. 将输入事件封装为NotifyKeyArgs对象放入队列中
<7>. 调用flush依次将事件传递给InputDispatcher
<8>. InputDispatcher在收到事件后,会重新封装为一个keyEntry对象,压入mInboundQueue列表中
<9>. 唤醒InputDispatcherThread线程
3.3 Input子系统应用--- Keylayout键值映射
key layout文件属于标准linux与anroid键值映射文件,kl文件可以有很多个,按一定优先级解析.通过getevent -i /dev/input/xxx可查看设备vendor id和product id.
frameworks/base/data/keyboards
common/products/mbox/Vendor_0001_Product_0001.kl
frameworks/native/include/android/keycodes.h
frameworkbase/core/res/res/values/attrs.xml
frameworks/base/core/java/android/view/KeyEvent.java
framework/native/include/input/InputEventLabels.h
/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