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读取事件概述

Android系统--输入系统(八)Reader线程_使用EventHub读取事件的更多相关文章

  1. 10.5 android输入系统_Reader线程_使用EventHub读取事件和核心类及配置文件_实验_分析

    4. Reader线程_使用EventHub读取事件 使用inotify监测/dev/input下文件的创建和删除 使用epoll监测有无数据上报 细节: a.fd1 = inotify_init(& ...

  2. Android系统--输入系统(九)Reader线程_核心类及配置文件

    Android系统--输入系统(九)Reader线程_核心类及配置文件 1. Reader线程核心类--EventHub 1.1 Reader线程核心结构体 实例化对象:mEventHub--表示多个 ...

  3. Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析

    Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析 0. 前言 个人认为该知识点阅读Android源代码会不仅容易走进死胡同,并且效果并不好,前脚看完后脚忘记,故进行总结, ...

  4. Android系统--输入系统(十一)Reader线程_简单处理

    Android系统--输入系统(十一)Reader线程_简单处理 1. 引入 Reader线程主要负责三件事情 获得输入事件 简单处理 上传给Dispatch线程 InputReader.cpp vo ...

  5. Android系统--输入系统(十二)Dispatch线程_总体框架

    Android系统--输入系统(十二)Dispatch线程_总体框架 1. Dispatch线程框架 我们知道Dispatch线程是分发之意,那么便可以引入两个问题:1. 发什么;2. 发给谁.这两个 ...

  6. Android系统--输入系统(十七)Dispatcher线程_分发dispatch

    Android系统--输入系统(十七)Dispatcher线程_分发dispatch 1. 回顾 InputRead线程从输入设备当中得到输入事件 对于读到输入事件稍作处理,比如紧急事件,来电时候按下 ...

  7. Android系统--输入系统(七)Reader_Dispatcher线程启动分析

    Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...

  8. Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件

    Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件 1. 输入按键 我们知道Android系统的按键分为三类:(1)Global Key;(2)Syste ...

  9. Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理

    Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理 1. 回顾 我们知道Android输入系统是Reader线程通过驱动程序得到上报的输入事件,还要经过处理 ...

随机推荐

  1. apicloud上传图片

    //定义api $("#photo").change(function(){ //获取图片 api.getPicture({ sourceType: 'library', enco ...

  2. GCD浅析

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000 } span.s1 { } 1.关于GCD ...

  3. KoaHub.JS基于Node.js开发的Koa 生成验证码插件代

    ccap node.js generate captcha using c++ library CImg without install any other lib or software node- ...

  4. UIImagePickerController拍照/相册/录像/本地视频

    1.导入系统库 #import <MobileCoreServices/MobileCoreServices.h> 2.遵守协议 <UIImagePickerControllerDe ...

  5. 一个想法照进现实-《IT连》创业项目:三天的风投对接活动内幕分享

    前言: 话说出来创业的,都有一颗寻找风投的心,只因都有一个共同的特征:缺钱. 有的只是缺几十万,有的缺几百万,有的缺几千万,有的缺几个亿. 中国的市场,只要有需求,就有服务,只要有服务,就多了套路. ...

  6. Java集合ArrayList源码解读

    最近在回顾数据结构,想到JDK这样好的代码资源不利用有点可惜,这是第一篇,花了心思.篇幅有点长,希望想看的朋友认真看下去,提出宝贵的意见.  :) 内部原理 ArrayList 的3个字段 priva ...

  7. 有个程序猿要去当CEO了:(一)事情始末

    事情大概是这样的: 去年年底,我从原公司离职,原因大概是公司绩效不好,呆着也没意思. 后来听说,年终结算遣散了所有人. 今年年初的时候,前老板又找上我,说希望能和我再合作. 起先是想分我一部分干股,让 ...

  8. .NET Core项目从xproj+project.json向csproj迁移简介

    3月7日,微软发布了Visual Studio 2017 RTM,与之一起发布的还有.NET Core Runtime 1.1.0以及.NET Core SDK 1.0.0,尽管这些并不是最新版,但也 ...

  9. Octave Tutorial(《Machine Learning》)之第五课《控制语句和方程及向量化》

    第五课 控制语句和方程 For,while,if statements and functions (1)For loop v=zeros(10,1) %initial vectors for i=1 ...

  10. 用shell实现linux系统应用文件清理工具

    用shell实现linux系统文件清理工具 1:原始需求 在系统运维中,会产生大量应用备份文件.落地文件等,这些文件需要定时清理.一般来说,都是使用crontab 拉起一个脚本来清理.类似这样: 30 ...