OpenHarmony按键分发流程(60%)

环境

系统版本: OpenHarmony 4.0.10.13
平台设备:rk3588

涉及代码

foundation/multimodalinput/input/service/module_loader/src/mmi_service.cpp
foundation/multimodalinput/input/service/libinput_adapter/src/libinput_adapter.cpp
foundation/multimodalinput/input/service/event_handler/src/input_event_handler.cpp
foundation/multimodalinput/input/service/event_handler/src/event_normalize_handler.cpp
foundation/multimodalinput/input/service/key_event_normalize/src/key_event_normalize.cpp
foundation/multimodalinput/input/service/event_handler/src/key_map_manager.cpp
foundation/multimodalinput/input/service/event_handler/src/key_event_value_transformation.cpp
foundation/multimodalinput/input/service/filter/src/event_filter_handler.cpp
foundation/multimodalinput/input/service/interceptor/src/event_interceptor_handler.cpp
foundation/multimodalinput/input/service/key_command/src/key_command_handler.cpp
foundation/multimodalinput/input/service/subscriber/src/key_subscriber_handler.cpp
foundation/multimodalinput/input/service/monitor/src/event_monitor_handler.cpp
foundation/multimodalinput/input/service/event_dispatch/src/event_dispatch_handler.cpp
foundation/multimodalinput/input/service/event_handler/src/key_auto_repeat.cpp
foundation/multimodalinput/input/frameworks/proxy/event_handler/src/client_msg_handler.cpp
foundation/multimodalinput/input/frameworks/proxy/event_handler/src/input_handler_manager.cpp
foundation/multimodalinput/input/frameworks/proxy/event_handler/src/input_manager_impl.cpp

多模输入子系统

OpenHamrony旨在为开发者提供NUI(Natural User Interface)的交互方式,有别于传统操作系统的输入,在OpenHarmony上,我们将多种维度的输入(触屏、鼠标、键盘、触摸板、遥控器等)整合在一起,通过归一/标准化处理后,分发给消费者(系统服务、应用)。开发者可以借助应用程序框架、系统自带的UI组件或API接口轻松地实现具有多维、自然交互特点的应用程序。
多模输入子系统在OpenHarmony系统架构中的位置:OpenHarmony技术架构

输入时间和设备状态数据流如下:
输入时间和设备状态数据流
如图所示,包含两类关键数据流:

  • 输入设备状态数据流
    输入设备状态数据描述输入设备的状态变化及其设备属性信息,包括:设备插入、移除状态、设备唯一标识、设备名称、设备支持的输入方式等。
    输入设备状态数据,经过内核设备驱动上报给多模输入服务端的输入设备状态管理模块。在输入设备管理模块对全局输入设备状态进行管理和维护,同时设备状态会封装为可监听接口提供给上层业务模块用来监听系统输入外设的状态。
  • 交互输入事件数据流
    交互输入事件数据用来描述键盘、鼠标、触摸屏输入事件;键盘事件包括:按键码、按键时间戳、按键所属设备等信息;鼠标事件包括:鼠标 X/Y 坐标、鼠标按钮(如:鼠标左|中|右)事件等;触摸事件包括:时间戳、触摸位置 X/Y 坐标等。
    输入事件数据由设备驱动上报给输入事件接收模块完成输入事件从内核空间到用户空间的转发,然后再给输入事件预处理模块完成输入事件标准化处理(按键 KeyCode 映射标准化等),最后由输入事件分发模块以系统预设分发机制和原则完成事件的分发。

根据上面数据流图,可以很清晰地了解到在用户通过输入设备发起一次交互请求后,输入事件上报和分发全流程。

按键分发代码流程梳理

多模输入分发流程,按键事件在kernel驱动层检测并识别后,向多模输入服务端分发,会经历以下处理流程:

  • 输入事件接收
  • 输入事件预处理
  • 输入事件分发:拦截、分发、监听
  • 应用框架传递输入事件
  • 应用监听处理

