参考: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. NETCore 同步AD域组织和用户

    BitAdminCore为没有自主开发框架的小团队,提供快速项目搭建及开发能力. 框架演示:http://bit.bitdao.cn 框架源码:https://github.com/chenyinxi ...

  2. javacript 实现瀑布流原理和效果, 滚动加载图片【图文解析 附源码】

    先科普下瀑布流吧 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pin ...

  3. C博客第01次作业---顺序,分支结构

    1.本章学习总结 1.1 思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 经过了这一周的学习,从一开始对C语言一无所知,到现在能够写出基本的代码,感到非常开心. 学习C语言也并非想象 ...

  4. 关于布尔值bool值

    1.空或0布尔值为false,非0或非空为true 2.多个判断连在一起判断优先级:(括号)>not >and >or and:    print(27 and 1>4)  - ...

  5. 动态代理方案性能对比 (CGLIB,ASSIT,JDK)

    动态代理工具比较成熟的产品有: JDK自带的,ASM,CGLIB(基于ASM包装),JAVAASSIST, 使用的版本分别为: JDK-1.6.0_18-b07, ASM-3.3, CGLIB-2.2 ...

  6. jdk命令行工具(一)

    1.概述 熟悉java开发的人应该都知道在jdk的bin目录下有许多的工具,这些工具主要用于监视虚拟机和故障处理.这些故障处理工具被Sun公司称作为“礼物”附赠给JDK的使用者,并在软件的使用说明中把 ...

  7. 苹果的 Metal 工程

    Basic Buffers 当向顶点着色器传递数据过多(大于 4096 字节)时, setVertexBytes:length:atIndex: 方法不允许使用,应该使用 setVertexBytes ...

  8. day 14 自定义模块,常用模块 time .datetime ,time 模块

    内容大纲 一:Import  模块 1,创建一个以tbjx命名的名称空间 2,执行此模块的代码,并将所有内容加载到内存 3,调用此模块的代码要通过tbjx.的方式 二:from 包 import 模块 ...

  9. 对drf视图的理解

    视图说明 1. 两个基类 1)APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父 ...

  10. 题目1002:Grading(简单判断)

    问题来源 http://ac.jobdu.com/problem.php?pid=1002 问题描述 题目背景为高考试卷批改打分制度.对于每一道题,至少需要两位评审老师进行打分, 当两个老师的打分结果 ...