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. */
    @VisibleForTesting
    static 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对象,使用InputReaderPolicyInterface
    mProcessor = 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.cpp
 
std::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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不要抱怨,不如抱 Java 运算符吧 (1)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

mplfinance 使用make_addplot做复杂股票走势图

mplfinance 使用make_addplot做复杂股票走势图 1.代码 import talib as tb import pandas as pd import mplfinance as mpfimport matplotlib.pyplot as pltplt.rcParams[font.sans-serif][simHei] # 以黑体显示中文 plt.rcParams[axes.unicode_minus]False # 解决保存图像符…

Meta 发布 MMCSG (多模态智能眼镜对话数据集)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

LeetCode 热题 100 Day01

哈希模块 哈希结构&#xff1a; 哈希结构&#xff0c;即hash table&#xff0c;哈希表|散列表结构。 图摘自《代码随想录》 哈希表本质上表示的元素和索引的一种映射关系。 若查找某个数组中第n个元素&#xff0c;有两种方法&#xff1a; 1.从头遍历&#xff0c;复杂度&#xf…

Java 学习和实践笔记(15):面向过程和面象对象其实很简单!

学完这一节&#xff0c;才真正明白了什么叫面向对象和面向过程&#xff0c;其实很简单~ 第一个例子&#xff1a;怎样把大象装进冰箱 这个很清楚很容易地可以列出第一步。 第二个例子&#xff1a;怎样制造一台汽车 这个就很难确定哪一步做第一步。 面向过程和面向对象的区别 …

【二十六】【C++】Map和Set

K模型与KV模型 在数据结构中&#xff0c;二叉搜索树&#xff08;BST&#xff09;的应用通常围绕着两种基本模型&#xff1a;键模型&#xff08;K模型&#xff09;和键值对模型&#xff08;KV模型&#xff09;。这两种模型定义了树中节点存储数据的方式&#xff0c;以及如何通过…

区块链游戏解说:什么是 Planet IX

作者&#xff1a;lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a;Planet IX Dashboard 什么是 Planet IX Planet IX&#xff0c;一个由原生 IX TOKEN 推动的 Web3 玩赚平台。作为一款 GameFi 策略游戏&#xff0c; Planet IX 上的每项资…

如何修改docker容器的端口映射

要修改 Docker 容器的端口映射&#xff0c;你需要停止并删除现有的容器&#xff0c;然后使用新的端口映射重新运行容器。以下是详细步骤&#xff1a; 停止容器&#xff1a; 使用 docker stop 命令停止正在运行的容器。替换 <container_id> 为你要停止的容器的 ID 或者容器…

浅谈消防设备电源监控系统在高层建筑中的应用

摘要&#xff1a;火灾发生后&#xff0c;非消防电源被切断&#xff0c;火灾报警系统应立即接通消防电源&#xff0c;满足消防设施 处于良好运行状态&#xff0c;对消防设备电源状态的监控是十分必要的。介绍消防设备电源的重要性 和三种类型&#xff0c;分析消防设备电源监控系…

Python中HTTP重定向和重定向链的处理:网络迷宫的导航专家

在网络世界里&#xff0c;有时候&#xff0c;我们访问的URL并不是直接指向我们想要的内容&#xff0c;而是像是一个神秘的迷宫&#xff0c;指引我们绕来绕去。这时候&#xff0c;HTTP重定向就像是迷宫里的路标&#xff0c;告诉我们“嘿&#xff0c;你要找的东西不在这里&#x…

这才是No.1的门禁管理技巧!赶紧抄作业

随着社会的不断发展和科技的飞速进步&#xff0c;安全管理成为各个领域不可或缺的重要环节。在这个背景下&#xff0c;门禁监控系统作为一种先进而高效的安全管理工具逐渐受到了广泛关注和应用。 客户案例 企业大厦管理 在江苏某繁忙的商业大厦中&#xff0c;管理人员常常面临…

【咕咕送书 | 第七期】世界顶级名校计算机专业,都在用哪些书当教材?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 写在前面参与规则 ✅参与方式&#xff1a;关注博主、点赞、收藏、评论&#xff0c;任意评论&#xff08;每人最多评论…

七、计算机视觉-图像的ROI区域

文章目录 1、什么是ROI2、ROI如何实现的3、一个案例总结 1、什么是ROI 在计算机视觉中&#xff0c;ROI代表感兴趣区域&#xff08;Region of Interest&#xff09;&#xff0c;它是指图像或视频中被指定为需要特别关注或处理的区域。ROI可以帮助减少计算量&#xff0c;并且在处…

基于JAVA springboot+mybatis 电商书城平台系统设计和实现

基于JAVA springbootmybatis 电商书城平台系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获…

初识VUE3

1.VUE3官网 https://cn.vuejs.org/ 2.通过Vite创建项目 全局安装vite npm config set registryhttps://registry.npmmirror.com 使用国内源npm install -g vitelatest 安装vite前要先查看镜像源地址并使用国内镜像源地址 //查看镜像源地址 npm config get registry //更…

Debug|百度OCR识别错误error_code: 216205

1. 什么错误 在使用百度OCR识别时遇到了错误error_code: 216205。 参照文档【百度OCR文字识别 - API文档 - 错误码】中的描述&#xff0c;是我的图片转base64后大于10M 测试两张图片&#xff1a;923k图片的Base64 大于 10M&#xff1b;2M图片的Base64 小于 10M。 # 电脑上看…

Maven的下载安装配置教程

一、简单了解一下什么是Maven Maven就是一款帮助程序员构建项目的工具&#xff0c;我们只需要告诉Maven需要哪些Jar 包&#xff0c;它会帮助我们下载所有的Jar&#xff0c;极大提升开发效率。 1.Maven翻译为“专家“&#xff0c; ”内行”的意思&#xff0c;是著名Apache公司下…

Day16_集合与泛型(泛型类与泛型接口,泛型方法,类型变量的上限与泛型的擦除,类型通配符)

文章目录 Day16 泛型学习目标1 泛型的概念1.1 没有泛型的问题1.2 泛型的引入1.2 泛型的好处1.3 泛型的定义 2 泛型类与泛型接口2.1 使用核心类库中的泛型类/接口案例一&#xff1a;Collection集合相关类型案例二&#xff1a;Comparable接口 2.2 自定义泛型类与泛型接口语法格式…

【成都游戏业:千游研发之都的发展与机遇】

成都游戏业&#xff1a; 千游研发之都的发展与机遇 作为我国西部游戏产业的龙头&#xff0c;成都这座城市正在高速发展&#xff0c;目标是崛起成为千亿级游戏研发之都。多年来&#xff0c;在政策扶持、人才汇聚以及文化底蕴等助力下&#xff0c;成都游戏业已经形成完整的产业链…

matlab代码--基于stbc编码的MIMO-OFDM系统的误码率分析

1 前言 空时分组编码STBC&#xff08;Space Time Block Coding&#xff09;用在无线通信中传输一个数据流的多个拷贝。通过许多天线来产生数据的多种接收版本&#xff0c;提高数据传输的可靠性。接收机接收到的数据拷贝中&#xff0c;存在一些比其它拷贝“更好”的拷贝。而这种…