Android系统--输入系统(八)Reader线程_使用EventHub读取事件

1. Reader线程工作流程

  • 获得事件

size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
  • 简单处理

processEventsLocked(mEventBuffer, count);
  • 将事件分发给Dispatch线程处理

mQueuedListener->flush();

2. Reader线程获得事件分析

2.1 事件结构体描述

struct RawEvent {nsecs_t when;int32_t deviceId;int32_t type;int32_t code;int32_t value;};
2.2 事件类型

事件类型type:

  • DEVICE_ADDED(输入设备插入)

  • DEVICE_REMOVED(输入设备被拔出)

  • FINISHED_DEVICE_SCAN(与Device相关的事件)

  • EV_KEY

  • EV_ABS

  • EV_REL

2.3 驱动层上报输入事件


struct input_event{struct timeval time;__u16 type;__u16 code;__s32 value;};

上报事件类型Type:

  • EV_KEY

  • EV_ABS

  • EV_REL

2.4 驱动层上报输入事件给上层概述

当输入设备有数据产生,驱动程序将该事件数据上报,上层的Reader线程将读取驱动程序,获得Input_event结构体,然后将Input_event结构体直接构造成RawEvent结构体进行处理。

3. 输入设备拔插检测实现

3.1 实现原理
  • 使用inotify机制来检测目录下的文件变化

  • 使用epoll机制来检测目录下的文件是否有数据

3.2 实现过程分析
  • 初始化得到文件句柄--fd1 = inotify_init(/dev/input/event0);

  • 检测对象--inotify_add_watch(fd1,目录/文件,创建/删除);

  • 将输入事件加入epoll池中,监听事件行为--add_to_epoll(mINotifyFd, mEpollFd);

由EventHub构造函数实现

EventHub.cpp


EventHub::EventHub(void) :mEpollFd = epoll_create(EPOLL_SIZE_HINT);LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);mINotifyFd = inotify_init();int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s.  errno=%d",DEVICE_PATH, errno);struct epoll_event eventItem;memset(&eventItem, 0, sizeof(eventItem));eventItem.events = EPOLLIN;eventItem.data.u32 = EPOLL_ID_INOTIFY;result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);int wakeFds[2];result = pipe(wakeFds);mWakeReadPipeFd = wakeFds[0];mWakeWritePipeFd = wakeFds[1];result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);eventItem.data.u32 = EPOLL_ID_WAKE;result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);}
  • 在ScanDeviceLocked()函数中,实现对设备函数的打开

    • fd2 = open("/dev/input/event1");

    • fd3 = open("/dev/input/event2");

  • 使用epoll_wait检测fd1,fd2,fd3

  • 读取文件句柄,构造RawEvent结构体;getEvent的循环

    • 如果是增加输入设备,还需要open,并将其加入epoll_wait

    • 如果是拔出输入设备,从epoll中删去


