Android InputMonitor

InputMonitor是InputManagerService和WMS之间的纽带,SystemServer.java中 startOtherServices()方法下进行初始化:

            inputManager = new InputManagerService(context);
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

            traceBeginAndSlog("StartWindowManagerService");
            wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

            traceBeginAndSlog("StartVrManagerService");
            mSystemServiceManager.startService(VrManagerService.class);
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

            mActivityManagerService.setWindowManager(wm);

            inputManager.setWindowManagerCallbacks(wm.getInputMonitor());//互相关联
            inputManager.start();

其中 wm.getInputMonitor()方法在WindowManagerService.java中如下:

 public InputMonitor getInputMonitor() {
        return mInputMonitor;
    }

    final InputMonitor mInputMonitor = new InputMonitor(this);


当IMS接收到相应输入事件后,会通过mWindowManagerCallbacks 来调用mInputMonitor对象方法:

return  mWindowManagerCallbacks.notifyConfigurationChanged();
return  mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);       

return  mWindowManagerCallbacks.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered);

return mWindowManagerCallbacks.notifyInputChannelBroken(inputWindowHandle);
return mWindowManagerCallbacks.notifyANR(
return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags);
 return mWindowManagerCallbacks.interceptMotionBeforeQueueingNonInteractive(
 return mWindowManagerCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags);
 return mWindowManagerCallbacks.dispatchUnhandledKey(focus, event, policyFlags);
 return mWindowManagerCallbacks.getPointerLayer();


