Openharmony 多模输入子系统适配方案

Linux设备驱动模型

参考如下Blog
Linux 内核:设备驱动模型 class与device

HDF 驱动框架

参考如下Blog
OpenHarmony-HDF驱动框架介绍及加载过程分析

Openharmony 如何兼容Linux 原生驱动

多模输入Linux标准事件转化成openharmony 标准事件

img

本节主要讲多模输入如何兼容linux 原生驱动,通过代码分析多模输入里如何将Linux标准事件转化成openharmony 标准事件。

多模输入子系统监听Linux原生驱动流程图

img

结合代码讲解

MMIService 如何监控lininput 事件
在foundation/multimodalinput/input/service/module_loader/src/mmi_service.cpp 中

bool MMIService::InitLibinputService()
{
    if (!(libinputAdapter_.Init(std::bind(&InputEventHandler::OnEvent, InputHandler,
        std::placeholders::_1, std::placeholders::_2)))) {
        MMI_HILOGE("Libinput init, bind failed");
        return false;
    }    // funInputEvent_ 绑定InputEventHandler::OnEvent
    auto inputFds = libinputAdapter_.GetInputFds();   // 接收libinput返回的文件描述符
    for (auto fd : inputFds) {
        auto ret = AddEpoll(EPOLL_EVENT_INPUT, fd);   // 监控返回的文件描述符
        .........
        .........
    }
    return true;
}

监听/dev/input 下输出输出节点

void MMIService::OnThread()
{
    .........
    .........
    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);
            if (mmiEd->event_type == EPOLL_EVENT_INPUT) {
                libinputAdapter_.EventDispatch(mmiEd->fd);  // 事件分类
            } 
            .........
            .........
        }
        TimerMgr->ProcessTimers();
        if (state_ != ServiceRunningState::STATE_RUNNING) {
            break;
        }
    }
    MMI_HILOGI("Main worker thread stop. tid:%{public}" PRId64 "", tid);
}

代码路径:foundation/multimodalinput/input/service/libinput_adapter/src/libinput_adapter.cpp

void LibinputAdapter::EventDispatch(int32_t fd)
{
    CALL_DEBUG_ENTER;
    if (fd == fd_) {
        MMI_HILOGD("Start to libinput_dispatch");
        if (libinput_dispatch(input_) != 0) {
            MMI_HILOGE("Failed to dispatch libinput");
            return;
        }
        OnEventHandler();  // 事件转化
        MMI_HILOGD("End to OnEventHandler");
    } 
    .........
    .........
}
void LibinputAdapter::OnEventHandler()
{
    while ((event = libinput_get_event(input_))) {
        funInputEvent_(event, frameTime);  // 转化为openharmony 对应的系统事件
        libinput_event_destroy(event);     // 事件分发
    }

}

路径: foundation/multimodalinput/input/service/event_handler/src/input_event_handler.cpp

void InputEventHandler::OnEvent(void *event, int64_t frameTime)
{
    .........
    .........

    auto *lpEvent = static_cast<libinput_event *>(event);   // 事件转化
    CHKPV(lpEvent);
    int32_t eventType = libinput_event_get_type(lpEvent);
    int64_t beginTime = GetSysClockTime();
    MMI_HILOGD("Event reporting. id:%{public}" PRId64 ",tid:%{public}" PRId64 ",eventType:%{public}d,"
               "beginTime:%{public}" PRId64, idSeed_, GetThisThreadId(), eventType, beginTime);
    if (IsTouchpadMistouch(lpEvent)) {
        return;
    }
    eventNormalizeHandler_->HandleEvent(lpEvent, frameTime);
    .........
    .........
}

上述函数完成的功能监听 /dev/input 下的驱动节点事件将其转化为openharmony 的系统事件发出。

TP驱动适配方案

方案一 HDF驱动框架适配TP驱动

参考如下Blog
input设备适配HDF框架并和用户态程序交互

方案二 Linux 原生驱动框架适配TP

参考如下Blog
Linux---TP外设调试

补充

适配HDF驱动有如下几点建议:

  1. openharmony 系统层次直接调用驱动接口则需要适配HDF驱动 (例如应用直接调用系统层接口控制GPIO),不与系统层直接交互(如LCD驱动),可根据项目情况考虑是否适配HDF驱动框架
  2. openharmony 系统对Linux原生驱动做了兼容处理,可根据项目情况考虑是否适配HDF驱动框架(例如输入输出等)
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