Android7 InputReader InputDispatcher Key Touch

本文详细介绍了Android系统中输入事件的一般流程,从EventHub的多路复用监听,到InputReader的事件收集,再到InputDispatcher的事件派发,以及InputManager的管理作用。同时,讨论了Key和Touch的调试工具、框架原理和常见需求,如按键映射、触屏事件处理和自动化测试优化。
摘要由CSDN通过智能技术生成

Android 输入事件的一般流程

EventHub

  1. EventHub 事件枢纽,可以多路复用监听/dev/input/目录 文件的变化;
  2. getEvents步骤:
    (1) . 开始循环执行,直至已经收集了任何事件,或者我们被显式地唤醒,立即返回。
    a. Reopen input devices if needed.
    b. Report any devices that had last been added/removed.
    c. scan devices if Needed, add devices / remove devices.
    d. product adding devices event if needed.
    e. product finishing scan devices event if needed.
    f. start grab the next input event really. //多路复用监听fd,
    g. readNotify()将修改设备列表,因此必须在处理所有其他事件之后完成,以确保在关闭设备之前读取所有剩余事件。
    h. 若上一个动作执行,Report added or removed devices immediately.
    i. 如果我们已经收集了任何事件,或者我们被显式地唤醒,立即返回。

多路复用监听事件补充:

		/*
		man help:
		EPOLLIN       连接到达;有数据来临;
		The associated file is available for read(2) operations.
		EPOLLOUT      有数据要写
		The associated file is available for write(2) operations.
		EPOLLRDHUP    表示读关闭。
		如果有EPOLLRDHUP,检测它就可以直到是对方关闭;否则就用上面方法。
		EPOLLHUP 表示读写都关闭。
		*/
					if (eventItem.events & EPOLLIN) {
   
					...
		            } else if (eventItem.events & EPOLLHUP) {
   
		                ALOGI("Removing device %s due to epoll hang-up event.",
		                        device->identifier.name.string());
		                deviceChanged = true;
		                closeDeviceLocked(device);
		            } else {
   
		                ALOGW("Received unexpected epoll event 0x%08x for device %s.",
		                        eventItem.events, device->identifier.name.string());
		            }

事件枢纽EventHub重点代码(getEvents 函数):

size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
   
    ALOG_ASSERT(bufferSize >= 1);

    AutoMutex _l(mLock);

    struct input_event readBuffer[bufferSize];

    RawEvent* event = buffer;
    size_t capacity = bufferSize;
    bool awoken = false;
    for (;;) {
   
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

        // Reopen input devices if needed.
        if (mNeedToReopenDevices) {
   
            mNeedToReopenDevices = false;

            ALOGI("Reopening all input devices due to a configuration change.");

            closeAllDevicesLocked();
            mNeedToScanDevices = true;
            break; // return to the caller before we actually rescan
        }

        // Report any devices that had last been added/removed.
        while (mClosingDevices) {
   
            Device* device = mClosingDevices;
            ALOGV("Reporting device closed: id=%d, name=%s\n",
                 device->id, device->path.string());
            mClosingDevices = device->next;
            event->when = now;
            event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
            event->type = DEVICE_REMOVED;
            event += 1;
            delete device;
            mNeedToSendFinishedDeviceScan = true;
            if (--capacity == 0) {
   
                break;
            }
        }

        if (mNeedToScanDevices) {
   
            mNeedToScanDevices = false;
            scanDevicesLocked();
            mNeedToSendFinishedDeviceScan = true;
        }

        while (mOpeningDevices != NULL) {
   
            Device* device = mOpeningDevices;
            ALOGV("Reporting device opened: id=%d, name=%s\n",
                 device->id, device->path.string());
            mOpeningDevices = device->next;
            event->when = now;
            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
            event->type = DEVICE_ADDED;
            event += 1;
            mNeedToSendFinishedDeviceScan = true;
            if (--capacity == 0) {
   
                break;
            }
        }

        if (mNeedToSendFinishedDeviceScan) {
   
            mNeedToSendFinishedDeviceScan = false;
            event->when = now;
            event->type = FINISHED_DEVICE_SCAN;
            event += 1;
            if (--capacity == 0) {
   
                break;
            }
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值