Linux/Android——Input系统之InputMapper 处理 (八)【转】
本文转载自:http://blog.csdn.net/jscese/article/details/43561773
前文Linux/Android——Input系统之InputReader (七)介绍到了inputreader的运作流程,如何获取events到初步的分发,依次分析到InputMapper做第一步的处理.
前文有解析Mapper类型的依赖规则,不做重述.,这里单以触摸屏input_device 对应的SingleTouchInputMapper 为例。
撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/43561773本博文来自【 jscese 】的博客!
SingleTouchInputMapper:
原型定义在InputReader.h 中:
- class SingleTouchInputMapper : public TouchInputMapper {
- public:
- SingleTouchInputMapper(InputDevice* device);
- virtual ~SingleTouchInputMapper();
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
- protected:
- virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
- virtual void configureRawPointerAxes();
- virtual bool hasStylus() const;
- private:
- SingleTouchMotionAccumulator mSingleTouchMotionAccumulator;
- };
继承自TouchInputMapper,函数实现全部放在InputReader.cpp中,先看首先调用进的process:
- void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
- TouchInputMapper::process(rawEvent); //调用父类的process
- mSingleTouchMotionAccumulator.process(rawEvent); //数据的同步
- }
继续跟:
- void TouchInputMapper::process(const RawEvent* rawEvent) {
- mCursorButtonAccumulator.process(rawEvent);
- mCursorScrollAccumulator.process(rawEvent);
- mTouchButtonAccumulator.process(rawEvent); //这三个Accumulator 进一步处理rawEvent ,原型都在InputReader.cpp中,根据rawEvent->code 取出对应信息
- ALOGW("jscese dsp TouchInputMapper::process event type==0x%x, code==0x%x, valude ==0x%x \n",rawEvent->type,rawEvent->code,rawEvent->value);
- if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
- sync(rawEvent->when); //同步
- }
- }
上面的几个process 有兴趣可以看下,会依次根据code type抽取对应的信息保存,比如CursorMotionAccumulator 中的 mRelX ,mRelY 代表相对坐标值
作为我调试的触摸框来说这里只在TouchButtonAccumulator中抽取了 BTN_TOUCH 一个按下或者抬起的事件值. ABS_X. ABS_Y 并没有在这里读取。而是在后面的SingleTouchMotionAccumulator::process中.
其它的input 设备就需要看驱动具体上报的code type了.
TouchInputMapper::sync:
从上面分析可以看到。一个rawEvent过来的时候 都会先经过三个process去抽取信息,然后才会检测是否是一个同步sync的rawEent事件,
这也就是为什么 在驱动中 一次完整的事件上报,总是先report一些button res abs之类的,最后来一个sync!
这个同步函数比较长只留意几个地方就可以了:
- void TouchInputMapper::sync(nsecs_t when) {
- ALOGW("TouchInputMapper::sync");
- // Sync button state.
- mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
- | mCursorButtonAccumulator.getButtonState();
- // Sync scroll state.
- ...
- // Sync touch state.
- bool havePointerIds = true;
- mCurrentRawPointerData.clear();
- syncTouch(when, &havePointerIds);//调用子类的syncTouch,这里自然调用的是我 触摸框的 SingleTouchMotionAccumulator的syncTouch,更新ABS 坐标值,我这里是把数据存入到mCurrentRawPointerData中供下面cook
- ...
- // Reset state that we will compute below.
- mCurrentFingerIdBits.clear();
- mCurrentStylusIdBits.clear();
- mCurrentMouseIdBits.clear();
- mCurrentCookedPointerData.clear(); // 先清掉
- ...
- // Cook pointer data. This call populates the mCurrentCookedPointerData structure
- // with cooked pointer data that has the same ids and indices as the raw data.
- // The following code can use either the raw or cooked data, as needed.
- cookPointerData(); //这个函数不跟进去了,太庞大,cook数据,主要是生成 mCurrentCookedPointerData.pointerCoords,mCurrentCookedPointerData.pointerProperties和mCurrentCookedPointerData.idToIndex
- ...
- dispatchTouches(when, policyFlags); //又进行分发
- ...
- //一些数据保存之类的操作
- }
这里正常的处理是调用dispatchTouches 函数 ,往里走是dispatchMotion:
- void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
- int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- const PointerProperties* properties, const PointerCoords* coords,
- const uint32_t* idToIndex, BitSet32 idBits,
- int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
- PointerCoords pointerCoords[MAX_POINTERS];
- PointerProperties pointerProperties[MAX_POINTERS];
- uint32_t pointerCount = 0;
- ...
- getListener()->notifyMotion(&args); //回调
- }
这里是走的signeltouch的所以最终会调用getListener()->notifyMotion(&args),如果是Keydown事件。根据上面的逻辑会在cookPointerData 之前调用synthesizeButtonKeys 依次会调用到context->getListener()->notifyKey(&args);
QueuedInputListener:
上面分析到的notifyMotion最后会调用到这个类中,这个作为inputreader环节的最后交接维护类,回顾一下InputRead的构建,可以看下:
- // --- InputReader ---
- InputReader::InputReader(const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& policy,
- const sp<InputListenerInterface>& listener) //这里注意最后一个参数~
- ...
- {
- mQueuedListener = new QueuedInputListener(listener); //构造了一个QueuedinputListener
- ...
- }
这里又要看下最开始的构造调用了/frameworks/base/services/input/InputManager.cpp中:
- InputManager::InputManager(
- ...
- mDispatcher = new InputDispatcher(dispatcherPolicy);
- mReader = new InputReader(eventHub, readerPolicy, mDispatcher); //可以看到这里传入的是InputDispatcher ,但是上面直接用的InputListenerInterface ,,直接强制转换成了 父类指针! 这里注意一下
- ...
- }
所以在InputReader中构造QueuedInputListener的时候保存的是InputDispatcher的父类指针,保存在私有成员 mInnerListener
- // --- QueuedInputListener ---
- QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
- mInnerListener(innerListener) {
- }
为什么这么做是应为 后续调用的纯虚函数。将会交由InputDispatcher 的函数来实现。实现了一个传递,C++ 就是这样,要整个看明白。才知道设计者写的代码到底跑到哪里去了~
往下分析流程就知道我为什么这么说了.
回到前面,调用 QueuedInputListener::notifyMotion,将这个notifyMotion push进mArgsQueue 链表队列,然后在 loopOnce() 中做完上述一次事件的获取以及分发处理之后将会调用 mQueuedListener->flush();
- void QueuedInputListener::flush() {
- size_t count = mArgsQueue.size();
- for (size_t i = 0; i < count; i++) {
- NotifyArgs* args = mArgsQueue[i];
- args->notify(mInnerListener); //这里依次调用上面push进来的不同种类notify的notify函数,NotifyConfigurationChangedArgs / NotifyKeyArgs / NotifyMotionArgs / NotifySwitchArgs / NotifyDeviceResetArgs 这几种
- delete args;
- }
- mArgsQueue.clear();
- }
这里还是单以我做的notifyMotion为例:
- void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
- listener->notifyMotion(this);
- }
就是这里。又来了一个 notifyMotion调用,这个纯虚函数 ,两个子类QueuedInputListener InputDispatcher 中都有实现,就像上面分析到的,最终是调用到 InputDispatcher 中的notifyMotion !
之后就是InputDispatcher 的处理了,这里不继续。后续再说~
Linux/Android——Input系统之InputMapper 处理 (八)【转】的更多相关文章
- Linux/Android——Input系统之InputReader (七)【转】
本文转载自:http://blog.csdn.net/jscese/article/details/42739197 在前文Linux/Android——Input系统之frameworks层Inpu ...
- Linux/Android——Input系统之frameworks层InputManagerService (六)【转】
本文转载自:http://blog.csdn.net/u013491946/article/details/72638954 版权声明:免责声明: 本人在此发文(包括但不限于汉字.拼音.拉丁字母)均为 ...
- Linux/Android——input系统之 kernel层 与 frameworks层交互 (五)【转】
本文转载自:http://blog.csdn.net/jscese/article/details/42291149 之前的四篇博文记录的都是linux中的input体系相关的东西,最底层以我调试的u ...
- input系统——android input系统
AndroidInput系统--JNI NativeInputManager InputManger InputReader AndroidInput系统--InputReader AndroidIn ...
- Linux/Android——input子系统核心 (三)【转】
本文转载自:http://blog.csdn.net/jscese/article/details/42123673 之前的博客有涉及到linux的input子系统,这里学习记录一下input模块. ...
- Linux 下Input系统应用编程实战
作者:杨源鑫(也是我们的校园代理) 经授权转载于公众号嵌入式开发圈,有些许修改. 什么是input子系统?不管是什么操作系统,都有一个程序用于管理各种输入设备,哪些是输入设备?比如,电脑键盘.鼠标,智 ...
- Linux & Android 多点触摸协议
Linux & Android 多点触摸协议 Android4.0多点触摸入门 1 KERNEL 对于触摸屏的驱动我们简单的划分为两个主要的部分,一个是注册,另一个是上报. 1.1 注册 单点 ...
- Linux/Android——input_handler之evdev (四) 【转】
转自:http://blog.csdn.net/u013491946/article/details/72638919 版权声明:免责声明: 本人在此发文(包括但不限于汉字.拼音.拉丁字母)均为随意敲 ...
- 图解Android - Android GUI 系统 (5) - Android的Event Input System
Android的用户输入处理 Android的用户输入系统获取用户按键(或模拟按键)输入,分发给特定的模块(Framework或应用程序)进行处理,它涉及到以下一些模块: Input Reader: ...
随机推荐
- 大项目之网上书城(八)——数据库大改&添加图书
目录 大项目之网上书城(八)--数据库大改&添加图书 主要改动 1.数据库新增表 代码 2.数据库新增触发器 3.其他对BookService和BookDao的修改 代码 4.addBook. ...
- Python:webshell 跳板机审计服务器
1.修改paramiko源码包实现 https://github.com/paramiko/paramiko/tree/1.10.1 下载源码包 unzip paramiko-1.10.1.zip p ...
- Java 读取linux上的文件
今天遇到一个问题,在Windows环境上开发,测试环境和正式环境服务器都是linux: 一个导出表格的功能,在本地没问题,发布到linux服务器就报找不到文件问题,但是模板文件已经在linux下了.刚 ...
- PHP:验证邮箱合法性
文章来源:http://www.cnblogs.com/hello-tl/p/7592304.html /** * [verifyPhone description] 效验邮箱号合法性 * @para ...
- Java线上应用故障排查
线上故障主要2种: CPU利用率很高, 内存占用率很大 一.CPU利用率很高 1. top查询那个进程CPU使用率高 2. 显示进程列表 ps -mp pid -o THREAD,tid,time 找 ...
- jmeter接口测试实战简例
1.接口需求文档说明 2.打开jmeter,新建线程组,线程组里面默认配置就可以 3.建立http请求,我这里是http请求,所以我选择这个,跟进实际情况 4.post请求说明,post直接加参数和参 ...
- Codeforces Round #364 (Div. 2),只有A与B
A. Cards time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- [NOIP2006] 提高组 洛谷P1066 2^k进制数
题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进制数q后 ...
- SharedPreferences保存用户偏好参数
package com.example.administrator.myapplication; import android.content.Context; import android.cont ...
- 深入理解hadoop(二)
hadoop RPC 网络通信是hadoop的核心模块之一,他支撑了整个Hadoop的上层分布式应用(HBASE.HDFS.MapReduce), Hadoop RPC具有以下几个特性,透明性(用户本 ...