Openharmony 设备自定义按键布局文件解析过程分析
·
.pro 文件概述
设备可以拥有自己的pro 文件用来映射自己特殊的键值,它的作用是将Linux scancode 转化为Openharmony keycode,scancode 就是硬件直接扫描到的数字,而这些数字会通过这个 pro文件找到对应的字符串也就是keycode.
配置文件示例
cat /vendor/etc/keymap/32002_2_3_BluetoothHID.pro
KEY_VOLUME_UP 115 17 HOS_KEY_VOLUME_DOWN // KEY_VOLUME_UP 115 Linux驱动键值 17 HOS_KEY_VOLUME_DOWN openharony 对应的系统键值
KEY_VOLUME_DOWN 114 16 HOS_KEY_VOLUME_DOWN
详细的Linux键值与openharony 系统键值对应关系可以参考
foundation/multimodalinput/input/service/event_handler/src/key_event_value_transformation.cpp 参考此结构体MAP_KEY_EVENT_VALUE_TRANSFORMATION
{314, {"KEY_BUTTON_SELECT", 314, 2311, HOS_KEY_BUTTON_SELECT}},
314:为nativeKeyValue 驱动上报键值
KEY_BUTTON_SELECT:linux键值上报描述
2311: openharmony 系统键值
HOS_KEY_BUTTON_SELECT: 系统键值描述
流程图
配置文件解析流程
监听配置文件事件
foundation/multimodalinput/input/service/event_handler/src/event_normalize_handler.cpp
void EventNormalizeHandler::HandleEvent(libinput_event* event, int64_t frameTime)
{
switch (type) {
case LIBINPUT_EVENT_DEVICE_ADDED: {
OnEventDeviceAdded(event); // 设备添加信号
break;
}
}
}
int32_t EventNormalizeHandler::OnEventDeviceAdded(libinput_event *event)
{
CHKPR(event, ERROR_NULL_POINTER);
auto device = libinput_event_get_device(event);
CHKPR(device, ERROR_NULL_POINTER);
InputDevMgr->OnInputDeviceAdded(device);
KeyMapMgr->ParseDeviceConfigFile(device); // 查找键值映射文件
KeyRepeat->AddDeviceConfig(device);
#ifdef OHOS_BUILD_ENABLE_KEYBOARD
KeyEventHdr->ResetKeyEvent(device);
#endif // OHOS_BUILD_ENABLE_KEYBOARD
return RET_OK;
}
void KeyMapManager::ParseDeviceConfigFile(struct libinput_device *device)
{
CHKPV(device);
std::string fileName = GetKeyEventFileName(device); // 获取设备号,配置文件
if (fileName.empty()) {
MMI_HILOGE("Get fileName is empty");
return;
}
int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
GetConfigKeyValue(fileName, deviceId); // 解析配置文件参数
}
void KeyMapManager::GetConfigKeyValue(const std::string &fileName, int32_t deviceId)
{
CALL_DEBUG_ENTER;
std::string filePath = GetProFilePath(fileName);
ReadProFile(filePath, deviceId, configKeyValue_);
MMI_HILOGD("Number of loaded config files:%{public}zu", configKeyValue_.size());
}
按键事件上报流程,解析配置文件
foundation/multimodalinput/input/service/key_event_normalize/src/key_event_normalize.cpp
int32_t KeyEventNormalize::Normalize(struct libinput_event *event, std::shared_ptr<KeyEvent> keyEvent)
{
CALL_DEBUG_ENTER;
CHKPR(event, PARAM_INPUT_INVALID);
CHKPR(keyEvent, ERROR_NULL_POINTER);
keyEvent->UpdateId();
auto data = libinput_event_get_keyboard_event(event);
CHKPR(data, ERROR_NULL_POINTER);
auto device = libinput_event_get_device(event);
CHKPR(device, ERROR_NULL_POINTER);
int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
int32_t keyCode = static_cast<int32_t>(libinput_event_keyboard_get_key(data));
MMI_HILOGD("The linux input keyCode:%{public}d", keyCode);
keyCode = KeyMapMgr->TransferDeviceKeyValue(device, keyCode); // 解析Linux键值,对应的系统键值
int32_t keyAction = (libinput_event_keyboard_get_key_state(data) == 0) ?
(KeyEvent::KEY_ACTION_UP) : (KeyEvent::KEY_ACTION_DOWN);
auto preAction = keyEvent->GetAction();
if (preAction == KeyEvent::KEY_ACTION_UP) {
std::optional<KeyEvent::KeyItem> preUpKeyItem = keyEvent->GetKeyItem();
if (preUpKeyItem) {
keyEvent->RemoveReleasedKeyItems(*preUpKeyItem);
} else {
MMI_HILOGE("The preUpKeyItem is nullopt");
}
}
}
foundation/multimodalinput/input/service/event_handler/src/key_map_manager.cpp
int32_t KeyMapManager::TransferDeviceKeyValue(struct libinput_device *device,
int32_t inputKey)
{
CALL_DEBUG_ENTER;
if (device == nullptr) {
return TransferDefaultKeyValue(inputKey);
}
int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
if (auto itr = configKeyValue_.find(deviceId); itr != configKeyValue_.end()) { // 有没有overrd 的键值,有返回
if (auto devKey = itr->second.find(inputKey); devKey != itr->second.end()) {
return devKey->second;
}
}
return TransferDefaultKeyValue(inputKey); // 没有返回默认键值
}
更多推荐
所有评论(0)