if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {if (eventItem.events & EPOLLIN) {mPendingINotify = true;}

readNotifyLocked.c


status_t EventHub::readNotifyLocked() {res = read(mINotifyFd, event_buf, sizeof(event_buf));while(res >= (int)sizeof(*event)) {event = (struct inotify_event *)(event_buf + event_pos);//printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");if(event->len) {strcpy(filename, event->name);if(event->mask & IN_CREATE) {openDeviceLocked(devname);} else {ALOGI("Removing device '%s' due to inotify event\n", devname);closeDeviceByPathLocked(devname);}}event_size = sizeof(*event) + event->len;res -= event_size;event_pos += event_size;}return 0;}
  • 如果是输入设备有数据,读取Input_event

size_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32);if (deviceIndex < 0) {ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.",eventItem.events, eventItem.data.u32);continue;}Device* device = mDevices.valueAt(deviceIndex);if (eventItem.events & EPOLLIN) {int32_t readSize = read(device->fd, readBuffer,sizeof(struct input_event) * capacity);}
  • 将input_event结构体构造为RawEvent结构体
event->deviceId = deviceId;event->type = iev.type;event->code = iev.code;event->value = iev.value;

4. 使用EventHub读取事件概述

转载于:https://www.cnblogs.com/lkq1220/p/6743279.html

Android系统--输入系统(八)Reader线程_使用EventHub读取事件相关推荐

  1. Android系统--输入系统(一)必备的Linux知识_inotify和epoll

    Android系统--输入系统(一)必备的Linux知识_inotify和epoll 引入 1. 笔记本电脑插入外接键盘,两个键盘都可以使用 a. 键盘即插即用--如何检测键盘的接入和拔出 hotpl ...

  2. Linux系统编程(八)线程

    Linux系统编程(八)线程 一.什么是线程? 二.Linux内核线程实现原理 线程共享资源 线程非共享资源 线程优缺点 线程控制原语 一.什么是线程? LWP:light weight proces ...

  3. Android Input 输入系统学习

    原文在https://blog.csdn.net/kehyuanyu/article/details/48573211 Android输入设备的映射 使用指令dumpsys input 可以看到以下信 ...

  4. android dispatch input输入子系统,10.12 android输入系统_InputStage理论

    android应用程序对输入系统的处理分为多个阶段,我们把这些阶段称为InputStage 理论处理流程: (1)activity发给window,如果window不能处理,再由activity处理; ...

  5. Android | 输入系统(IMS)

    前言 一般情况下很多同学对于点击事件的认识都只存在于从 Activity 开始的,然后从 Window 中进行分发,甚至有些人可能也只知道 onTouchEvent 和 dispatchTouchEv ...

  6. Android输入系统IMS(1)--基础知识epoll和notify

    做Android系统三年多,量产项目也有3~4个了,却从来没写过相关博客,最近换工作到新东家报道前这段时间比较闲写写博客总结一下这些年对Android系统的了解.先挑个相对简单的ims下手. epol ...

  7. Android 系统(57)---深入理解Android输入系统

    <深入理解Android 卷III>第五章 深入理解Android输入系统 <深入理解Android 卷III>即将发布,作者是张大伟.此书填补了深入理解Android Fra ...

  8. android 输入法框架,Android输入系统(2)——输入系统框架(Android+Linux)

    1.优秀文档 android输入系统官方文档:http://source.android.com/devices/input/index.html 中文官方文档 <深入理解Android 卷II ...

  9. Android 源码 输入系统之 InputReader

    InputReaderThread 线程负责读取事件.InputReaderThread 启动后会执行 threadLoop 函数.threadLoop 函数返回 true,InputReaderTh ...

最新文章

  1. 国内C/C++刷题网站汇总
  2. 【2019暑假刷题笔记-链表】总结自《算法笔记》
  3. 《OEA - 实体扩展属性系统 - 设计方案说明书》
  4. 每个程序员都必须知道的8种通用数据结构
  5. java多因子认证,Milvus 实战|生物多因子认证系列 (二):人脸识别
  6. 面向对象程序设计中“超类”和“子类”概念的来历
  7. My Calendar I
  8. java final对象_JAVA final 与 不可变对象
  9. FMDB在Swift中的基本使用
  10. OSAL 添加一个LED任务
  11. Windows Server AppFabric
  12. Linux驱动学习--ALSA框架(三)PCM设备的创建--以SCO虚拟声卡为例
  13. 如何退出或卸载奇安信天擎软件
  14. pdf会签_图纸会签规定
  15. 1000道最新高频Java面试题,覆盖25个技术栈(多线程、JVM、高并发、spring、微服务、kafka,redis、分布式)从底层原理到架构!
  16. 如何注册和设置 zoom Background
  17. java数据类型、常量与变量、内部存储
  18. python入门--常用的numpy函数:arange()
  19. LC6936-TWS耳机方案
  20. 300个韩国网站欣赏

热门文章

  1. Spring mvc @SessionAttribute
  2. jinja Template Synopsis
  3. linux 内核/proc
  4. java 正则表达式
  5. opencv-api boxPoints
  6. python壁纸数据抓取_python 多线程爬取壁纸网站的示例
  7. oracle 连接数_Oracle多租户数据库资源管理,就这么简单
  8. vSAN 6.7培训_第1章-Virtual SAN各版本功能介绍
  9. VMware NSX 6组件通信图
  10. 敏捷开发系列学习总结(13)——Spotify敏捷模式详解三部曲第一篇:研发团队