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. Not supported by Zabbix Agent & zabbix agent重装

    zabbix服务器显示一些监控项不起效,提示错误[Not supported by Zabbix Agent], 最后定位为zabbix客户端版本过低. Not supported by Zabbix ...

  2. Jedis-returnResource使用注意事项

    遇到过这样一个严重问题: 发布的项目不知从什么时候开始,每月会出现一两次串号问题.串号现象指的是,用户用账号A登录系统,然后某个时间,登录账号自动变成了B. 串号出现的时间不定,测试平台难以重现,且后 ...

  3. 在eclipse-jee-juno中配置Aptana对jQuery代码自动提示

    主要问题 在Aptana的Web Project中打开js文件有JavaScript的自动提示,但是在JavaEE项目中却没有. 版本 eclipse-jee-juno,即Eclipse 4.2的Ja ...

  4. 一天搞定CSS: 浮动(float)与inline-block的区别--11

    浮动: 使元素脱离文档流,按照指定的方向发生移动,遇到父级的边界或者相邻的浮动元素就会停下来. inline-block: inline-block是指行内块元素,它具有行内元素和块元素两者的特点,可 ...

  5. 使用外部容器运行spring-boot项目:不使用spring-boot内置容器让spring-boot项目运行在外部tomcat容器中

    前言:本项目基于maven构建 spring-boot项目可以快速构建web应用,其内置的tomcat容器也十分方便我们的测试运行: spring-boot项目需要部署在外部容器中的时候,spring ...

  6. tr的用法

    一.tr的基本功能 功能:转换.挤压或删除字符串,从标准输入接收输入,输出到标准输出基本用法:tr [options] string1 [string2] 二.例子 1.转换 $ echo " ...

  7. springmvc 之 DispatcherServlet

    DispatcherServlet说明 使用Spring MVC,配置DispatcherServlet是第一步. DispatcherServlet是一个Servlet,所以可以配置多个Dispat ...

  8. 关于getHTML()方法和getHtmlAjax()方法 GetHttpLength, 清除HTML标签

    public string getHtml(string Url, string type = "UTF-8") { try { System.Net.WebRequest wRe ...

  9. Mysql数据库存储emoji表情

    emoji表情需要使用编码格式未utf8mb4,mysql数据库版本要5.5以上,我用的是5.6,因为只有5.5以上支持utf8mb4. 1.数据库编码设定为utf8mb4,如果建库时指定的是utf8 ...

  10. nodejs 字符串全排列 和 去重

    以前写了个java版的 现在写个nodejs 版的 var list = sort('CCAV');var noRepeat = {};for(var i in list){ noRepeat[lis ...