参考: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 输入子系统分析(未完)的更多相关文章

  1. 7.Linux 输入子系统分析

    为什么要引入输入子系统? 在前面我们写了一些简单的字符设备的驱动程序,我们是怎么样打开一个设备并操作的呢? 一般都是在执行应用程序时,open一个特定的设备文件,如:/dev/buttons .... ...

  2. 12.Linux之输入子系统分析(详解)

    版权声明:本文为博主原创文章,转载请标注出处:   在此节之前,我们学的都是简单的字符驱动,涉及的内容有字符驱动的框架.自动创建设备节点.linux中断.poll机制.异步通知.同步互斥/非阻塞.定时 ...

  3. linux input输入子系统分析《四》:input子系统整体流程全面分析

    1      input输入子系统整体流程 本节分析input子系统在内核中的实现,包括输入子系统(Input Core),事件处理层(Event Handler)和设备驱动层.由于上节代码讲解了设备 ...

  4. linux内核输入子系统分析

    1.为何引入input system? 以前我们写一些输入设备(键盘.鼠标等)的驱动都是采用字符设备.混杂设备处理的.问题由此而来,Linux开源社区的大神们看到了这大量输入设备如此分散不堪,有木有可 ...

  5. SpaceSyntax【空间句法】之DepthMapX学习:第四篇 凸多边形图分析[未完]

    这一篇正式讲解分析类型中的第一个,凸多边形分析,流程图参照上一篇的. 博客园/B站/知乎/CSDN @秋意正寒(我觉得这一篇肯定很多盗图的,那么我在版头加个本篇地址吧) https://www.cnb ...

  6. Universal-Image-Loader(UIL)使用方法&流程图&源码分析 ----- 未完

    GitHub源码: Android-Universal-Image-Loader Features Multithread image loading (async or sync) 多线程加载(同步 ...

  7. SQL注入蠕虫分析//未完待续

    蠕虫代码: DECLARE @S VARCHAR(4000);SET @S=CAST(0x4445434C415245204054205641524348415228323535292C4043205 ...

  8. Linux输入子系统 转载

    NQian 记录成长~ 首页 新随笔 联系 订阅 管理 随笔 - 305  文章 - 0  评论 - 254 12.Linux之输入子系统分析(详解)   在此节之前,我们学的都是简单的字符驱动,涉及 ...

  9. Linux输入子系统框架分析(1)

    在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...

随机推荐

  1. (zxing.net)二维码QR Code的简介、实现与解码

    一.简介 二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字 ...

  2. 基于JSP的在线考试系统-JavaWeb项目-有源码

    开发工具:Myeclipse/Eclipse + MySQL + Tomcat 系统简介: 网络考试系统主要用于实现高校在线考试,基本功能包括:自动组卷.试卷发布.试卷批阅.试卷成绩统计等.本系统结构 ...

  3. 2018-2019-2 20165219《网络对抗技术》Exp0 Kali安装 Week1

    2018-2019-2 20165219<网络对抗技术>Exp0 Kali安装 Week1 安装Kali 在官网下载,然后将解压后的文件导入 输入username和password 共享文 ...

  4. byte转文件流 下载到本地

    此方法将byte类型文件转为文件流保存到本地 byte 经过BASE64Decoder 进行编码之后的类型 所以需要解码 防止出现乱码及文件损毁 /** * byte 转文件 下载到本地 * @par ...

  5. Java_多线程2_线程池

    线程池(pool): 线程池的作用: 1.节省资源,减少线程的数量和创建销毁线程的开销2.合理的管理线程的分配 线程池的创建: 1.newCachedThreadPool //优点:很灵活,弹性的线程 ...

  6. C语言数据结构之图的基本操作

    本博文是是博主在学习数据结构图的这一章知识时做的一些总结,代码运行环境:visual studio2017 纯C语言 ,当然掌握了方法,你也可以试着用其它的语言来实现同样的功能. 下面的程序主要实现了 ...

  7. Python抓取远程文件获取真实文件名

    用urllib下载远程文件并转存到hdfs服务器,在下载时,下载地址中不一定包含文件名,需要从连接信息中获取. 1 file_url = request.form.get('file_url') 2 ...

  8. P1525 关押罪犯 题解

    #include<iostream> #include<cstdio> #include<algorithm> using namespace std; //带边权 ...

  9. 【性能测试】脚本开发,最普通的http协议脚本2

    Action() { lr_start_transaction("FM0075基金购买"); web_submit_data("ehouse_ehGetPwdRandom ...

  10. How to install Jenkins on CentOS 7

    How to install Jenkins on CentOS 7 on March 3, 2018 by AmirLeave a comment Introduction Jenkins is a ...