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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

股票K线认知从形态到逻辑,仓位管理与交易体系实战

一、教程描述 本套教程内容分为三个部分&#xff0c;1、基础篇&#xff1a;讲的都是干货基础&#xff0c;有些是书本上没有的&#xff0c;通过对基础知识的掌握&#xff0c;对技术形态会有更深的理解&#xff0c;比如集合竞价、K线指标、盘中看盘技巧等等。2、交易篇&#xff…

boolean在Java中占几个字节?(企业真题)

boolean 占几个字节 编译时不谈占几个字节。 但是JVM在给boolean类型分配内存空间时&#xff0c;boolean类型的变量占据一个槽位(slot(狭槽、窄口、扁口)&#xff0c;等于4个字节)。 细节&#xff1a;true:1 false:0 拓展&#xff1a;在内存中&#xff0c;byte\short\char\boo…

express静态资源访问错误 xxx.js was blocked due to MIME type (“text/html“)

归根结底原因是没有静态资源xxx.js的访问权限 如何在express中给静态资源添加访问权限&#xff0c;我在express js中添加以下语句解决了该问题&#xff1a; app.use(express.static(public)); 此时访问public文件夹中的xxx.js文件时&#xff0c;只需要使用路径 http://127.0…

备战蓝桥杯 Day9(背包dp)

01背包问题 1267&#xff1a;【例9.11】01背包问题 【题目描述】 一个旅行者有一个最多能装 M&#xfffd; 公斤的背包&#xff0c;现在有 n&#xfffd; 件物品&#xff0c;它们的重量分别是W1&#xff0c;W2&#xff0c;...,Wn&#xfffd;1&#xff0c;&#xfffd;2&#…

CentOS升级python

1、下载python39 https://mirrors.huaweicloud.com/python/3.9.0/Python-3.9.0.tgz2、拷贝到Linux环境&#xff08;当然也可以直接在Linux环境使用wget直接下载&#xff09; 先安装一下依赖&#xff0c;不然编译会有问题 sudo yum -y install zlib-devel bzip2-devel openssl…

【day02】每天三道 java后端面试题:Java、C++和Go的区别 | Redis的特点和应用场景 | 计算机网络七层模型

文章目录 1. Java、C和 Go 语言的区别&#xff0c;各自的优缺点&#xff1f;2. 什么是Redis&#xff1f;Redis 有哪些特点&#xff1f; Redis有哪些常见的应用场景&#xff1f;3. 简述计算机网络七层模型和各自的作用&#xff1f; 1. Java、C和 Go 语言的区别&#xff0c;各自的…

hsv Matlab

HSV 色彩空间 1.1 色调&#xff08;Hue&#xff09; 1.2 饱和度&#xff08;Saturation&#xff09; 1.3 明度&#xff08;Value&#xff09; 参考&#xff1a; HSV matlab

C#算法(12)—对图像像素做X/Y方向的偏移

我们在上位机开发领域有时候需要对获取的图像的像素做整体的偏移,比如所有像素在X方向上偏移几个像素,或者所有像素在Y方向上偏移几个像素,本文就是开发了像素整体偏移算法来解决这个问题。 比如有一个图像大小为3*3,像素值如下图1,如果我想实现将这个幅图像的像素整体往右…

Neon简介

欢迎关注“安全有理”微信公众号。 概述 本文介绍了 Arm Neon 技术&#xff0c;一种⾼级 SIMD&#xff08;Single Instruction Multiple Data&#xff0c;一条指令操作多个数据&#xff09;架构扩展&#xff0c;Armv8‑A 和 Armv8-R 架构支持了 Neon 技术扩展。 Neon 技术是指…

探索海洋世界,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建海洋场景下海洋生物检测识别分析系统

前面的博文中&#xff0c;开发实践过海底相关生物检测识别的项目&#xff0c;对于海洋场景下的海洋生物检测则很少有所涉及&#xff0c;这里本文的主要目的就是想要开发构建基于YOLOv7不同系列参数模型的海洋场景下的海洋生物检测识别系统。 前文已有相关实践&#xff0c;感兴…

