i.mx android6 输入子系统分析(未完)
参考:http://blog.csdn.net/u010312937/article/details/53285286
https://www.jianshu.com/p/7fca94b330ea
注意:关于下面的一些时序图,如果看不清,可以使用下载后再看,源码我已经放在GitHub上,工具为bouml,
GitHub地址为:https://github.com/maogefff/Other/tree/master
也可以使用我将时序图转化为PNG图片以后的,GitHub地址为:https://github.com/maogefff/Other/tree/inputSystem
1. 框架
InputManagerService(IMS)
Linux内核,接受输入设备的中断,并将原始事件的数据写入设备节点中,设备节点作为内核与IMS的桥梁,将原始事件的数据暴露给用户空间,以便IMS可以从中读取事件
InputManagerService,一个android系统服务,分为Java层和Native层两部分,java层负责与WMS通信,而Native层则是InputReader和InputDispatcher两个输入系统关键组件的运行容器
EventHub,直接访问所有的设备节点,通过一个名为getEvents()的函数将所有输入系统相关的待处理的底层事件返回给使用者,包括原始输入事件,设备节点的增删等
InputReader,是IMS中的关键组件之一,它运行一个独立的线程中,负责管理输入设备的列表和配置,以及进行输入事件的加工处理,它通过其线程循环不断地通过getEvents()函数从EventHub中将事件取出并进行处理,对于设备节点的增删事件,它会更新输入设备列表与配置,对于原始输入事件,InputReader对其进行翻译,组装,封装为包含更多信息,更多可读性的输入事件,然后交给InputDispatcher进行派发
InputReaderPolicy,为InputReader的事件加工处理提供一些策略配置,例如键盘布局信息等。
InputDispatcher,是IMS中的另一个关键组件,运行于一个独立的线程中,InputDispatcher中保管来自WMS的所有窗口的信息,收到InputReader的输入事件后,会在其保管的窗口中寻找合适的窗口,并将事件派发给此窗口
InputDispatcherPolicy,为InputDispatcher的派发过程提供策略控制,例如HOME键被InputDispatcherPolicy截取到PhoneWindowManager中处理,并阻止窗口收到HOME键按下的事件
WMS,并不是输入系统的一员,新建窗口时,WMS为新窗口和IMS创建了事件传递所用的通道,会将窗口的可点击区域,焦点窗口等信息实时更新到IMS的InputDispatcher中,使得InputDispatcher可以正确将事件派发到指定窗口
ViewRootImpl,对某些窗口,如壁纸窗口,SurfaceView的窗口来说,窗口就是输入事件派发的终点,而对其他的如Activity,对话框等使用了Android控件系统的窗口来说,输入事件的终点是控件
运行流程
简单来说,内核将原始事件写入到设备节点中,InputReader不断地通过EventHub将原始事件取出来并翻译加工成Android输入事件,然后交给InputDispatcher。InputDispatcher根据WMS提供的窗口信息将事件交给合适的窗口。窗口的ViewRootImpl对象再沿着控件树将事件派发给感兴趣的控件。控件对其收到的事件作出响应,更新自己的画面、执行特定的动作。所有这些参与者以IMS为核心,构建了Android庞大而复杂的输入体系。
2. 阅读代码后的总结
2.1 启动创建流程
图2.1非常重要;就是Android层输入子系统的创建流程,看不清可以github上下载下来看,黄色为JAVA代码,红色为CPP代码,蓝色为CPP代码所在文件
大致思路:
SystemServer创建整个输入子系统InputManagerService类用来管理整个输入子系统 (JAVA层)
InputManagerService调用构造函数然后调用nativeInit(调用到C++层)创建本地管理者NativeInputManager,然后创建各种累
下面有三个重要的功能类(这三个功能详看第一节)
EventHub: 实例化对象为eventHub
InputReader: 实例化对象为mReader
InputDispatcher:实例化对象为mDispatcher
还有三个重要的类:
InputManager: 实例化对象为minputManager ;主要作用为管理下面两个线程,mReaderThread和mDispathcerThread
InputReaderThread: 实例化对象为mReaderThread ;为一个线程的对象,主要作用为管理mReader
InputDispatcherThread: 实例化对象为mDispathcerThread ;为一个线程的对象,主要作用为管理mDispatcher
图2.1 创建输入系统时序图
图2.2 类之间的包含关系
2.2 InputReaderThread和EventHub的流程
(一). InputReaderThread流程:
InputReader如下图2.3所示,主要负责三个方面的工作:
1. 获得事件(事件是通过EventHub获取,包括:1. 设备节点的增删事件; 2. 原始输入事件)
2. 对事件进行简单的处理(1. 对于设备节点的增删事件(更新设备列表和配置); 2. 原始输入事件(进行翻译和组装))
3. 将处理后的事件分发给dispatch
(二). EventHub流程:
EventHub如2.3所示,主要负责检测设备节点增删事件和原始输入事件
通过inotify检测/dev/input文件夹是否有节点增删,通过epoll分别检测/dev/input/xxx里面的内容是否有修改
1. 通过epoll_wait等待获取事件(无事件等待)
2. 获取增删事件后
3. 获取原始输入事件后
下面是伪代码:
getEvents(RawEvent* buffer)
{
//检测目录是否有增删
fd1 = inotify.init("/dev/input"); //打开具体设备节点
fd2 = open("/dev/input/event0");
fd3 = open("/dev/input/event1"); //同时检测文件和文件夹
int pollResult = epoll_wait(fd1, fd2, fd3); switch(){
case 增加了一个设备节点:
buffer.type = DEVICE_ADDED;
fd4 = open("dev/input/xxx");
epoll_wait(fd1, fd2, fd3, fd4); //在epoll_wait里再增加一个fd4
break; case 减少了一个设备节点:
buffer.type = DEVICE_REMOVE;
epoll_wait(fd1, fd2, fd3); //在epoll_wait里再删除掉fd4
break; case 文件内容修改了:
buffer.xxx = xxx; //构造RawEvent
break;
}
}
黄色代码类名,蓝色代表所在文件(注意:时序图在EventHub.cpp当中有点问题,loop不是包含第三个,而是包含整个)
图2.3 readThread时序图
3. InputManagerService(IMS)流程分析
3.1 启动流程:
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
...
private void run() {
...
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices(); //其他服务里面
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void startOtherServices() {
...
NsdService serviceDiscovery= null;
WindowManagerService wm = null; //窗口管理服务
...
InputManagerService inputManager = null; //输入管理服务
... Slog.i(TAG, "Input Manager");
//创建输入系统
inputManager = new InputManagerService(context); Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
//将输入系统加入系统服务当中,以便其他人可以方便的访问(包括应用程序)
ServiceManager.addService(Context.INPUT_SERVICE, inputManager); mActivityManagerService.setWindowManager(wm); //设置输入系统的回调函数:设置向WMS发起回调
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
//启动输入系统服务
inputManager.start();
...
}
i.mx android6 输入子系统分析(未完)的更多相关文章
- 7.Linux 输入子系统分析
为什么要引入输入子系统? 在前面我们写了一些简单的字符设备的驱动程序,我们是怎么样打开一个设备并操作的呢? 一般都是在执行应用程序时,open一个特定的设备文件,如:/dev/buttons .... ...
- 12.Linux之输入子系统分析(详解)
版权声明:本文为博主原创文章,转载请标注出处: 在此节之前,我们学的都是简单的字符驱动,涉及的内容有字符驱动的框架.自动创建设备节点.linux中断.poll机制.异步通知.同步互斥/非阻塞.定时 ...
- linux input输入子系统分析《四》:input子系统整体流程全面分析
1 input输入子系统整体流程 本节分析input子系统在内核中的实现,包括输入子系统(Input Core),事件处理层(Event Handler)和设备驱动层.由于上节代码讲解了设备 ...
- linux内核输入子系统分析
1.为何引入input system? 以前我们写一些输入设备(键盘.鼠标等)的驱动都是采用字符设备.混杂设备处理的.问题由此而来,Linux开源社区的大神们看到了这大量输入设备如此分散不堪,有木有可 ...
- SpaceSyntax【空间句法】之DepthMapX学习:第四篇 凸多边形图分析[未完]
这一篇正式讲解分析类型中的第一个,凸多边形分析,流程图参照上一篇的. 博客园/B站/知乎/CSDN @秋意正寒(我觉得这一篇肯定很多盗图的,那么我在版头加个本篇地址吧) https://www.cnb ...
- Universal-Image-Loader(UIL)使用方法&流程图&源码分析 ----- 未完
GitHub源码: Android-Universal-Image-Loader Features Multithread image loading (async or sync) 多线程加载(同步 ...
- SQL注入蠕虫分析//未完待续
蠕虫代码: DECLARE @S VARCHAR(4000);SET @S=CAST(0x4445434C415245204054205641524348415228323535292C4043205 ...
- Linux输入子系统 转载
NQian 记录成长~ 首页 新随笔 联系 订阅 管理 随笔 - 305 文章 - 0 评论 - 254 12.Linux之输入子系统分析(详解) 在此节之前,我们学的都是简单的字符驱动,涉及 ...
- Linux输入子系统框架分析(1)
在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...
随机推荐
- 在jquery中怎么使用css类名和id来获取元素?
在jquery中,你可以很容易的使用CSS类名和id类获取元素. 例如: 1.ID:#id $('#idA')——选择id为idA的所有元素,不管元素的标签名如何. $('div#idA')——选择i ...
- 解决“找不到请求的 .Net Framework Data Provider。可能没有安装.”错误
问题: 这几天在装.NET 的开发环境,在装好VS2013和Oracle 11g之后,做了一个测试项目,运行调试没问题 但是涉及到数据库相关操作,如新建数据集.连接数据库等在调试的时候则会出现如下错误 ...
- 在VC++中执行VBS代码
此代码来自https://blog.csdn.net/zhu2695/article/details/13770671 作者: zhu2695 时间:2013年10月31日 13:08:41 #i ...
- [uwp]MVVM模式实战之必应壁纸查看器
最近学习MVVM,至于什么是MVVM我也在这儿不多说了,一是关于它的解释解释网上非常多,二是我怕自己讲不清,误导自己没关系,误导别人就不好了.. 好了,废话结束,看是实战...... 这个必应壁纸的d ...
- RabbitMq初探——消息持久化
消息持久化 前言 通过上一节,我们知道,有消息确认机制,保证了当消费者进程挂掉后,消息的不丢失. 但是如果rabbitmq挂掉呢?它的队列和消息都会丢失的.为了保证消息在rabbitmq挂掉重启后不丢 ...
- 自动统计安卓log中Anr,Crash,Singnal出现数量的Python脚本 (转载)
自动统计安卓log中Anr,Crash,Singnal出现数量的Python脚本 转自:https://www.cnblogs.com/ailiailan/p/8304989.html 作为测试, ...
- Syncthing源码解析 - 启动过程
我相信很多朋友会认为启动就是双击一下Syncthing程序图标,随后就启动完毕了!如果这样认为,对,也不对!对,是因为的确是这样操作,启动了Syncthing:不对是因为在调试Syncthing启动过 ...
- Delphi XE2 新增 System.Zip 单元,压缩和解压缩文件
Delphi XE2 新增 System.Zip 单元, 可用一句话压缩整个文件夹了 单元内主要就是 TZipFile 类, 最方便使用的是它的类方法: TZipFile.ExtractZipFile ...
- java学习笔记—Servlet技术(11)
如果大家要开发一个动态的网站,那么就必须要学习一种动态的网页开发技术.那么在SUN提供的JavaEE中主要包含两种开发动态网页的技术:Servlet和JSP技术. Servlet技术简介 Servle ...
- 利用django form 模块处理post请求
在django框架中,利用 form 模块处理post请求提交的数据,可以大大提高开发效率,减小代码冗余度,提高性能 models.py 中: from django.db import models ...