当前位置: 首页 > news >正文

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层两个部分&#xff0c;其启动过程是从Java部分的初始化开始&#xff0c;进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start&#xff08;&#xff09;函数完成启动 同其他系统服务一样&#xff0c;IMS在SystemServer中的ServerT…...

搜维尔科技:【周刊】适用于虚拟现实VR中的OptiTrack

适用于 VR 的 OptiTrack 我们通过优化对虚拟现实跟踪最重要的性能指标&#xff0c;打造世界上最准确、最易于使用的广域 VR 跟踪器。其结果是为任何头戴式显示器 (HMD) 或洞穴自动沉浸式环境提供超低延迟、极其流畅的跟踪。 OptiTrack 主动式 OptiTrack 世界领先的跟踪精度和…...

matlab倒立摆小车LQR控制动画

1、内容简介 略 54-可以交流、咨询、答疑 2、内容说明 略 摆杆长度为 L&#xff0c;质量为 m 的单级倒立摆(摆杆的质心在杆的中心处)&#xff0c;小车的质量为 M。在水平方向施加控制力 u&#xff0c;相对参考系产生位移为 y。为了简化问题并且保其实质不变&#xff0c;忽…...

【C++】类和对象(2)

目录 1. 初始化列表 2.explicit关键字 3. Static成员 3. 友元 3.1友元函数 3.2友元类 4. 内部类 5.匿名对象 1. 初始化列表 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值&#xff0c;但是这个过程并不能称为对对…...

用Python实现创建十二星座数据分析图表

下面小编提供的代码中&#xff0c;您已经将pie.render()注释掉&#xff0c;并使用了pie.render_to_file(十二星座.svg)来将饼状图渲染到一个名为十二星座.svg的文件中。这是一个正确的做法&#xff0c;如果您想在文件中保存图表而不是在浏览器中显示它。 成功创建图表&#xf…...

备战蓝桥杯————递归反转单链表的一部分

递归反转单链表已经明白了&#xff0c;递归反转单链表的一部分你知道怎么做吗&#xff1f; 一、反转链表Ⅱ 题目描述 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反…...

rabbitmq知识梳理

一.WorkQueues模型 Work queues&#xff0c;任务模型。简单来说就是让多个消费者绑定到一个队列&#xff0c;共同消费队列中的消息。 当消息处理比较耗时的时候&#xff0c;可能生产消息的速度会远远大于消息的消费速度。长此以往&#xff0c;消息就会堆积越来越多&#xff0c…...

【数据结构与算法】动态规划法解题20240227

动态规划法 一、什么是动态规划二、动态规划的解题步骤三、509. 斐波那契数1、动规五部曲&#xff1a; 四、70. 爬楼梯1、动规五部曲&#xff1a; 五、746. 使用最小花费爬楼梯1、动规五部曲&#xff1a; 一、什么是动态规划 动态规划&#xff0c;英文&#xff1a;Dynamic Pro…...

备战蓝桥杯—— 双指针技巧巧答链表2

对于单链表相关的问题&#xff0c;双指针技巧是一种非常广泛且有效的解决方法。以下是一些常见问题以及使用双指针技巧解决&#xff1a; 合并两个有序链表&#xff1a; 使用两个指针分别指向两个链表的头部&#xff0c;逐一比较节点的值&#xff0c;将较小的节点链接到结果链表…...

半监督节点分类-graph learning

半监督节点分类相当于在一个图当中&#xff0c;用一部分节点的类别上已知的&#xff0c;有另外一部分节点的类别是未知的&#xff0c;目标是使用有标签的节点来推断没有标签的节点 注意 半监督节点分类属于直推式学习&#xff0c;直推式学习相当于出现新节点后&#xff0c;需要…...

软件文档-运维-开发-管理-资质-评审-招投标-验收

开发文档&#xff1a;这类文档主要用于记录软件的开发过程和细节&#xff0c;包括&#xff1a; 《功能要求》&#xff1a;描述了软件应具备的功能&#xff0c;是软件开发的基础。《投标方案》&#xff1a;向潜在的客户或招标方展示公司的技术和项目实施能力。《需求分析》&…...

猫头虎分享已解决Bug || Vue中的TypeError: Cannot read property ‘name‘ of undefined 错误

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …...

技术应用:使用Spring Boot、MyBatis Plus和Dynamic DataSource实现多数据源

引言 在现代的软件开发中&#xff0c;许多应用程序需要同时访问多个数据库。例如&#xff0c;一个电子商务平台可能需要访问多个数据库来存储用户信息、产品信息和订单信息等。在这种情况下&#xff0c;使用多数据源是一种常见的解决方案&#xff0c;它允许我们在一个应用程序…...

C# Onnx 使用onnxruntime部署实时视频帧插值

目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx 使用onnxruntime部署实时视频帧插值 介绍 github地址&#xff1a;https://github.com/google-research/frame-interpolation FILM: Frame Interpolation for Large Motion, In ECCV 2022. The official Tensorflow 2…...

编程笔记 Golang基础 016 数据类型:数字类型

编程笔记 Golang基础 016 数据类型&#xff1a;数字类型 1. 整数类型&#xff08;Integer Types&#xff09;a) 固定长度整数&#xff1a;b) 变长整数&#xff1a; 2. 浮点数类型&#xff08;Floating-Point Types&#xff09;3. 复数类型&#xff08;Complex Number Types&…...

一周学会Django5 Python Web开发-会话管理(CookiesSession)

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计26条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…...

QT之QString.arg输出固定位数

问题描述 我需要用QString输出一个固定位数的数字字符串。起初我的代码是这样&#xff1a; int img_num 1 auto new_name QString("%1.png").arg((int)img_num, 3, 10, 0); //最后一个参数用u0也是一样的 qDebug() << "new_name:" << new…...

Linux下各种压缩包的压缩与解压

tar 归档&#xff0c;不压缩&#xff0c;常见后缀 .tar # 将文件夹归档成为一个包 tar cf rootfs.tar rootfs # 将归档包还原为文件夹 tar xf rootfs.tar # 将归档包还原到路径 a/b/c tar xf rootfs.tar -C a/b/cgzip压缩&#xff0c; 常见后缀 .tar.gz .tgz # 压缩 tar czf …...

【ctfshow—web】——信息搜集篇1(web1~20详解)

ctfshow—web题解 web1web2web3web4web5web6web7web8web9web10web11web12web13web14web15web16web17web18web19web20 web1 题目提示 开发注释未及时删除 那就找开发注释咯&#xff0c;可以用F12来查看&#xff0c;也可以CtrlU直接查看源代码呢 就拿到flag了 web2 题目提示 j…...

GEE入门篇|遥感专业术语(实践操作4):光谱分辨率(Spectral Resolution)

目录 光谱分辨率&#xff08;Spectral Resolution&#xff09; 1.MODIS 2.EO-1 光谱分辨率&#xff08;Spectral Resolution&#xff09; 光谱分辨率是指传感器进行测量的光谱带的数量和宽度。 您可以将光谱带的宽度视为每个波段的波长间隔&#xff0c;在多个波段测量辐射亮…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...