如何在debian上实现一键恢复操作系统?

在Debian或任何其他Linux发行版上实现一键恢复操作系统&#xff0c;需要创建一个系统镜像或快照&#xff0c;并设置一个简单的方法来从该镜像恢复。以下是创建和恢复系统的基本步骤&#xff1a; 1. 创建系统镜像&#xff1a; 使用像dd&#xff0c;rsync或专门的备份工具&#…

CDC 整合方案:MySQL > Flink CDC > Kafka > Hudi

继上一篇 《CDC 整合方案:MySQL > Kafka Connect + Schema Registry + Avro > Kafka > Hudi》 讨论了一种典型的 CDC 集成方案后,本文,我们改用 Flink CDC 完成同样的 CDC 数据入湖任务。与上一个方案有所不同的是:借助现有的 Flink 环境,我们可以直接使用 Flink CDC 从…

STM32—触摸键

目录 1 、 电路构成及原理图 2 、编写实现代码 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 触摸键简单的了解就是一次电容的充放电过程。从原理图可以看出&#xff0c;触摸键 …

4.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-模拟游戏登陆器启动游戏并且完成注入

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;游戏启动流程的分析 码云地址&#xff08;master 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/titan 码云版本号&#xff1a;bcf7559184863febdcad819e48aaacad9f25d633 代码下…

Docker介绍与使用

Docker介绍与使用 目录&#xff1a; 一、Docker介绍 1、Docker概述与安装 2、Docker三要素 二、Docker常用命令的使用 1、镜像相关命令 2、容器相关命令 三、Docker实战之下载mysql、redis、zimg 一、Docker介绍 Docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包…

C#上位机与三菱PLC的通信09---开发自己的通讯库(A-3E版)

1、A-3E报文回顾 具体细节请看&#xff1a; C#上位机与三菱PLC的通信05--MC协议之QnA-3E报文解析 C#上位机与三菱PLC的通信06--MC协议之QnA-3E报文测试 2、为何要开发自己的通讯库 前面开发了自己的A-1E协议的通讯库&#xff0c;实现了数据的读写&#xff0c;对于封装的通…

Kubernetes二进制搭建

目录 1.操作系统初始化配置&#xff08;所有节点同此操作&#xff09; 2.部署etcd集群 etcd概述 准备签发证书环境 在master01节点上操作&#xff08;192.168.88.22&#xff09; 在两个node节点上操作 总结&#xff1a; 3.部署docker引擎 4.部署Master组件 总结&…

SQL语法-DQL-测试练习

因篇幅原因&#xff0c;本篇承接此篇->第八篇&#xff1a;SQL语法-DQL-数据查询语言-CSDN博客 本篇是对于SQL语法DQL语句的练习&#xff0c;因水平和精力有限&#xff08;就不像前两篇的DDL&#xff0c;DML那样自出练习了&#xff09;直接照搬了【黑马程序员】在哔哩哔哩的…

有影响因子的《科教文汇》2024投稿攻略

《科教文汇》主要设有八面来风、教育观察、卷首语、教育管理、思政教育、教改教法、课程思政、基础教育、职业教育等栏目。 主管单位 安徽省科学技术协会 主办单位 安徽省老科技工作者协会、安徽省科学教育研究会 国内统一刊号CN34-1274/G&#xff0c; 国际标准刊号ISSN 16…

基于 Fluid+JindoCache 加速大模型训练的实践

作者&#xff1a;王涛(扬礼)、陈裘凯(求索)、徐之浩(东伝) 背景 时间步入了 2024 年&#xff0c;新的技术趋势&#xff0c;如大模型/AIGC/多模态等技术&#xff0c;已经开始与实际业务相结合&#xff0c;并开始生产落地。这些新的技术趋势不仅提高了算力的需求&#xff0c;也…