多模输入服务(MutilModalInputService)MMIService启动

MMIService服务有init进程启动,代码流程如下:
base/startup/init/services/init/main.c

//init进程启动
int main(int argc, char * const argv[])
{
   ...
   EnableInitLog(INIT_INFO);
   if (isSecondStage == 0) {
       SystemPrepare(); //系统做准备工作:打开log服务、使能kmsg、挂载基本目录、进入init第二阶段
   } else {
       LogInit();
   }
   SystemInit(); //系统初始化
   SystemExecuteRcs();
   SystemConfig();//加载系统配置文件、启动开机服务和基本服务
   SystemRun();//启动属性服务ParamService
   return 0;
}

init进程做好系统准备工作后,由SystemConfig()启动各系统服务
base/startup/init/services/init/standard/init.c

void SystemConfig(void)
{
    ...
    TriggerServices(START_MODE_BOOT); //启动开机阶段服务,如:hdf_devmgr、hiview、param_watcher、device_manager、storage_manager、appspawn等
    TriggerServices(START_MODE_NORMAL);//启动基本服务:wifi_hal_service、multimodalinput、bluetooth_service、netmanager等
}

至此通过TriggerServices(START_MODE_NORMAL)启动了多模输入服务multimodalinput,即MMIS
foundation/multimodalinput/input/service/module_loader/src/mmi_service.cpp

void MMIService::OnStart()
{
    ...
    //初始化MMIS和相关的windowManager、ANRManager 、PointerDrawingManager 、InputHandler等。
    int32_t ret = Init();
    //启动OnThread线程,监听kernel上报的event
    t_ = std::thread(std::bind(&MMIService::OnThread, this));
    pthread_setname_np(t_.native_handle(), name.c_str());
	...
}

MMIService服务启动后,紧接着进行init,并创建OnThread线程;我们首先看看init()

int32_t MMIService::Init()
{
    ...
    WinMgr->Init(*this);    //初始化WindowsManager
    ANRMgr->Init(*this);    //初始化ANRManager
    FINGERSENSE_WRAPPER->InitFingerSenseWrapper();
    DISPLAY_MONITOR->InitCommonEventSubscriber();
    if (!IPointerDrawingManager::GetInstance()->Init()) {
       ...
    }
    ...
    InputHandler->Init(*this);    //初始化InputHandler,调用BuildInputHandlerChain()构建inputHandler的传递链
    if (!InitLibinputService()) {    //初始化InitLibinputAdapter
        ..
    }
    if (!InitDelegateTasks()) {
        ..
    }
    ...
}
...
bool MMIService::InitLibinputService()
{
	//初始化libinputAdapter并绑定InputEventHandler::OnEvent()
    if (!(libinputAdapter_.Init(std::bind(&InputEventHandler::OnEvent, InputHandler, std::placeholders::_1)))) {
        MMI_HILOGE("Libinput init, bind failed");
        return false;
    }
    ...
}

在init中初始化相关manager和其他服务,其中包括初始化libinputAdapter并绑定InputEventHandler::OnEvent(),监听Event事件,并进一步处理。
了解inputHander.Init()便于理解后续各inputHandler中keyevent传递过程
foundation/multimodalinput/input/service/event_handler/src/input_event_handler.cpp

void InputEventHandler::Init(UDSServer& udsServer)
{
    udsServer_ = &udsServer;
    BuildInputHandlerChain();
}
nt32_t InputEventHandler::BuildInputHandlerChain()
{
    eventNormalizeHandler_ = std::make_shared<EventNormalizeHandler>();
#if !defined(OHOS_BUILD_ENABLE_KEYBOARD) && !defined(OHOS_BUILD_ENABLE_POINTER) && !defined(OHOS_BUILD_ENABLE_TOUCH)
    return RET_OK;
#endif // !OHOS_BUILD_ENABLE_KEYBOARD && !OHOS_BUILD_ENABLE_POINTER && !OHOS_BUILD_ENABLE_TOUCH

    std::shared_ptr<IInputEventHandler> handler = eventNormalizeHandler_;
#if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
    eventFilterHandler_ = std::make_shared<EventFilterHandler>();
    handler->SetNext(eventFilterHandler_);
    handler = eventFilterHandler_;
#endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
	...
}

