Android14 InputManager-InputManagerService环境的构造
IMS分为Java层与Native层两个部分,其启动过程是从Java部分的初始化开始,进而完成Native部分的初始化。
□创建新的IMS对象。
□调用IMS对象的start()函数完成启动
同其他系统服务一样,IMS在SystemServer中的ServerThread线程中启动。
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("startOtherServices");
inputManager = new InputManagerService(context);inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());inputManager.start();
创建新的IMS对象
线程 mLooper = DisplayThread.get().getLooper()
构造NativeInputManagerService
/** Point of injection for test dependencies. */@VisibleForTestingstatic class Injector {private final Context mContext;private final Looper mLooper;Injector(Context context, Looper looper) {mContext = context;mLooper = looper;}Context getContext() {return mContext;}Looper getLooper() {return mLooper;}NativeInputManagerService getNativeService(InputManagerService service) {return new NativeInputManagerService.NativeImpl(service, mLooper.getQueue());}void registerLocalService(InputManagerInternal localService) {LocalServices.addService(InputManagerInternal.class, localService);}}public InputManagerService(Context context) {this(new Injector(context, DisplayThread.get().getLooper()));}
class NativeImpl implements NativeInputManagerService {/** Pointer to native input manager service object, used by native code. */@SuppressWarnings({"unused", "FieldCanBeLocal"})private final long mPtr;NativeImpl(InputManagerService service, MessageQueue messageQueue) {mPtr = init(service, messageQueue);}
nativeInit()函数创建了一个类型为NativeInputManager的对象,它是Java层与Native层互相通信的桥梁。
com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,jobject messageQueueObj) {sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);if (messageQueue == nullptr) {jniThrowRuntimeException(env, "MessageQueue is not initialized.");return 0;}static std::once_flag nativeInitialize;NativeInputManager* im = nullptr;std::call_once(nativeInitialize, [&]() {// Create the NativeInputManager, which should not be destroyed or deallocated for the// lifetime of the process.im = new NativeInputManager(serviceObj, messageQueue->getLooper());});LOG_ALWAYS_FATAL_IF(im == nullptr, "NativeInputManager was already initialized.");return reinterpret_cast<jlong>(im);
}
看下这个类的声明可以发现,它实现了InputReaderPolicyInterface与InputDispatcher-PolicyInterface两个接口。这说明上一节曾经介绍过的两个重要的输入系统参与者InputReaderPolicy和InputDispatcherPolicy是由NativeInputManager实现的,然而它仅仅为两个策略提供接口实现而已,并不是策略的实际实现者。NativeInputManager通过JNI回调Java层的IMS,由它完成决策。本节暂不讨论其实现细节,读者只要先记住两个策略参与者的接口实现位于NativeInputManager即可。
4 class NativeInputManager : public virtual InputReaderPolicyInterface,
265 public virtual InputDispatcherPolicyInterface,
266 public virtual PointerControllerPolicyInterface {
NativeInputManager构造如下:
1、创建一个全局引用,并通过mServiceObj指向上层的InputManagerService对象
2、创建并注册服务InputManager。
原来,InputManager才是底层输入系统的服务,而NativeInputManagerService通过mServiceObj保存了上层InputManagerService引用,并且上层InputManagerService通过mPtr指向底层的NativeInputManager。因此,我们可以判定NativeInputManagerService就是一个连接上层与底层的桥梁。
NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& looper): mLooper(looper), mInteractive(true) {JNIEnv* env = jniEnv();mServiceObj = env->NewGlobalRef(serviceObj);InputManager* im = new InputManager(this, *this);mInputManager = im;defaultServiceManager()->addService(String16("inputflinger"), im);
}
InputManager.cpp
InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,InputDispatcherPolicyInterface& dispatcherPolicy) {mDispatcher = createInputDispatcher(dispatcherPolicy); 4、创建InputDispatcher对象,使用InputReaderPolicyInterfacemProcessor = std::make_unique<InputProcessor>(*mDispatcher);mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mProcessor);mReader = createInputReader(readerPolicy, *mBlocker); 4、创建InputReader对象,使用InputReaderPolicyInterface和InputListenerInterface
}
可以看到InputManager
主要做以下几件事:
- 构造InputDispatcher对象;(用于后续事件分发处理)
- 构造InputReader对象;(用于事件输入监听)
- 调用InputDispatcher和InputReader的start()方法;
InputManager构造函数所使用的两个接口,分别由InputDispatcher和InputReader所使用。因此InputManager向上通信的能力是由子模块InputDispatcher和InputReader实现的。
InputManager创建了,InputReader、InputDispatcher。
InputReader负责从EventHub中获取事件,然后把事件加工后,发送给InputClassifier。
最后InputDispatcher会对事件进行分发。
frameworks/native/services/inputflinger/dispatcher/InputDispatcherFactory.cppstd::unique_ptr<InputDispatcherInterface> createInputDispatcher(InputDispatcherPolicyInterface& policy) {return std::make_unique<android::inputdispatcher::InputDispatcher>(policy);
}
std::unique_ptr<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener) {return std::make_unique<InputReader>(std::make_unique<EventHub>(), policy, listener);
}
调用IMS对象的start()函数完成启动
public void start() {Slog.i(TAG, "Starting input manager");mNative.start();
}
static void nativeStart(JNIEnv* env, jobject nativeImplObj) {NativeInputManager* im = getNativeInputManager(env, nativeImplObj);status_t result = im->getInputManager()->start();if (result) {jniThrowRuntimeException(env, "Input manager could not be started.");}
}
status_t InputManager::start() {status_t result = mDispatcher->start();if (result) {ALOGE("Could not start InputDispatcher thread due to error %d.", result);return result;}result = mReader->start();if (result) {ALOGE("Could not start InputReader due to error %d.", result);mDispatcher->stop();return result;}return OK;
}
启动mDispatcher和mReader
status_t InputReader::start() {if (mThread) {return ALREADY_EXISTS;}mThread = std::make_unique<InputThread>("InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });return OK;
}
status_t InputDispatcher::start() {if (mThread) {return ALREADY_EXISTS;}mThread = std::make_unique<InputThread>("InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });return OK;
}
相关文章:
Android14 InputManager-InputManagerService环境的构造
IMS分为Java层与Native层两个部分,其启动过程是从Java部分的初始化开始,进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start()函数完成启动 同其他系统服务一样,IMS在SystemServer中的ServerT…...
搜维尔科技:【周刊】适用于虚拟现实VR中的OptiTrack
适用于 VR 的 OptiTrack 我们通过优化对虚拟现实跟踪最重要的性能指标,打造世界上最准确、最易于使用的广域 VR 跟踪器。其结果是为任何头戴式显示器 (HMD) 或洞穴自动沉浸式环境提供超低延迟、极其流畅的跟踪。 OptiTrack 主动式 OptiTrack 世界领先的跟踪精度和…...
matlab倒立摆小车LQR控制动画
1、内容简介 略 54-可以交流、咨询、答疑 2、内容说明 略 摆杆长度为 L,质量为 m 的单级倒立摆(摆杆的质心在杆的中心处),小车的质量为 M。在水平方向施加控制力 u,相对参考系产生位移为 y。为了简化问题并且保其实质不变,忽…...
【C++】类和对象(2)
目录 1. 初始化列表 2.explicit关键字 3. Static成员 3. 友元 3.1友元函数 3.2友元类 4. 内部类 5.匿名对象 1. 初始化列表 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值,但是这个过程并不能称为对对…...
用Python实现创建十二星座数据分析图表
下面小编提供的代码中,您已经将pie.render()注释掉,并使用了pie.render_to_file(十二星座.svg)来将饼状图渲染到一个名为十二星座.svg的文件中。这是一个正确的做法,如果您想在文件中保存图表而不是在浏览器中显示它。 成功创建图表…...
备战蓝桥杯————递归反转单链表的一部分
递归反转单链表已经明白了,递归反转单链表的一部分你知道怎么做吗? 一、反转链表Ⅱ 题目描述 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反…...
rabbitmq知识梳理
一.WorkQueues模型 Work queues,任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息。 当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,…...
【数据结构与算法】动态规划法解题20240227
动态规划法 一、什么是动态规划二、动态规划的解题步骤三、509. 斐波那契数1、动规五部曲: 四、70. 爬楼梯1、动规五部曲: 五、746. 使用最小花费爬楼梯1、动规五部曲: 一、什么是动态规划 动态规划,英文:Dynamic Pro…...
备战蓝桥杯—— 双指针技巧巧答链表2
对于单链表相关的问题,双指针技巧是一种非常广泛且有效的解决方法。以下是一些常见问题以及使用双指针技巧解决: 合并两个有序链表: 使用两个指针分别指向两个链表的头部,逐一比较节点的值,将较小的节点链接到结果链表…...
半监督节点分类-graph learning
半监督节点分类相当于在一个图当中,用一部分节点的类别上已知的,有另外一部分节点的类别是未知的,目标是使用有标签的节点来推断没有标签的节点 注意 半监督节点分类属于直推式学习,直推式学习相当于出现新节点后,需要…...
软件文档-运维-开发-管理-资质-评审-招投标-验收
开发文档:这类文档主要用于记录软件的开发过程和细节,包括: 《功能要求》:描述了软件应具备的功能,是软件开发的基础。《投标方案》:向潜在的客户或招标方展示公司的技术和项目实施能力。《需求分析》&…...
猫头虎分享已解决Bug || Vue中的TypeError: Cannot read property ‘name‘ of undefined 错误
博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …...
技术应用:使用Spring Boot、MyBatis Plus和Dynamic DataSource实现多数据源
引言 在现代的软件开发中,许多应用程序需要同时访问多个数据库。例如,一个电子商务平台可能需要访问多个数据库来存储用户信息、产品信息和订单信息等。在这种情况下,使用多数据源是一种常见的解决方案,它允许我们在一个应用程序…...
C# Onnx 使用onnxruntime部署实时视频帧插值
目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx 使用onnxruntime部署实时视频帧插值 介绍 github地址:https://github.com/google-research/frame-interpolation FILM: Frame Interpolation for Large Motion, In ECCV 2022. The official Tensorflow 2…...
编程笔记 Golang基础 016 数据类型:数字类型
编程笔记 Golang基础 016 数据类型:数字类型 1. 整数类型(Integer Types)a) 固定长度整数:b) 变长整数: 2. 浮点数类型(Floating-Point Types)3. 复数类型(Complex Number Types&…...
一周学会Django5 Python Web开发-会话管理(CookiesSession)
锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计26条视频,包括:2024版 Django5 Python we…...
QT之QString.arg输出固定位数
问题描述 我需要用QString输出一个固定位数的数字字符串。起初我的代码是这样: int img_num 1 auto new_name QString("%1.png").arg((int)img_num, 3, 10, 0); //最后一个参数用u0也是一样的 qDebug() << "new_name:" << new…...
Linux下各种压缩包的压缩与解压
tar 归档,不压缩,常见后缀 .tar # 将文件夹归档成为一个包 tar cf rootfs.tar rootfs # 将归档包还原为文件夹 tar xf rootfs.tar # 将归档包还原到路径 a/b/c tar xf rootfs.tar -C a/b/cgzip压缩, 常见后缀 .tar.gz .tgz # 压缩 tar czf …...
【ctfshow—web】——信息搜集篇1(web1~20详解)
ctfshow—web题解 web1web2web3web4web5web6web7web8web9web10web11web12web13web14web15web16web17web18web19web20 web1 题目提示 开发注释未及时删除 那就找开发注释咯,可以用F12来查看,也可以CtrlU直接查看源代码呢 就拿到flag了 web2 题目提示 j…...
GEE入门篇|遥感专业术语(实践操作4):光谱分辨率(Spectral Resolution)
目录 光谱分辨率(Spectral Resolution) 1.MODIS 2.EO-1 光谱分辨率(Spectral Resolution) 光谱分辨率是指传感器进行测量的光谱带的数量和宽度。 您可以将光谱带的宽度视为每个波段的波长间隔,在多个波段测量辐射亮…...
c++中模板的注意事项
1. 模板定义时,<>中的虚拟类型参数不能为空。(因为我们使用模板就是希望使用模拟类型代替其它的类型,如果我们不定义就没有意义了) 2. 无论是定义函数模板还是类模板,其实template定义与后面使用虚拟类型的类或者函数,是…...
【代码随想录python笔记整理】第十三课 · 链表的基础操作 1
前言:本笔记仅仅只是对内容的整理和自行消化,并不是完整内容,如有侵权,联系立删。 一、链表 在之前的学习中,我们接触到了字符串和数组(列表)这两种结构,它们具有着以下的共同点:1、元素按照一定的顺序来排列。2、可以通过索引来访问数组中的元素和字符串中的字符。由此,…...
JAVA工程师面试专题-《Mysql》篇
目录 一、基础 1、mysql可以使用多少列创建索引? 2、mysql常用的存储引擎有哪些 3、MySQL 存储引擎,两者区别 4、mysql默认的隔离级别 5、数据库三范式 6、drop、delete 与 truncate 区别? 7、IN与EXISTS的区别 二、索引 1、索引及索…...
@ 代码随想录算法训练营第4周(C语言)|Day22(二叉树)
代码随想录算法训练营第4周(C语言)|Day22(二叉树) Day22、二叉树(包含题目 ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点 ) 235. 二叉搜索树的最近公…...
福特锐界2021plus 汽车保养手册
福特锐界2021plus汽车保养手册两页,零部件保养要求,电子版放这里方便查询:...
c++进阶路线
学完C后的进阶路线-初学者勿入【程序员Rock】_哔哩哔哩_bilibili 1.系统训练代码阅读能力 代码阅读工具: 1).Source Insight(阅读大型源码) 2).understand(整体代码模块关系构建) 3).SOURCETRAIL 代码阅读能力--千行级 嵌入…...
python中的类与对象(2)
目录 一. 类的基本语法 二. 类属性的应用场景 三. 类与类之间的依赖关系 (1)依赖关系 (2)关联关系 (3)组合关系 四. 类的继承 一. 类的基本语法 先看一段最简单的代码: class Dog():d_…...
Android横竖屏切换configChanges=“screenSize|orientation“避免activity销毁重建,Kotlin
Android横竖屏切换configChanges"screenSize|orientation"避免activity销毁重建,Kotlin 如果不在Androidmanifest.xml设置activity的: android:configChanges"screenSize|orientation" 那么,每次横竖屏切换activity都会…...
【C语言基础】:操作符详解(二)
文章目录 操作符详解一、上期扩展二、单目操作符三、逗号表达式四、下标访问[]、 函数调用()五、结构成员访问操作符六、操作符的属性:优先级、结合性1. 优先级2. 结合性 操作符详解 上期回顾:【C语言基础】:操作符详解(一) 一、上期扩展 …...
模型训练基本结构
project_name/ │ ├── data/ │ ├── raw/ # 存放原始数据 │ ├── processed/ # 存放预处理后的数据 │ └── splits/ # 存放数据集划分(训练集、验证集、测试集等) │ ├── noteboo…...
安庆城乡建设局网站/国产免费crm系统有哪些在线
说明 POI可以对2003-和2007版本的Excel文件做导入导出操作,本章只简单介绍对Excel文件的导入操作。 Excel文件的上传处理处理请求,依然使用SpringMvc中的MultipartRequest方式处理。前端JSP中使用传统form表单提交方式。环境 MavenJDK6 Tomcat7.x Sprin…...
网站开发用php还是.net好/网络推广app是干什么的
ldd : 列出一个可执行文件在运行时需要的共享库信息 ar : 创建静态库,插入,删除,列出和提取成员 strings : 列出文件中的所有可打印字符串strip : 从目标文件中删除符号表信息nm : 列出目标文件中符号表中定义的符号size : 列出目标文件中…...
a5源码网站/色盲怎么治疗
Python实战社群Java实战社群长按识别下方二维码,按需求添加扫码关注添加客服进Python社群▲扫码关注添加客服进Java社群▲作者丨zvving来源丨老司机技术周报(LSJCoding)作者:zvving,iOS 开发者,现就职于字节…...
Wordpress电脑版需要下载吗/搜索引擎优化方法总结
在HttpServletRequest,您可以使用以下方法获取URI的各个部分。您也可以使用它们逐块重构URL(以帮助调试或其他任务),如下所示:// Example: http://myhost:8080/people?lastnameFox&age30String uri request.getScheme() "://&quo…...
广东手机版建站系统开发/谷歌推广网站
关注公众号【秋叶 Excel】回复关键词【工具】获取 Excel 高效小工具合集,让你效率开挂!本文作者:竺兰本文来源:秋叶Excel(ID:Excel100)本文编辑:思雨、竺兰距离下班还有俩小时,我伸了伸懒腰,想着…...
网络营销与策划实训/长沙网站优化推广方案
结果为: [2,3] 和 [2] array.splice(start[, deleteCount[, item1[, item2[, …]]]]) splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。 start: 指定修改的开始位置(从0计数) i…...