Android输入系统之InputReader(AndroidV)

一:概述

    由前文Android输入系统之启动篇(AndroidV)-CSDN博客可知,InputReader线程用于读取Input事件,是input系统的起始点,下面来看下InputReader线程是如何工作的。

二:InputReader的启动

    InputReader线程启动后,先从EventHub中读取input事件,具体事件的读取流程可以参考Android输入系统之EventHub(AndroidV)_eventhub: no input device configuration file found-CSDN博客,这里就不多介绍了。读取到有input事件发生后,会把事件校准、包装然后发送给InputDispatcher。

//frameworks/native/services/inputflinger/reader/InputReader.cpp
void InputReader::loopOnce() {
    ...
    //从EventHub中读取事件
    std::vector<RawEvent> events = mEventHub->getEvents(timeoutMillis);

    { // acquire lock
        std::scoped_lock _l(mLock);
        ...
        //处理事件,把将要分发的事件包装成NotifyMotionArgs并赋值给mPendingArgs
        if (!events.empty()) {
            mPendingArgs += processEventsLocked(events.data(), events.size());
        }
        ...
        //把mPendingArgs赋值给notifyArgs
        std::swap(notifyArgs, mPendingArgs);
        ...
    } // release lock

    ...
    //发送事件到InputDispatcher
    for (const NotifyArgs& args : notifyArgs) {
        mNextListener.notify(args);
    }

    ...
    //输入设备发生改变
    if (inputDevicesChanged) {
        mPolicy->notifyInputDevicesChanged(inputDevices);
    }
    ...
}

三:input事件的处理

  3.1 InputReader.processEventsLocked

    根据事件的类型(设备添加、设备移除、设备搜索完成、input),执行不同的逻辑

//frameworks/native/services/inputflinger/reader/InputReader.cpp
std::list<NotifyArgs> InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    std::list<NotifyArgs> out;
    for (const RawEvent* rawEvent = rawEvents; count;) {
        int32_t type = rawEvent->type;
        size_t batchSize = 1;
        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
            ...
            //处理输入事件
            out += processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
        } else {
            switch (rawEvent->type) {
                case EventHubInterface::DEVICE_ADDED://设备添加
                    addDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                case EventHubInterface::DEVICE_REMOVED://设备移除
                    removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                case EventHubInterface::FINISHED_DEVICE_SCAN://设备搜索完成
                    handleConfigurationChangedLocked(rawEvent->when);
                    break;
                default:
                    ALOG_ASSERT(false); // can't happen
                    break;
            }
        }
        count -= batchSize;
        rawEvent += batchSize;
    }
    return out;
}

3.2 InputReader.addDeviceLocked

    input事件触发的前提必然是设备已经正常添加,所以在梳理input事件处理流程之前,先看下设备添加事件的处理流程。大致流程如下

  • 创建InputDevice对象
  • 根据设备的类型创建对应的InputMapper
  • 把InputDevice对象添加到mDevices中
//frameworks/native/services/inputflinger/reader/InputReader.cpp
void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
    ...
    //创建InputDevice对象
    std::shared_ptr<InputDevice> device = createDeviceLocked(when, eventHubId, identifier);
    ...
    //把InputDevice对象添加到mDevices中
    mDevices.emplace(eventHubId, device);
    //在mDeviceToEventHubIdsMap通过device查找看是否已经保存该设备
    const auto mapIt = mDeviceToEventHubIdsMap.find(device);
    if (mapIt == mDeviceToEventHubIdsMap.end()) {//没有保存
        std::vector<int32_t> ids = {eventHubId};
        //把eventHubId和device保存到mDeviceToEventHubIdsMap中
        mDeviceToEventHubIdsMap.emplace(device, ids);
    } else {
        mapIt->second.push_back(eventHubId);
    }
    ...
}

//frameworks/native/services/inputflinger/reader/InputReader.cpp
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
        nsecs_t when, int32_t eventHubId, const InputDeviceIdentifier& identifier) {
    ...
    if (deviceIt != mDevices.end()) {
        device = deviceIt->second;
    } else {
        ...
        //创建InputDevice对象
        device = std::make_shared<InputDevice>
### Android Input 子系统架构与组件 #### 架构概述 Android输入系统负责处理来自各种硬件设备的输入事件,如触摸屏、键盘和其他传感器。该子系统通过分层结构来管理这些输入数据流,确保应用程序能够高效响应用户的交互。 #### 主要组成部分 ##### 输入驱动程序 位于内核空间中的输入驱动程序直接与物理硬件通信并收集原始输入数据。对于特定架构的支持可能包含在机器专用代码中[^2]。当检测到新的输入时,驱动会将其转换成标准化格式并通过`/dev/input/eventX`文件节点暴露给用户空间。 ##### Input Manager Service (IMS) 这是框架服务的一部分,在用户空间运行。它接收由Input Reader解析后的事件消息,并决定如何分配这些事件至相应的窗口或应用进程。此外,还承担着协调多点触控操作以及手势识别等功能。 ##### Input Dispatcher 作为IMS内部的一个模块,专门用于调度已过滤和解释过的输入事件给目标Window对象。此过程涉及复杂的优先级判断机制以保证用户体验流畅度。 ##### Input Readers 同样属于IMS范畴内的功能单元,主要职责是从底层读取经过编码的二进制形式的输入报告,并解码成为易于理解和使用的Java类表示法——即MotionEvent、KeyEvent等实例。 ```java // 示例:注册一个简单的按键监听器 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); View rootView = findViewById(android.R.id.content); rootView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { Log.d("MainActivity", "KeyCode: " + keyCode); return false; } }); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值