通过SetNext()将各种inputEventHandler链起来,形成
EventNormalizeHandler-->EventFilterHandler-->EventInterceptorHandler-->KeyCommandHandler->KeySubscriberHandler->EventMonitorHandler->EventDispatchHandler

回到主线OnStart(),看看OnThread()内容

//OnThread线程,分发kernel上报的event
void MMIService::OnThread()
{
    ...
    libinputAdapter_.ProcessPendingEvents();
    while (state_ == ServiceRunningState::STATE_RUNNING) {
        ...
        for (int32_t i = 0; i < count && state_ == ServiceRunningState::STATE_RUNNING; i++) {
            auto mmiEd = reinterpret_cast<mmi_epoll_event *>(ev[i].data.ptr);
            CHKPC(mmiEd);
            //根据I/O类型的不同,处理流程不同,按键事件为EPOLL_EVENT_INPUT类型,进入libinputAdapter_.EventDispatch()
            if (mmiEd->event_type == EPOLL_EVENT_INPUT) {
                libinputAdapter_.EventDispatch(mmiEd->fd);
            } else if (mmiEd->event_type == EPOLL_EVENT_SOCKET) {
                OnEpollEvent(ev[i]);
            } else if (mmiEd->event_type == EPOLL_EVENT_SIGNAL) {
                OnSignalEvent(mmiEd->fd);
            } else if (mmiEd->event_type == EPOLL_EVENT_ETASK) {
                OnDelegateTask(ev[i]);
            } else {
                MMI_HILOGW("Unknown epoll event type:%{public}d", mmiEd->event_type);
            }
        }
        ...
    }
}

OnThread处理kernel上报上来的按键事件,向后续流程进行libinputAdapter_.EventDispatch()按键事件分发
foundation/multimodalinput/input/service/libinput_adapter/src/libinput_adapter.cpp

void LibinputAdapter::EventDispatch(int32_t fd)
{
	...
		//准备处理kernel上报上来的event
        OnEventHandler();
	...
}

void LibinputAdapter::OnEventHandler()
{
    CALL_DEBUG_ENTER;
    CHKPV(funInputEvent_);
    libinput_event *event = nullptr;
    while ((event = libinput_get_event(input_))) {
        funInputEvent_(event);
        libinput_event_destroy(event);
    }
}

前面InitLibinputService()绑定了input_event_handler.cpp的OnEvent()

void InputEventHandler::OnEvent(void *event)
{
    ...
    eventNormalizeHandler_->HandleEvent(lpEvent);
    ...
}

foundation/multimodalinput/input/service/event_handler/src/event_normalize_handler.cpp