<think> 我们之前讨论的是Android系统服务相关的内容,特别是关于InputMonitor的调用机制。根据用户当前的需求,用户希望了解com.android.server.wm.InputMonitor的相关信息,包括调用机制。因此,我们需要围绕这个类在Android窗口管理中的作用、它的主要方法以及调用流程进行解释。 首先,com.android.server.wm.InputMonitorAndroid窗口管理系统中的一个重要类,它属于WindowManagerService(WMS)模块。它的主要职责是监控输入事件(如触摸、按键等)的分发过程,并协调窗口之间的输入事件传递。 接下来,我们将详细说明InputMonitor的调用机制: 1. **InputMonitor的创建**:InputMonitor实例通常在WindowManagerService的初始化过程中创建。WindowManagerService会为每个显示(Display)创建一个InputMonitor对象。这是因为不同的显示设备可能有不同的输入配置。 2. **与InputManagerService的关联**:InputMonitor通过InputManagerService(IMS)来接收输入事件。IMS是Android输入系统的核心服务,它负责从设备驱动读取输入事件,并将事件分发给相应的窗口。 3. **事件分发过程**: - 当IMS有输入事件时,它会调用InputMonitor的方法(如`dispatchInputEvent`)来通知窗口管理系统。 - InputMonitor会根据当前窗口的布局和状态(如焦点窗口、触摸窗口等)决定将事件分发给哪个窗口。 - 在分发之前,InputMonitor可能会进行一些处理,例如检查是否存在系统覆盖层(如状态栏)需要优先处理事件,或者根据窗口的触摸区域(TouchRegion)过滤事件。 4. **与InputChannel的关联**:每个窗口在添加到WMS时,都会创建一个InputChannel,用于接收输入事件。InputMonitor负责管理这些InputChannel,并将事件发送到正确的InputChannel。 5. **输入事件的处理流程**: - InputMonitor将事件传递给目标窗口的InputChannel。 - 目标窗口的ViewRootImpl会通过其InputEventReceiver(通常是WindowInputEventReceiver)接收事件,然后交给DecorView进行事件分发,最终传递给具体的View。 6. **输入事件拦截**:InputMonitor还负责处理一些系统级的输入事件拦截。例如,当系统处于某些状态(如屏幕关闭、键盘弹出)时,InputMonitor可能会拦截事件,不将其分发给应用窗口。 7. **同步屏障(Synchronization Barrier)**:在Android系统中,输入事件的分发需要与UI线程同步。InputMonitor会确保在正确的时机将事件插入到目标窗口的消息队列中,避免在窗口正在处理其他消息(如布局、绘制)时插入事件。 8. **ANR(Application Not Responding)监控**:InputMonitor还参与ANR的检测。如果某个窗口在一定时间内没有处理完输入事件,InputMonitor会触发ANR报告流程。 下面我们用一个简化的序列图来描述输入事件的分发流程: ```mermaid sequenceDiagram participant IMS as InputManagerService participant IM as InputMonitor participant WMS as WindowManagerService participant InputChannel as 目标窗口的InputChannel participant ViewRootImpl IMS->>IM: dispatchInputEvent(event) IM->>WMS: 查询当前焦点窗口和触摸区域 WMS-->>IM: 返回目标窗口信息 IM->>InputChannel: 发送事件 InputChannel->>ViewRootImpl: 通过InputEventReceiver接收事件 ViewRootImpl->>DecorView: 分发事件 DecorView->>View: 事件传递 ``` 注意:上述序列图是一个简化的流程,实际过程更为复杂,涉及多个模块和状态判断。 最后,我们生成几个相关问题: §§相关问题§§ 1. InputMonitorAndroid输入系统中如何与InputManagerService交互? 2. InputMonitor如何处理多个触摸事件的分发? 3. 在Android系统中,InputMonitor在ANR检测中扮演什么角色? </think> ### com.android.server.wm.InputMonitor 解析 `com.android.server.wm.InputMonitor` 是 Android 窗口管理系统(WindowManagerService)的核心组件之一,主要负责协调输入事件(触摸、按键等)与窗口显示的关系。其核心功能包括: #### 1. **核心职责** - **输入事件分发**:监控并转发输入事件到正确的窗口 - **焦点管理**:跟踪当前获得焦点的窗口(如`mFocusedWindow`) - **输入通道管理**:维护窗口的`InputChannel`(与`InputDispatcher`通信的管道) - **同步屏障**:确保输入事件与VSync信号同步,避免画面撕裂 #### 2. **关键调用机制** ```mermaid graph LR A[InputDispatcher] --> B(InputMonitor.updateInputWindows) B --> C{遍历WindowState列表} C --> D[计算输入区域] D --> E[更新InputChannel] E --> F[通过Socket发送事件] F --> G[App进程处理事件] ``` 1. **输入事件入口**: - `InputDispatcher` 通过 `InputMonitor.updateInputWindows()` 触发事件分发流程 - 示例代码段: ```java // WindowManagerService.java void updateInputWindows() { mInputMonitor.updateInputWindows(true /*force*/); } ``` 2. **窗口状态同步**: - 遍历所有`WindowState`对象,调用`populateInputWindowHandle()`更新: - 窗口层级(`mInputWindowHandle.layer`) - 触摸区域(`touchableRegion`) - 焦点状态(`focusable`标志) - 关键判断逻辑: ```java if (win.canReceiveKeys()) { mInputWindowHandle.focusable = true; mInputWindowHandle.hasFocus = (win == mFocusedWindow); } ``` 3. **输入通道操作**: - 通过`InputChannel`与客户端进程通信: ```java InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); win.setInputChannel(inputChannels[0]); // 服务端保留 clientChannel = inputChannels[1]; // 发送到应用进程 ``` 4. **异常处理机制**: - ANR检测:5秒内未处理事件触发`notifyWindowUnresponsive()` - 输入丢失保护:通过`batchTimeout`机制合并连续事件 #### 3. **与其他模块交互** | 模块 | 交互方式 | 关键接口 | |------|----------|----------| | `InputManagerService` | Binder调用 | `IInputManager` | | `SurfaceFlinger` | 同步屏障 | `setInputWindows()` | | `ViewRootImpl` | Socket通信 | `InputEventReceiver` | | `ActivityManager` | ANR上报 | `appNotResponding()` | #### 4. **典型工作流** 1. 用户触摸屏幕 2. `InputReader` 读取事件 → `InputDispatcher` 分发 3. `InputMonitor` 确定目标窗口(基于`Z-order`和`touchableRegion`) 4. 通过`InputChannel`将事件传递到`ViewRootImpl` 5. 应用消费事件后返回`FINISHED`信号 > 注:输入事件延迟需控制在 **16ms** 内(60Hz刷新率要求)[^1] #### 5. **调试技巧** - 查看当前输入状态: ```shell adb shell dumpsys input ``` - 监控事件分发: ```shell adb shell getevent -lt ``` - 强制刷新输入窗口: ```java mInputMonitor.updateInputWindowsImmediately(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值