Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件

1. 输入按键

我们知道Android系统的按键分为三类:(1)Global Key;(2)System Key;(3)User Key

  • Global Key:按下一个按键,启动某个APP。 具体使用哪个按键启动哪个APP可以自己指定,修改\frameworks\base\core\res\res\xml\Global_keys.xml,接下来有一篇博文具实现,假设它是AKEYCODE_TV

  • System Key:比如音量键(AKEYCODE_VOLUME_DOWN)

  • User Key:其他按键,比如ABCD(AKEYCODE_A)

2. 回顾

2.1 概述

Reader线程把驱动上报的scancode根据.kl文件转化为keycode,Dispatch线程根据所获得keycode进行处理。Android Dispatch线程对这三类按键的处理

* Global Key
* System Key
* User Key
2.2 具体处理流程
  1. Reader线程将输入事件稍作处理
  2. Reader线程会将输入事件放入mInBoundQueue队列中
  3. Dispatch线程将从mInBoundQueue队列中取出输入事件,稍作处理
  4. 再将处理后的输入事件放入mOutBoundQueue队列
  5. 最后再从mOutBoundQueue队列中取出来,发给目的应用

3. 阅读源码分析三种按键的处理过程

之前已经分析了Reader线程从驱动程序得到扫描码之后,根据.KL文件,得到对应的按键码,然后构造args参数,接着使用NotifiyKey将该参数告诉Reader线程的Listener,而Reader线程的监听者肯定为Dispatch线程,要想验证,可以通过源代码分析得出。

3.1 Golbal Key分析

1. Reader线程获得他的Listener,调用notifykey做进一步的处理
InputReader.cpp
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2. 放入队列之前,稍作处理

2.1 调用Java里面PhoneWindowManager的同名函数

2.2 根据返回值设置policeFlags,对于global按键直接返回Pass_To_User

InputDispatch.cpp
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
3. 放入mInboundQueue队列
InputDispatch.cpp
needWake = enqueueInboundEventLocked(newEntry);
4. 必要时候唤醒Dispatch线程
InputDispatch.cpp
if (needWake) {
mLooper->wake();
}

3.2 System Key分析

1. Reader线程获得他的Listener,调用notifykey做进一步的处理
InputReader.cpp
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2. 放入队列之前,稍作处理

2.1 调用Java里面PhoneWindowManager的同名函数,分类处理

  • 可以处理的紧急事件,处理他,设置返回值为:!Pass_to_user
  • 返回pass_to_user
InputDispatch.cpp
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
3. 放入mInboundQueue队列
InputDispatch.cpp
needWake = enqueueInboundEventLocked(newEntry);
4. 必要时候唤醒Dispatch线程
InputDispatch.cpp
if (needWake) {
mLooper->wake();
}

3.3 User Key分析

1. Reader线程获得他的Listener,调用notifykey做进一步的处理
InputReader.cpp
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2. 放入队列之前,稍作处理

2.1 调用Java里面PhoneWindowManager的同名函数

2.2 根据返回值设置policyFlags,对于用户按键直接返回Pass_To_User

InputDispatch.cpp
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
3. 放入mInboundQueue队列
InputDispatch.cpp
needWake = enqueueInboundEventLocked(newEntry);
4. 必要时候唤醒Dispatch线程
InputDispatch.cpp
if (needWake) {
mLooper->wake();
}

4. DIspatch流程修订图

