EventHub分析(二)
来源:互联网 发布:2016淘宝搜索排名规则 编辑:程序博客网 时间:2024/05/04 17:35
2, EventHub
一台移动设备中能产生输入消息的部件很多,比如键盘,触摸屏以及按键等等,EventHub主要是将这些设备产生的消息打包成一种格式,再发往上层进行处理.
首先看看EventHub的构造函数,
EventHub::EventHub(void) : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(), mOpeningDevices(0), mClosingDevices(0), mNeedToSendFinishedDeviceScan(false), mNeedToReopenDevices(false), mNeedToScanDevices(true), mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 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); LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno); int wakeFds[2]; result = pipe(wakeFds); LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); mWakeReadPipeFd = wakeFds[0]; mWakeWritePipeFd = wakeFds[1]; result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", errno); result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", errno); eventItem.data.u32 = EPOLL_ID_WAKE; result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem); LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", errno); int major, minor; getLinuxRelease(&major, &minor); // EPOLLWAKEUP was introduced in kernel 3.5 mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5);}
这里面涉及的是linux驱动的知识,反正知道会监视目录文件 /dev/input就可以了。
在getEvents方法中,
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {•••if (mNeedToScanDevices) { mNeedToScanDevices = false; scanDevicesLocked(); mNeedToSendFinishedDeviceScan = true; }•••}
如果是第一次调用getEvents方法,则会调用scanDevicesLocked方法来扫描设备,
void EventHub::scanDevicesLocked() { status_t res = scanDirLocked(DEVICE_PATH); if(res < 0) { ALOGE("scan dir failed for %s\n", DEVICE_PATH); } if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) { createVirtualKeyboardLocked(); }}
static const char *WAKE_LOCK_ID = "KeyEvents";static const char *DEVICE_PATH = "/dev/input";
直接看scanDirLocked方法,
status_t EventHub::scanDirLocked(const char *dirname){ char devname[PATH_MAX]; char *filename; DIR *dir; struct dirent *de; dir = opendir(dirname); if(dir == NULL) return -1; strcpy(devname, dirname); filename = devname + strlen(devname); *filename++ = '/'; while((de = readdir(dir))) { if(de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) continue; strcpy(filename, de->d_name); openDeviceLocked(devname); } closedir(dir); return 0;}
scanDirLocked打开目录/dev/input 目录后,对目录下的每个文件都调用
openDeviceLocked方法,在该目录下存放的并不是设备,而是event文件,这些event文件对应的设备信息可以在文件 /proc/bus/input/devices中可以查看。不同的设备对应不同的文件。
openDeviceLocked方法太长,首先打开设备并获取设备的信息,然后判断设备的类型,根据类型来初始化,最后为设备创建一个InputDevice对象,然后调用addDeviceLocked方法将InputDevice对象添加到EventHub的mDevices列表中。
总体的流程图如下:
0 0
- EventHub分析(二)
- Android Input流程分析(二):EventHub
- Android Input Framework(二)---EventHub
- Android Input Framework(二)---EventHub
- Android Input Framework(二)---EventHub
- eventhub
- EventHub
- Android 输入系统(二)EventHub
- eventhub类的device 结构体分析
- Android输入事件流程中的EventHub分析及源码演示
- Android输入事件流程中的EventHub分析及源码演示
- Android输入事件流程中的EventHub分析及源码演示
- Android输入事件流程中的EventHub分析及源码演示
- 对“Android输入事件流程中的EventHub分析及源码演示”的补充
- android学习笔记6 eventhub
- android学习笔记6 eventhub
- Microsoft Azure eventhub相关文档
- vue data: { eventHub: new Vue() }
- LeetCode371/104/389
- SharedPreference的封装
- PAT甲级1095
- [UOJ171][WC2016] 挑战NPC 一般图最大匹配
- Towards Scalable Emotion Classification in Microblog Based on Noisy Training Data
- EventHub分析(二)
- 【BootStrap】栅格系统、表单样式与按钮样式-附有源码
- Yii隐藏URL中index.php的方法
- MAC Can't connect to MySQL server on '127.0.0.1' (61)
- 互动游戏网页抽签版
- builtwith的使用
- 一.jenkins+github+gradle 实现android自动化打包全攻略(MAC版)
- java.lang.NoSuchMethodError:org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/e
- [Matlab] 三视图查看3D矩阵