本文转载自:http://blog.csdn.net/u013491946/article/details/72638954

版权声明:免责声明: 本人在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系 .挖井挑水无水表,不会网购无快递

 
 

上一篇Linux/Android——input系统之 kernel层 与 frameworks层交互 (五)中有介绍kernel层一下以及与Android这边frameworks层之间的联系,算是打通android 应用层与 kernel驱动层,对整个input系统的学习是至关重要的,其中frameworks层只是简单记录了几个接入点,这里开始分析frameworks层的细节部分。

撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42392311

input服务的启动:

android启动的时候会启动很多个service,这个可以参考SystemServer.Java ,会启动InputManagerService这个服务:

  1. Slog.i(TAG, "Input Manager");
  2. inputManager = new InputManagerService(context, wmHandler);
  3. ...
  4. ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

直接看InputManagerService.java中的start函数:

  1. public void start() {
  2. Slog.i(TAG, "Starting input manager");
  3. nativeStart(mPtr);   //调用了本地方法,JNI对应的cpp 在server下的jni目录下
  4. ...
  5. }

这个牵扯到android的server的jni,最开始是在SystemServer中加载android_server这个动态库,

至于这个动态库的编译可参考/frameworks/base/services/jni/Android.mk中的内容

所以在调用这个nativeStart方法时,相关的动态库已经加载到SystemServer的进程中。

先看下这个start函数在jni文件中的实现,frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp中:

  1. static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {
  2. NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);  //这个NativeInputManager 是在上面InputMangerService构造的时候调用nativeInit时new出来的
  3. status_t result = im->getInputManager()->start(); //这里是调用了NativeInputManager中的InputManager中的start方法,同样这个InputManager是NativeInputManager构造的时候new出来的
  4. if (result) {
  5. jniThrowRuntimeException(env, "Input manager could not be started.");
  6. }
  7. }

其实熟悉JNI的话,我分析到这里,就应该差不多了。。对于JNI 不是很了解的话可以参考我之前的博客:Andorid——ubuntu下的 NDK / JNI

看下NativeInputManager构造函数中的:

  1. sp<EventHub> eventHub = new EventHub();
  2. mInputManager = new InputManager(eventHub, this, this);

这里的JNI部分就不多说了,现在就看这个InputManager的start方法,上面提到到Android.mk,可以看到include了一个libinput的动态库,

而这个动态库的路径是在/frameworks/base/services/input下,这就明了啦.此目录下有InputManager.cpp . EventHub.cpp等

直接看start:

  1. status_t InputManager::start() {
  2. status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);  //这个mDispatcherThread是在InputManager构造函数里调用initialize初始化,这里很明显启动了这个名为InputDispatcher的线程
  3. if (result) {
  4. ALOGE("Could not start InputDispatcher thread due to error %d.", result);
  5. return result;
  6. }
  7. result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); //同上,开启线程
  8. if (result) {
  9. ALOGE("Could not start InputReader thread due to error %d.", result);
  10. mDispatcherThread->requestExit();
  11. return result;
  12. }
  13. return OK;
  14. }

到这里算是看到真面目的感觉,看这两个线程,字面意思,一个是分发给input事件给当前的activity的,一个是读取从下层发上来的input事件的

InputDispatcher分发:

从上面的线程启动分析:

  1. bool InputDispatcherThread::threadLoop() {
  2. mDispatcher->dispatchOnce();
  3. return true;
  4. }

调用分发一次的函数:

  1. void InputDispatcher::dispatchOnce() {
  2. nsecs_t nextWakeupTime = LONG_LONG_MAX;
  3. { // acquire lock
  4. AutoMutex _l(mLock);
  5. mDispatcherIsAliveCondition.broadcast();
  6. // Run a dispatch loop if there are no pending commands.
  7. // The dispatch loop might enqueue commands to run afterwards.
  8. if (!haveCommandsLocked()) {           //如果有缓存的命令就调用下面的runCommand去执行,没有的话这里去检查是否有新的input事件,这里定义一个唤醒时间控制
  9. dispatchOnceInnerLocked(&nextWakeupTime);
  10. }
  11. // Run all pending commands if there are any.
  12. // If any commands were run then force the next poll to wake up immediately.
  13. if (runCommandsLockedInterruptible()) {
  14. nextWakeupTime = LONG_LONG_MIN;
  15. }
  16. } // release lock
  17. // Wait for callback or timeout or wake.  (make sure we round up, not down)
  18. nsecs_t currentTime = now();
  19. int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
  20. mLooper->pollOnce(timeoutMillis);  //执行上面一次分发之后,就进入了loop,这个loop会持续的检测对应的管道中是否有内容可读,而另外一个线程InputReader 读取到input事件之后就会往这个管道写入
  21. }

这个是处理input事件的,后续分析,先看怎么读取事件.

InputReader读取:

源码位于frameworks/base/libs/ui/InputReader.cpp ,开启线程如下:

  1. bool InputReaderThread::threadLoop() {
  2. mReader->loopOnce();
  3. return true;
  4. }

这里看这个loopOnce:

  1. void InputReader::loopOnce() {
  2. ...
  3. size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);  //这里去获取event事件
  4. ...
  5. if (count) {
  6. processEventsLocked(mEventBuffer, count); //如果获取到事件,就处理
  7. }
  8. ...
  9. }