void EventNormalizeHandler::HandleEvent(libinput_event* event)
{
    //获取event事件类型
    auto type = libinput_event_get_type(event);
    ...
    switch (type) {
        ...
        //处理按键类型event
        case LIBINPUT_EVENT_KEYBOARD_KEY: {
            HandleKeyboardEvent(event);
            DfxHisysevent::CalcKeyDispTimes();    //统计按键分发次数
            break;
        }
        ...
}
//进入处理按键事件流程
int32_t EventNormalizeHandler::HandleKeyboardEvent(libinput_event* event)
{
    ...
    auto keyEvent = KeyEventHdr->GetKeyEvent();    //获取keyEvent对象
    auto packageResult = KeyEventHdr->Normalize(event, keyEvent);    //标准化keyevent
    ...
    nextHandler_->HandleKeyEvent(keyEvent);    //传递至下个handler处理按键事件
    KeyRepeat->SelectAutoRepeat(keyEvent);    //是否出发某些自动重复功能,如键盘长按连续输入字符
    MMI_HILOGD("keyCode:%{public}d, action:%{public}d", keyEvent->GetKeyCode(), keyEvent->GetKeyAction());
    ...
}

//将底层异构的硬件输入事件统一封装为应用层可理解的标准化事件,包含设备信息、按键状态、时间戳及语义意图,实现输入事件的抽象与跨平台兼容
int32_t KeyEventNormalize::Normalize(struct libinput_event *event, std::shared_ptr<KeyEvent> keyEvent)
{
    ....
    //根据device转换keycode
    keyCode = KeyMapMgr->TransferDeviceKeyValue(device, keyCode);
    ....
    //标准化keyEvent对象参数值,包括按键事件、意图、设备id、按键码等
    keyEvent->SetActionTime(time);
    keyEvent->SetAction(keyAction);
    keyEvent->SetDeviceId(deviceId);
    keyEvent->SetKeyCode(keyCode);
    keyEvent->SetKeyAction(keyAction);
    if (keyEvent->GetPressedKeys().empty()) {
        keyEvent->SetActionStartTime(time);
    }

    KeyEvent::KeyItem item;
    bool isKeyPressed = (libinput_event_keyboard_get_key_state(data) != KEYSTATUS);
    item.SetDownTime(time);
    item.SetKeyCode(keyCode);
    item.SetDeviceId(deviceId);
    item.SetPressed(isKeyPressed);
    item.SetUnicode(KeyCodeToUnicode(keyCode, keyEvent));
	
	//管理特殊keyEvent状态,如NumLock、CapsLock、ScrollLock
    HandleKeyAction(device, item, keyEvent);
	
    int32_t keyIntention = keyItemsTransKeyIntention(keyEvent->GetKeyItems());
    keyEvent->SetKeyIntention(keyIntention);
    return RET_OK;
}

根据代码执行先后顺序,这里主要动作:

  • 根据设备,将linux keycode转换成device keycode
  • 标准化keyevent对象各参数
  • 管理特殊按键状态
  • 更新按键intention

了解下TransferDeviceKeyValue()转换过程
foundation/multimodalinput/input/service/event_handler/src/key_map_manager.cpp

int32_t KeyMapManager::TransferDeviceKeyValue(struct libinput_device *device,
    int32_t inputKey)
{
    //device为空时使用默认按键映射表转换inputKey
    if (device == nullptr) {
        return TransferDefaultKeyValue(inputKey);
    }
     //使用定制按键映射表转换inputKey
    int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
    if (auto itr = configKeyValue_.find(deviceId); itr != configKeyValue_.end()) {
        if (auto devKey = itr->second.find(inputKey); devKey != itr->second.end()) {
            return devKey->second;
        }
    }
    //上面调节不成立,仍使用默认按键映射表
    return TransferDefaultKeyValue(inputKey);
}

int32_t KeyMapManager::TransferDefaultKeyValue(int32_t inputKey)
{
    ...
    return TransferKeyValue(inputKey).sysKeyValue;
}

foundation/multimodalinput/input/service/event_handler/src/key_event_value_transformation.cpp

KeyEventValueTransformation TransferKeyValue(int32_t keyValueOfInput)
{
    auto it = MAP_KEY_EVENT_VALUE_TRANSFORMATION.find(keyValueOfInput);
    ...
    return it->second;
}

//默认的键值映射表:当前按下的键为KEY_1 
//2:linux keycode      KEY_1: key event标签		2:native keycode 	 2001: 系统keycode  HOS_KEY_1:系统key event码
const std::multimap<int32_t, KeyEventValueTransformation> MAP_KEY_EVENT_VALUE_TRANSFORMATION = {
    {11, {"KEY_0", 11, 2000, HOS_KEY_0}},
    {2, {"KEY_1", 2, 2001, HOS_KEY_1}},
    {3, {"KEY_2", 3, 2002, HOS_KEY_2}},
    ...
};

当前按键为数字1,由于没有没有定制按键转化配置文件,使用默认的配置表,将linux keycode 2转为2001系统keycode,即后续APP使用的keycode。
得到转换后的keycode并进行标准化keyevent,继续HandleKeyEvent()
foundation/multimodalinput/input/service/event_handler/src/event_normalize_handler.cpp

void EventNormalizeHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
    ...
    //继续向EventFilterHandler传递keyevent
    nextHandler_->HandleKeyEvent(keyEvent);
    ...
}

