open harmony多模组子系统分析
multimodalinput是open harmony的核心输入子系统,负责统一管理触摸屏,键盘,鼠标,手势,传感器等多种 输入源,提供标准化事件分发机制。其核心 目标是通过统一的事件处理框架,实现跨设备,多模态输入的无缝协同。
今天我们学习下整个多模组子系统的工作流程,输入事件到应用的传递路径,整个过程涉及从设备驱动到事件处理,再到 分发给应用程序 的整个流程。
最终我们总结一下 整个模块的设计思路 ,比如分层 架构,各层之间的接口调用 ,模块如何支持多种 输入设备(如触摸屏,键盘,鼠标等)。以及如何处理复杂事件(如组合键,手持识别)
多模组子系统的整个关键的目录结构图如下
/ohos-oneconnect/foundation/multimodalinput/input$ tree -L 1
.
├── BUILD.gn //是构建配置文件,说明模块如何编译
├── CODEOWNERS
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
├── bundle.json
├── common //包含一些公共代码或工具类
├── etc //存放 的是一些 配置文件
├── examples //存放 一些 示例代码
├── figures
├── frameworks //包含核心 框架代码
├── intention
├── interfaces //定义 了一些 接口, kits和native提供api接口供其它模块调用
├── libudev
├── mmi_uinput.rc
├── multimodalinput.cfg
├── multimodalinput_mini.gni
├── sa_profile
├── service //包含服务 实现 account_manager,device_manager(负责管理输入设备), event_handler(处理事件分发)等 ,对应 不同 的服务组件,负责处理不同的输入事件或设备管理
├── test //是测试相关 test 下的unittest和fuzztest用于保证 代码质量
├── tools //工具脚本
├── uinput //输入设备模拟
└── util //实用工具
代码目录结构详解:
1.核心 服务层(service/)
├── account_manager # 多用户账户的输入权限管理
├── device_manager # 输入设备的生命周期管理(增删/状态监控)
├── event_handler # 输入事件的核心处理引擎(包含事件过滤/转换)
├── event_dispatch # 事件分发机制(IPC通信/窗口关联)
├── key_event_normalize # 键盘事件标准化(组合键/长按/重复键处理)
├── touch_event_normalize # 触摸事件校准/手势识别
├── subscriber # 事件订阅管理(应用注册监听特定事件)
├── filter # 输入事件过滤规则(防抖/安全策略)
├── permission_helper # 输入权限验证(如截屏权限)
└── window_manager # 窗口焦点与输入事件的绑定关系
核心作用:
- 实现输入设备的全生命周期管理 (device_manager)
- 事件处理流水线:原始事件-》标准化-》过滤-》分发(event_handler串联各环节)
- 权限与安全控制 (permission_helper+account_manger)
2.设备抽象层(uinput/)
uinput/
├── virtual_device.cpp # 虚拟输入设备基类
├── virtual_keyboard.cpp # 虚拟键盘设备实现
├── virtual_touch_screen.cpp # 虚拟触摸屏模拟
└── hdf_device_event_* # HDF驱动层事件对接
核心作用:
- 提供虚拟输入设备的创建/销毁接口(用于自动化测试)
- 对接硬件驱动 (HDF)获取原始输入事件
- 实现输入事件的硬件抽象(virtual_device 系列类)
3.框架接口层(framework/&interfaces/)
frameworks/
├── native/ # Native层事件处理API(C++)
├── napi/ # JS API的Native适配层
└── proxy/ # 跨进程通信代理
interfaces/
├── kits/js/napi/ # 对应用暴露的JS API
└── native/ # Native层头文件(供其他模块调用)
核心作用
- 提供统一的输入事件api给上层应用(JS/Native)
- 实现跨进程通信 (如systemUI与应用间的事件传递)
4.策略配置层(etc/)
etc/
├── exclude_keys_config.json # 需要屏蔽的物理按键列表
├── white_list_config.json # 特权应用白名单(可监听系统级按键)
└── multimodalinput.para.dac # 输入子系统的DAC权限配置
核心作用:
- 定义输入事件处理的安全策略(如禁用某些危险按键)
- 配置设备校准参数 (触摸屏灵敏度等)
5.工具与测试(tools/& test/)
tools/
├── event_inject # 输入事件注入工具(模拟用户操作)
└── vuinput # 虚拟输入设备控制工具
test/
├── unittest/ # 单元测试(事件处理逻辑验证)
└── fuzztest/ # 模糊测试(健壮性验证)
6.公共组件(common/ &util/)
common/
└── anco # 异步非阻塞通信组件(用于低延迟事件传递)
util/
├── napi/ # NAPI工具类(JS/Native类型转换)
└── socket/ # 套接字通信工具(跨进程事件传输)
核心作用:
- 封装可利用的基础设施(网络通信、数据序列化)
- 提供跨语言交互 支持(JS C++数据类型转换)
关键代码流程解析
1:输入事件处理流水线
硬件驱动-》uinput->event_handler->filter->subscriber->应用
- 硬件事件获取:通过 uinput/virture_device从HDF驱动读取原始事件
- 事件标准化:key_event_normalize处理物理按键,touch_event_normalize处理触控轨迹
- 安全过滤 :filter模块 根据 策略屏蔽危险事件
- 跨进程分发; event_dispatch 通过 IPC将事件传递给订阅者(应用)
2:组合按键处理示例
以Power+volume up组合键为例:
1.key_event_normalize检测到power 键 按下,启动组合键计时器
2.若在500ms以内 收到 volume up键:
- 触发组合键回调(如截屏)
- 调用 filter模块屏蔽volume up的独立事件
- 若超时未检测到组合键,正常分发volume up事件
模块间的依赖关系
设置亮点与挑战
1.多模态事件整合 通过 intention/目录 下的意图识别模块 ,实现触控+传感器数据整合(如旋转设备时调整触摸坐标)
2.低延迟优化 使用common/anco 实现异步非阻塞通信 event_resample/模块 对触摸事件进行运动预测
3.跨设备协同挑战 connect_manager/ 处理多设备输入冲突(如手机和平板同时连接时的焦点竞争)
调试与扩展建议
事件追踪
使用 tools/event_inject 注入测试事件,结合 hilog 日志分析处理流程:
hilog | grep MMI
添加新输入设备方法
在 uinput/ 下实现新的 virtual_device 子类
在 device_manager 中注册设备类型
自定义手势识别
修改 touch_event_normalize/ 中的手势识别算法,扩展 gesturesense_wrapper