可以看到这里就到了获取event事件了。上一篇中有提到!

getEvent中会一直read,直到get到event之后,通过precessevent处理,最终会唤醒上面介绍到的InputDispatcherThread,通知它有新的事件来了

Linux/Android——Input系统之frameworks层InputManagerService (六)【转】的更多相关文章

  1. Linux/Android——input系统之 kernel层 与 frameworks层交互 (五)【转】

    本文转载自:http://blog.csdn.net/jscese/article/details/42291149 之前的四篇博文记录的都是linux中的input体系相关的东西,最底层以我调试的u ...

  2. Linux/Android——Input系统之InputReader (七)【转】

    本文转载自:http://blog.csdn.net/jscese/article/details/42739197 在前文Linux/Android——Input系统之frameworks层Inpu ...

  3. Linux/Android——Input系统之InputMapper 处理 (八)【转】

    本文转载自:http://blog.csdn.net/jscese/article/details/43561773 前文Linux/Android——Input系统之InputReader (七)介 ...

  4. input系统——android input系统

    AndroidInput系统--JNI NativeInputManager InputManger InputReader AndroidInput系统--InputReader AndroidIn ...

  5. Linux/Android——input子系统核心 (三)【转】

    本文转载自:http://blog.csdn.net/jscese/article/details/42123673 之前的博客有涉及到linux的input子系统,这里学习记录一下input模块. ...

  6. Linux 下Input系统应用编程实战

    作者:杨源鑫(也是我们的校园代理) 经授权转载于公众号嵌入式开发圈,有些许修改. 什么是input子系统?不管是什么操作系统,都有一个程序用于管理各种输入设备,哪些是输入设备?比如,电脑键盘.鼠标,智 ...

  7. Linux & Android 多点触摸协议

    Linux & Android 多点触摸协议 Android4.0多点触摸入门 1 KERNEL 对于触摸屏的驱动我们简单的划分为两个主要的部分,一个是注册,另一个是上报. 1.1 注册 单点 ...

  8. Linux/Android——input_handler之evdev (四) 【转】

    转自:http://blog.csdn.net/u013491946/article/details/72638919 版权声明:免责声明: 本人在此发文(包括但不限于汉字.拼音.拉丁字母)均为随意敲 ...

  9. SQLite数据库学习小结——Frameworks层实现

    3. SQLite的Frameworks层实现 3.1 Frameworks层架构 Android系统方便应用使用,在Frameworks层中封装了一套Content框架,之所以叫Content框架而 ...

随机推荐

  1. h5移动端常见虚拟键盘顶起底部导航栏解决办法

    在h5移动端开发中相信很多朋友跟我一样都会遇到页面底部导航被虚拟键盘顶起的问题,自己在网上找到的解决办法拿出来与大家分享,有不完美之处还望见谅,有更好的解决办法可以贴出来大家一起互相学习!! var ...

  2. 「 Luogu P2196 」 挖地雷

    # 解题思路 跑 $\text{n}$ 遍 $\text{spfa}$ 并记录路径,找到比当前最长路长的就更新答案,并且将路径也更新,注意起点的处理. # 附上代码 #include <iost ...

  3. 笔试算法题(16):二叉树深度计算 & 字符串全排列

    出题:要求判断二元树的深度(最长根节点到叶节点的路径): 分析:二元递归不容易使用循环实现 解题: struct Node { int value; Node *left; Node *right; ...

  4. HashMap、ConcurrentHashMap以及HashTable(面试向)

    ---->HashMap 在java1.7中,hashmap的数据结构是基于数组+链表的结构,即我们比较熟悉的Entry数组,其包含的(key-value)键值对的形式.在多线程环境下,Hash ...

  5. 当执行计划中出现BITMAP CONVERSION TO ROWIDS关键字时,需要注意了。

    前言 前些天优化了一些耗费buffers较多的SQL,但系统CPU降低的效果不明显,于是又拉了awr报告,查看了SQL ordered by Gets排名前列的SQL. 分析 SQL代码: selec ...

  6. rbac组件之菜单操作(三)

    菜单包括菜单列表,菜单列表不仅将菜单列出来,而且将每个菜单下的权限也列出来.菜单的添加.删除.修改. urls.py ... re_path(r'^menus/list/$', MenuView.as ...

  7. 绑定IP 绑定设备

    首先引别人的组播测试如下 1. 一个udp client可以同时往多个组播地址发送数据,多个udpclient可以同时往一个组播发数据. 2. 本地udp必须监听组播端口,否则收不到数据.3. 一个u ...

  8. About SQL Server 2014 SP1

    其实补丁这个月初就放出,个人懒惰所以也没怎么写归整文档 官方Blog: http://blogs.technet.com/b/dataplatforminsider/archive/2015/05/1 ...

  9. typeof instanceof操作符的相关知识

    数据类型 ECMAScript中有5中基本数据类型:Undefined Null Boolean Number String. Typeof运算符 对一个值使用typeof操作符可能返回下列某个字符串 ...

  10. Floyd算法实现总结

    问题描述 给出图,求任意两点的最短距离 算法思路 定义n+1个矩阵矩阵A,和记录路径的矩阵path 依次求A0~An的值,最后的An即为最短路径矩阵 // int A[8][7][7],path[7] ...