通过前文BuildInputHandlerChain()可知EventNormalizeHandler的nextHandler为EventFilterHandler
foundation/multimodalinput/input/service/filter/src/event_filter_handler.cpp

void EventFilterHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
	//处理需要过滤的keyevent
    if (HandleKeyEventFilter(keyEvent)) {
        MMI_HILOGD("Key event is filtered");
        return;
    }
    //继续向EventInterceptorHandler传递keyevent
    nextHandler_->HandleKeyEvent(keyEvent);
}

bool EventFilterHandler::HandleKeyEventFilter(std::shared_ptr<KeyEvent> event)
{
	//默认filters为空,直接return
	if (filters_.empty()) {
        return false;
    }
    //遍历过滤器,检查keyevent是否需要过滤处理
    for (auto &i: filters_) {
        if (!inputDevice->HasCapability(i.deviceTags)) {
            continue;
        }
        if (i.filter->HandleKeyEvent(event)) {
            MMI_HILOGD("Call HandleKeyEventFilter return true");
            return true;
        }
    }
    return false;
}

foundation/multimodalinput/input/service/interceptor/src/event_interceptor_handler.cpp

void EventInterceptorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
	//检查按键是否需要拦截
    if (OnHandleEvent(keyEvent)) {
        MMI_HILOGD("KeyEvent filter find a keyEvent from Original event keyCode:%{public}d",
            keyEvent->GetKeyCode());
        BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_INTERCEPT_EVENT);
        return;
    }
    //继续向KeyCommandHandler传递keyEvent
    nextHandler_->HandleKeyEvent(keyEvent);
}

bool EventInterceptorHandler::OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)
{
    MMI_HILOGD("Handle KeyEvent");
    ...
    //检查是否keyevent需要被拦截
    return interceptors_.HandleEvent(keyEvent);
}

bool EventInterceptorHandler::InterceptorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
{
    CHKPF(keyEvent);
    //默认未设置拦截器,在此return
    if (interceptors_.empty()) {
        MMI_HILOGD("Key interceptors is empty");
        return false;
    }
    ...
    return isInterceptor;
}

foundation/multimodalinput/input/service/key_command/src/key_command_handler.cpp

void KeyCommandHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
	//处理短按按键、组合按键、特殊按键(默认均未配置)
    if (OnHandleEvent(keyEvent)) {
        MMI_HILOGD("The keyEvent start launch an ability, keyCode:%{public}d", keyEvent->GetKeyCode());
        BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_LAUNCH_EVENT);
        return;
    }
    //继续向KeySubscriberHandler传递keyevent
    nextHandler_->HandleKeyEvent(keyEvent);
}

bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<KeyEvent> key)
{
	//处理(快捷键)按键短按事件
    bool isHandled = HandleShortKeys(key);
    //处理组合按键(如Ctrl + C)
    isHandled = HandleSequences(key) || isHandled;
    if (isHandled) {
        return true;
    }
	//检查是否为特殊按键, Power、Vol+、Vol-
    if (!specialKeys_.empty() && specialKeys_.find(key->GetKeyCode()) != specialKeys_.end()) {
        HandleSpecialKeys(key->GetKeyCode(), key->GetAction());
        return true;
    }
	//处理订阅按键事件
    if (IsSpecialType(key->GetKeyCode(), SpecialType::SUBSCRIBER_BEFORE_DELAY)) {
        	...
            InputHandler->GetSubscriberHandler()->HandleKeyEvent(tmpKey);
        	...
    }
    ...
}

