input子系统三 input系统启动和EventHub数据读取

本文分析了Android输入系统启动的过程,从systemServer启动InputManagerService,到InputReader和InputDispatcher的创建,以及EventHub如何读取kernel层的数据。Input系统启动涉及InputManagerService的回调设置和start函数调用。EventHub利用epoll机制监测Input驱动变化,进行设备打开、事件读取和等待操作。首次调用getEvents函数时,会扫描并打开/dev/input下的设备文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、框架介绍

由下图可以看出,在系统服务启动时会通过InputManager启动InputReader和InputDispatcher,创建EventHub对象,当kernel层向dev节点中写入数据时,EventHub会读出数据,经过InputReader处理后,通过InputDispatcher发送给系统服务,或者其他需要使用的应用程序,后面将分为三部分分析,一为input子系统的启动;二为input子系统的在framework中的数据获取;三为数据的处理和传输。


二、input系统启动分析

1、Android系统的服务基本都是从systemServer启动的,同样Input系统也是从systemserver启动的,首先创建InputManagerService对象,为这个对象设置与WindowManagerService相关的回调函数,然后调用InputManagerService的start函数。

./frameworks/base/services/java/com/android/server/SystemServer.java
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
2、在InputManagerService中的start方法会通过JNI调用,启动Native层的InputReadThread、InputDispatcherThread线程,先看InputManagerService的构造函数,代码如下:
./frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public InputManagerService(Context context) {
    this.mContext = context;
    this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
    mUseDevInputEventForAudioJack =
            context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
    Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
            + mUseDevInputEventForAudioJack);
    mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());//通过JNI调用nativeInit来启动native层的input系统

    LocalServices.addService(InputManagerInternal.class, new LocalService());
}
这里首先构造InputManagerHandler用于处理消息,当然这个handle是绑定在"WindowManager"这个looper上的。然后JNI调用nativeInit去完成natvie层的初始化,接下来查看native层所做的工作:
./frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }
	//NativeInputManager,使用messageQueue意味着java和native层的消息传输使用同一个messageQueue
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);//将新建的NativeInputManager强制转换返回给应用层的mPtr
}
<think>好的,用户想了解安卓的input子系统的架构实现细节。首先,我需要回忆一下Android系统的整体架构,确定input子系统属于哪一层。Android大致分为应用层、应用框架层、系统服务层、硬件抽象层(HAL)Linux内核层。Input子系统应该属于系统服务层内核层的部分。 接下来,要分解input子系统的各个组件。通常,Android的输入处理涉及设备驱动、内核输入子系统、HAL层、系统服务(如InputManagerService)、窗口管理服务(WindowManagerService)以及应用层的处理流程。需要详细说明每个部分的作用交互方式。 然后,考虑用户可能的实际需求。他们可能是开发者,需要了解输入事件的处理流程来进行应用开发或调试;也可能是系统工程师,想深入底层优化输入响应或处理特定硬件问题。因此,回答需要兼顾架构概述关键实现细节,比如事件传递路径、关键数据结构(如InputEvent)、线程模型等。 还需要检查是否有相关的引用内容可以支持回答。用户提供的引用中有提到Linux内核系统构建相关内容,比如引用[1]提到Buildroot用于嵌入式Linux环境搭建,可能与驱动开发相关。引用[3]涉及内核函数,可能与输入设备驱动有关联。需要合理引用这些内容,但注意相关性可能有限,需谨慎使用。 另外,注意用户要求的中文回答,以及格式要求中的数学表达式使用正确LaTeX格式。虽然input子系统内容可能较少涉及数学公式,但如果有涉及性能分析的部分,可能需要使用LaTeX表达,比如时间复杂度的计算。 最后,生成相关问题时要围绕input子系统展开,考虑其架构、实现、优化、调试工具、与其他子系统的关系等。确保问题具有针对性延伸性,帮助用户深入理解。 总结回答结构:先概述架构层次,再分层详细说明各组件,包括驱动、HAL、系统服务、应用处理流程,然后讨论关键实现细节如事件传递机制、线程模型,最后补充调试工具可能的优化点。确保引用相关参考资料,如内核模块部分引用[3]提到的函数,或构建环境引用[1]。</think>### Android Input子系统架构与实现细节 Android Input子系统是处理触摸屏、物理按键、鼠标等输入设备的核心模块,其架构分为五个层次(如下图),采用典型的分层设计模式: $$系统架构图$$ $$应用层 \rightarrow 框架层 \rightarrow JNI \rightarrow 系统服务层 \rightarrow HAL \rightarrow 内核驱动层$$ #### 一、核心组件解析 1. **Linux内核驱动层** - 设备驱动通过`evdev`接口向用户空间上报事件[^3] - 输入设备注册示例: ```c input_register_device(struct input_dev *dev); ``` - 关键数据结构`input_event`包含事件类型(如`EV_KEY`)、编码(如`KEY_POWER`)值 2. **硬件抽象层(HAL)** - `InputReader`通过`EventHub`监听`/dev/input`节点 - 事件解析流程: ``` 原始数据 → 坐标校准 → 手势识别 → 事件分类 ``` 3. **系统服务层** - `InputManagerService`包含两个核心线程: - `InputReaderThread`(优先级=32):负责原始事件读取 - `InputDispatcherThread`(优先级=31):事件分发 - 窗口焦点管理通过`WindowManagerService`实现 #### 二、事件传递路径 ``` 驱动层 → EventHubInputReader → InputDispatcher → WindowManager → 目标应用 ``` - 跨进程通信采用`SocketPair`机制,时延要求<100ms - 使用`InputChannel`实现应用级事件分发 #### 、关键实现细节 1. **多指触控处理** - 通过`ABS_MT_SLOT`区分触点ID - 支持协议:Type A(同步帧)/Type B(独立跟踪) 2. **输入过滤机制** - 防手掌误触算法:$P = \sum_{i=1}^n w_i \cdot x_i > \theta$ - 手势识别状态机包含5种状态迁移 3. **性能优化** - 使用`epoll`实现事件多路复用 - 事件批处理机制减少IPC次数 #### 四、调试工具 ```bash adb shell getevent -l # 查看原始输入事件 dumpsys input # 显示输入子系统状态 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值