从上文分析可知,不论是否Pass_to_user,最终都要放入到队列mInboundQueue当中去,上篇博客总结的流程图有点错误,故进行修改,具体如下图。

Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件的更多相关文章

  1. 10.7 android输入系统_Dispatcher线程情景分析_Reader线程传递事件和dispatch前处理

    android输入系统C++最上层文件是com_android_serve_input_InputManagerService.cpp global key:按下按键,启动某个APP可以自己指定,修改 ...

  2. Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理

    Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理 1. 回顾 我们知道Android输入系统是Reader线程通过驱动程序得到上报的输入事件,还要经过处理 ...

  3. Android系统--输入系统(十七)Dispatcher线程_分发dispatch

    Android系统--输入系统(十七)Dispatcher线程_分发dispatch 1. 回顾 InputRead线程从输入设备当中得到输入事件 对于读到输入事件稍作处理,比如紧急事件,来电时候按下 ...

  4. Android系统--输入系统(七)Reader_Dispatcher线程启动分析

    Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...

  5. Android系统--输入系统(八)Reader线程_使用EventHub读取事件

    Android系统--输入系统(八)Reader线程_使用EventHub读取事件 1. Reader线程工作流程 获得事件 size_t count = mEventHub->getEvent ...

  6. Android系统--输入系统(九)Reader线程_核心类及配置文件

    Android系统--输入系统(九)Reader线程_核心类及配置文件 1. Reader线程核心类--EventHub 1.1 Reader线程核心结构体 实例化对象:mEventHub--表示多个 ...

  7. Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析

    Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析 0. 前言 个人认为该知识点阅读Android源代码会不仅容易走进死胡同,并且效果并不好,前脚看完后脚忘记,故进行总结, ...

  8. Android系统--输入系统(十一)Reader线程_简单处理

    Android系统--输入系统(十一)Reader线程_简单处理 1. 引入 Reader线程主要负责三件事情 获得输入事件 简单处理 上传给Dispatch线程 InputReader.cpp vo ...

  9. Android系统--输入系统(十二)Dispatch线程_总体框架

    Android系统--输入系统(十二)Dispatch线程_总体框架 1. Dispatch线程框架 我们知道Dispatch线程是分发之意,那么便可以引入两个问题:1. 发什么;2. 发给谁.这两个 ...

随机推荐

  1. python利用selenium和safari浏览器驱动实现新浪微博自动点赞 Demo

    import time from selenium import webdriver browser = webdriver.Safari() browser.get('http://weibo.co ...

  2. 外部无法捕捉Realm的doGetAuthenticationInfo方法抛出的异常

    shiro权限框架,用户登录方法的subject.login(token)会进入自定义的UserNamePasswordRealm类的doGetAuthenticationInfo身份验证方法 通常情 ...

  3. Centos7下安装部署MXNET

    Centos下安装MXNET,参考官方文档http://mxnet.io/get_started/setup.html#prerequisites, 一.安装python的mxnet步骤如下: #!/ ...

  4. 生成JSON数据--官方方法

    官方生成方法: 1)需要什么就给什么,要属性就给属性,要对象就给对象,要集合就给集合 2)添加都是使用put()方法 要求: 1.生成如下JSON数据: {"age":4,&quo ...

  5. Idea中执行TestNg报错

    今天在Idea中使用TestNg过程中报错: java.lang.AbstractMethodError: org.testng.remote.RemoteTestNG$DelegatingTestR ...

  6. JQuery--Ajax 异步操作 动态添加节点 (新人试水,求支持)

    异步操作动态添加节点,导致在代码中给添加的节点全局绑定事件或者获取元素无效,上代码: $(function () { var IP = '...'; // 页面中的默认编号起始值 和 公用IP前缀 s ...

  7. dedecms 动态tab写法

    项目要求要dedecms动态添加选项卡然后自己写了一个 现在需要些tab的栏目下创建子栏目 (如果是首页需要顶级栏目) 如图我在案例下添加了3个子栏目 然后每个子栏目里面添加需要在tab里面输出的内容 ...

  8. 解决Ubuntu SMPlayer播放视频无声音问题

    问题:Ubuntu Kylin 14.04 系统默认装好之后,smplayer播放视频都是正常的,但最近可能由于一些误设置,导致smplayer播放任何格式的视频都无声.解决方法:由于ALSA是Lin ...

  9. 将数据库从服务器移到浏览器--indexedDB基本操作封装

    数据库是属于服务器的,这是天经地义的事,但是有时候数据也许并非需要存储在服务器,但是这些数据也是一条一条的记录,怎么办?今天来带领你领略一下H5的一个新特性--indexedDB的风骚.你会情不自禁的 ...

  10. Python原理 -- 深浅拷贝

    python原理 -- 深浅拷贝 从数据类型说开去 str, num : 一次性创建, 不能被修改, 修改即是再创建. list,tuple,dict,set : 链表,当前元素记录, 下一个元素的位 ...