KeyCommandHandler::OnHandleEvent()按键事件处理分类按键

  • 快捷键:
  • 全局特殊按键:Power、Vol+、Vol-

快捷键处理:

bool KeyCommandHandler::HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)
{
    ...
    //遍历快捷键配置表的快捷键(etc/multimodalinput/ability_launch_config.json 默认未配置),并处理相应的快捷键事件
    for (auto &item : shortcutKeys_) {
        ...
        //从配置文件/data/service/el1/public/multimodalinput/Settings.xml(默认无此文件)中获取识别为按键短按的配置
        int32_t delay = GetKeyDownDurationFromXml(shortcutKey.businessId);
        //按键按下持续0~4s则认为是短按事件
        if (delay >= MIN_SHORT_KEY_DOWN_DURATION && delay <= MAX_SHORT_KEY_DOWN_DURATION) {
            MMI_HILOGD("User defined new short key down duration: %{public}d", delay);
            shortcutKey.keyDownDuration = delay;
        }
        //根据快捷键配置的出发类型决定Down或up触发时机
        if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_DOWN) {
            return HandleKeyDown(shortcutKey);
        } else if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_UP) {
            return HandleKeyUp(keyEvent, shortcutKey);
        } else {
            return HandleKeyCancel(shortcutKey);
        }
    }
    //取消按键事件
    return HandleConsumedKeyEvent(keyEvent);
}

Power按键处理:

//特殊按键类型
enum SpecialType {
    SPECIAL_ALL = 0,
    SUBSCRIBER_BEFORE_DELAY = 1,
    KEY_DOWN_ACTION = 2
};
//默认特殊按键表,包含Power按键、音量键
const std::map<int32_t, SpecialType> SPECIAL_KEYS = {
    { KeyEvent::KEYCODE_POWER, SpecialType::KEY_DOWN_ACTION },
    { KeyEvent::KEYCODE_VOLUME_DOWN, SpecialType::SPECIAL_ALL },
    { KeyEvent::KEYCODE_VOLUME_UP, SpecialType::SPECIAL_ALL }
};

//拦截电源键和音量键继续下发
void KeyCommandHandler::HandleSpecialKeys(int32_t keyCode, int32_t keyAction)
{
    auto iter = specialKeys_.find(keyCode);
    if (keyAction == KeyEvent::KEY_ACTION_UP) {
        if (iter != specialKeys_.end()) {
            specialKeys_.erase(iter);
            return;
        }
    }

    if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
        if (iter == specialKeys_.end()) {
            auto it = specialKeys_.emplace(keyCode, keyAction);
            if (!it.second) {
                MMI_HILOGD("KeyCode duplicated");
                return;
            }
        }
    }
}

若按键不是快捷键和系统按键,则继续向KeySubscriberHandler传递
foundation/multimodalinput/input/service/subscriber/src/key_subscriber_handler.cpp

void KeySubscriberHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
	//
    if (OnSubscribeKeyEvent(keyEvent)) {
        ...
    }
    //继续向EventMonitorHandler传递keyevent
    nextHandler_->HandleKeyEvent(keyEvent);
}

bool KeySubscriberHandler::OnSubscribeKeyEvent(std::shared_ptr<KeyEvent> keyEvent)
{
    ...
    //根据按键动作调用不同处理方法,按下时首先进入HandleKeyDown()
    if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
        handled = HandleKeyDown(keyEvent);
    } else if (keyAction == KeyEvent::KEY_ACTION_UP) {
        hasEventExecuting_ = false;
        handled = HandleKeyUp(keyEvent);
    } else if (keyAction == KeyEvent::KEY_ACTION_CANCEL) {
        hasEventExecuting_ = false;
        handled = HandleKeyCancel(keyEvent);
    } 
    ...
}

bool KeySubscriberHandler::HandleKeyDown(const std::shared_ptr<KeyEvent> &keyEvent)
{
    ...
    for (const auto &subscriber : subscribers_) {
        auto &keyOption = subscriber->keyOption_;
        if (!keyOption->IsFinalKeyDown()) {
            MMI_HILOGD("!keyOption->IsFinalKeyDown()");
            continue;
        }
        if (keyCode != keyOption->GetFinalKey()) {
            ClearTimer(subscriber);
            MMI_HILOGD("keyCode != keyOption->GetFinalKey()");
            continue;
        }
        if (!IsPreKeysMatch(keyOption->GetPreKeys(), pressedKeys)) {
            ClearTimer(subscriber);
            MMI_HILOGD("preKeysMatch failed");
            continue;
        }
        if (keyOption->GetFinalKeyDownDuration() <= 0) {
            MMI_HILOGD("keyOption->GetFinalKeyDownDuration() <= 0");
            //向订阅者通知并发送按键事件信息
            NotifySubscriber(keyEvent, subscriber);
            handled = true;
            continue;
        }

        if (!AddTimer(subscriber, keyEvent)) {
            MMI_HILOGE("Leave, add timer failed");
        }
    }
    MMI_HILOGD("%{public}s", handled ? "true" : "false");
    return handled;
}

foundation/multimodalinput/input/service/monitor/src/event_monitor_handler.cpp

void EventMonitorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
    OnHandleEvent(keyEvent);
    //继续向EventDispatchHandler传递keyevent
    nextHandler_->HandleKeyEvent(keyEvent);
}

bool EventMonitorHandler::OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)
{
    	...
        if (monitors_.HandleEvent(keyEvent)) 
        ...
}

bool EventMonitorHandler::MonitorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
{
    ...
    //
    for (const auto &mon : monitors_) {
        if ((mon.eventType_ & HANDLE_EVENT_TYPE_KEY) == HANDLE_EVENT_TYPE_KEY) {
            mon.SendToClient(keyEvent);
        }
    }
    ...
}

void EventMonitorHandler::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
{
    
    NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
    ...
    if (!session_->SendMsg(pkt)) {
    ...
}

foundation/multimodalinput/input/service/event_dispatch/src/event_dispatch_handler.cpp

void EventDispatchHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
{
    ...
    DispatchKeyEventPid(*udsServer, keyEvent);
}

int32_t EventDispatchHandler::DispatchKeyEventPid(UDSServer& udsServer, std::shared_ptr<KeyEvent> key)
{
    ...
    MMI_HILOGD("Event dispatcher of server:KeyEvent:KeyCode:%{public}d,Action:%{public}d,EventType:%{public}d,"
        "Fd:%{public}d", key->GetKeyCode(), key->GetAction(), key->GetEventType(), fd);
    auto session = udsServer.GetSession(fd);
 
    auto currentTime = GetSysClockTime();
    if (ANRMgr->TriggerANR(ANR_DISPATCH, currentTime, session)) {
        MMI_HILOGW("The key event does not report normally, application not response");
        return RET_OK;
    }

    NetPacket pkt(MmiMessageId::ON_KEY_EVENT);
    InputEventDataTransformation::KeyEventToNetPacket(key, pkt);

    if (!udsServer.SendMsg(fd, pkt)) {
        MMI_HILOGE("Sending structure of EventKeyboard failed! errCode:%{public}d", MSG_SEND_FAIL);
        return MSG_SEND_FAIL;
    }
    ANRMgr->AddTimer(ANR_DISPATCH, key->GetId(), currentTime, session);
    return RET_OK;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值