android12 InputManagerService分析之输入事件如何回到应用层

InputDispatcher:事件的"派发员"

InputDispatcherInputReader 接收事件后,并不会立即盲目发送。它内部维护了一个由 WMS(WindowManagerService) 实时更新的窗口状态表,记录了所有窗口的焦点、层级、可见性等信息。InputDispatcher 会查阅这张表,找到事件的正确目标窗口,然后通过与该窗口建立的 InputChannel(基于Socket)将事件发送过去。整个派发过程是异步和非阻塞的,保证了系统对用户操作的快速响应。

rust 复制代码
//frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
                                           DropReason* dropReason, nsecs_t* nextWakeupTime) {
    ATRACE_CALL();
    // Preprocessing.
    if (!entry->dispatchInProgress) {
       //标记事件正在分发,防止重复处理
        entry->dispatchInProgress = true;

    }

    // Clean up if dropping the event.
    //这是一个关键检查。如果 `dropReason` 不是 `NOT_DROPPED`,
    意味着事件应该被丢弃(例如被策略决策拦截)。代码会直接根据丢弃原因(
    是策略丢弃还是其他)设置注入结果,并返回 `true` 结束处理
    if (*dropReason != DropReason::NOT_DROPPED) {
        setInjectionResult(*entry,
                           *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
                                                             : InputEventInjectionResult::FAILED);
        return true;
    }

    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;

    // Identify targets.
    std::vector<InputTarget> inputTargets;

    bool conflictingPointerActions = false;
    InputEventInjectionResult injectionResult;
    //指针事件 
    if (isPointerEvent) {
        // Pointer event.  (eg. touchscreen)
        //它通过触摸点坐标,在窗口层级的"命中测试"中寻找最顶层的、可接收触摸的窗口
        injectionResult =
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                                               &conflictingPointerActions);
    } else {
        //非指针事件
        injectionResult =
                findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
    }
    //返回的 `injectionResult` 决定了后续流程:
   //`PENDING`: 事件需要等待(例如等待某个窗口就绪),函数直接返回 `false`。
   //`PERMISSION_DENIED` 或其他错误: 事件会被丢弃,并可能生成取消事件。
   //`SUCCEEDED`: 成功找到目标窗口,继续下一步。
    if (injectionResult == InputEventInjectionResult::PENDING) {
        return false;
    }

    setInjectionResult(*entry, injectionResult);
    if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
        ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
        return true;
    }
    if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
        CancelationOptions::Mode mode(isPointerEvent
                                              ? CancelationOptions::CANCEL_POINTER_EVENTS
                                              : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
        CancelationOptions options(mode, "input event injection failed");
        synthesizeCancelationEventsForMonitorsLocked(options);
        return true;
    }

    // Add monitor channels from event's or focused display.
    //添加全局监控
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));

    if (isPointerEvent) {
        std::unordered_map<int32_t, TouchState>::iterator it =
                mTouchStatesByDisplay.find(entry->displayId);
        if (it != mTouchStatesByDisplay.end()) {
            const TouchState& state = it->second;
            //**处理 Portal 窗口**: 这是一个较新的机制,用于处理跨显示器的触摸事件。
            如果事件穿过了一个 `Portal` 窗口,代码需要为这个 `Portal` 窗口所对应
            的显示器也添加全局监控目标
            if (!state.portalWindows.empty()) {
                // The event has gone through these portal windows, so we add monitoring targets of
                // the corresponding displays as well.
                for (size_t i = 0; i < state.portalWindows.size(); i++) {
                    const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
                    addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
                                                     -windowInfo->frameLeft, -windowInfo->frameTop);
                }
            }
        }
    }

    // Dispatch the motion.
    //冲突处理: 如果在处理多点触摸时检测到有冲突的动作(如两根手指同时按下),
    会调用 `synthesizeCancelationEventsForAllConnectionsLocked` 生成取消
    事件,确保所有相关窗口的状态一致**
    if (conflictingPointerActions) {
        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                                   "conflicting pointer actions");
        synthesizeCancelationEventsForAllConnectionsLocked(options);
    }
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}


void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
                                          std::shared_ptr<EventEntry> eventEntry,
                                          const std::vector<InputTarget>& inputTargets) {
    ATRACE_CALL();
    ...
    for (const InputTarget& inputTarget : inputTargets) {
        sp<Connection> connection =
                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
        if (connection != nullptr) {
            //遍历目标列表,为每个有效的 `Connection` 启动一个异步的分发周期
            prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
        } else {
            
            }
        }
    }
}


void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
                                                   const sp<Connection>& connection,
                                                   std::shared_ptr<EventEntry> eventEntry,
                                                   const InputTarget& inputTarget) {
    ...
    if (wasEmpty && !connection->outboundQueue.empty()) {
        startDispatchCycleLocked(currentTime, connection);
    }
}


void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                               const sp<Connection>& connection) {
   
    ...
    //不断从发送队列中获取DispatchEntry并将事件发送到InputChannel
    while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
        //获取 `outboundQueue` 队首的 `DispatchEntry` 指针,不删除
        DispatchEntry* dispatchEntry = connection->outboundQueue.front();
        //设置事件的投递时间为当前时间,用于后续性能统计和 ANR 判断
        dispatchEntry->deliveryTime = currentTime;
        //根据连接令牌获取分发超时时长(通常来自 `WindowManager` 配置)。
        //计算事件的绝对超时时间点 = 当前时间 + 超时时长
        //超时后若应用未处理完成,会触发 ANR
        const std::chrono::nanoseconds timeout =
                getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
        dispatchEntry->timeoutTime = currentTime + timeout.count();

        // Publish the event.
        status_t status;
        const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
        //根据不同类型的事件选择不同的发送函数
        switch (eventEntry.type) {
            //按键事件
            case EventEntry::Type::KEY: {
                //将 `EventEntry` 向下转型为 `KeyEntry`
                const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
                //生成 HMAC 签名,用于安全验证,防止恶意应用伪造输入事件
                std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);

                // Publish the key event.
                //通过 `InputPublisher` 将按键事件发布到目标应用
                status = connection->inputPublisher
                                 .publishKeyEvent(dispatchEntry->seq,
                                                  dispatchEntry->resolvedEventId, keyEntry.deviceId,
                                                  keyEntry.source, keyEntry.displayId,
                                                  std::move(hmac), dispatchEntry->resolvedAction,
                                                  dispatchEntry->resolvedFlags, keyEntry.keyCode,
                                                  keyEntry.scanCode, keyEntry.metaState,
                                                  keyEntry.repeatCount, keyEntry.downTime,
                                                  keyEntry.eventTime);
                break;
            }
            //触摸事件
            case EventEntry::Type::MOTION: {
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
                //定义 `scaledCoords` 数组用于存储缩放后的坐标
                PointerCoords scaledCoords[MAX_POINTERS];
                //`usingCoords` 指针指向实际要使用的坐标数据,默认指向原始坐标
                const PointerCoords* usingCoords = motionEntry.pointerCoords;
                //事件源属于指针类(触摸/鼠标)**且**目标标志
                未设置 `FLAG_ZERO_COORDS`
                if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
                    !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
                    //全局缩放因子(例如在显示缩放设置中)
                    float globalScaleFactor = dispatchEntry->globalScaleFactor;
                    if (globalScaleFactor != 1.0f) {
                        for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
                            scaledCoords[i] = motionEntry.pointerCoords[i];
                            
                           //对每个指针坐标进行缩放。
                           //`windowXScale` 和 `windowYScale` 传入 1,
                           //表示不额外进行窗口缩放。
                           scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
                                                  1 /* windowYScale */);
                        }
                        //缩放完成后,将 `usingCoords` 指向缩放后的数组
                        usingCoords = scaledCoords;
                    }
                } else {
                    
                    //如果目标标志包含 `FLAG_ZERO_COORDS`(通常用于
                    系统级监听者,如手势导航),将所有坐标清零,防止敏感位置信息泄露。
                    if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
                        for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
                            scaledCoords[i].clear();
                        }
                        usingCoords = scaledCoords;
                    }
                }

                std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);

                //发布触摸事件
                status = connection->inputPublisher
                                 .publishMotionEvent(dispatchEntry->seq,
                                                     dispatchEntry->resolvedEventId,
                                                     motionEntry.deviceId, motionEntry.source,
                                                     motionEntry.displayId, std::move(hmac),
                                                     dispatchEntry->resolvedAction,
                                                     motionEntry.actionButton,
                                                     dispatchEntry->resolvedFlags,
                                                     motionEntry.edgeFlags, motionEntry.metaState,
                                                     motionEntry.buttonState,
                                                     motionEntry.classification,
                                                     dispatchEntry->transform,
                                                     motionEntry.xPrecision, motionEntry.yPrecision,
                                                     motionEntry.xCursorPosition,
                                                     motionEntry.yCursorPosition,
                                                     dispatchEntry->displaySize.x,
                                                     dispatchEntry->displaySize.y,
                                                     motionEntry.downTime, motionEntry.eventTime,
                                                     motionEntry.pointerCount,
                                                     motionEntry.pointerProperties, usingCoords);
                break;
            }

            ...
            
        }

        // Check the result.
        if (status) {
            //表示发送通道(Socket/管道)已满,目标应用处理速度跟不上
            if (status == WOULD_BLOCK) {
                 //意味着通道满但没有任何事件等待确认,这是不一致状态,
                 调用 `abortBrokenDispatchCycleLocked` 中断分发。
                if (connection->waitQueue.empty()) {
                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
                } else {
                    
                    //如果 `waitQueue` 非空,说明应用正在处理之前的事件,
                    只是暂时阻塞,等待应用消费后自然恢复

                }
            } else {
                //其他任何错误都被视为严重问题,记录错误日志后
                调用 `abortBrokenDispatchCycleLocked` 中断分发周期。
                abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
            }
            return;
        }

        // Re-enqueue the event on the wait queue.
        //使用erase-remove从 `outboundQueue` 中移除已发布的 `dispatchEntry`
        //`std::remove` 按值删除,但由于指针唯一,会准确移除
        connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
                                                    connection->outboundQueue.end(),
                                                    dispatchEntry));
        //追踪 `outboundQueue` 长度变化(用于 Systrace)
        traceOutboundQueueLength(*connection);
        //将 `dispatchEntry` 追加到 `waitQueue`(等待队列)尾部,
        表示该事件已发送但尚未收到完成确认
        connection->waitQueue.push_back(dispatchEntry);
        //连接是否响应式(通常为 true)
        if (connection->responsive) {
            //将事件的超时时间点注册到 ANR 监控器中。如果超时前未收到完成
            通知,`InputDispatcher` 会触发 ANR
            mAnrTracker.insert(dispatchEntry->timeoutTime,
                               connection->inputChannel->getConnectionToken());
        }
        //追踪 `waitQueue` 长度变化
        traceWaitQueueLength(*connection);
    }
}



status_t InputPublisher::publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId,
                                         int32_t source, int32_t displayId,
                                         std::array<uint8_t, 32> hmac, int32_t action,
                                         int32_t flags, int32_t keyCode, int32_t scanCode,
                                         int32_t metaState, int32_t repeatCount, nsecs_t downTime,
                                         nsecs_t eventTime) {
    ...
    //声明一个 `InputMessage` 结构体实例,用于承载所有事件数据
    InputMessage msg;
    msg.header.type = InputMessage::Type::KEY;
    msg.header.seq = seq;
    msg.body.key.eventId = eventId;
    msg.body.key.deviceId = deviceId;
    msg.body.key.source = source;
    msg.body.key.displayId = displayId;
    msg.body.key.hmac = std::move(hmac);
    msg.body.key.action = action;
    msg.body.key.flags = flags;
    msg.body.key.keyCode = keyCode;
    msg.body.key.scanCode = scanCode;
    msg.body.key.metaState = metaState;
    msg.body.key.repeatCount = repeatCount;
    msg.body.key.downTime = downTime;
    msg.body.key.eventTime = eventTime;
    //调用InputChannel::sendMessage` 将构建好的 `InputMessage` 发送到目标应用进程
    return mChannel->sendMessage(&msg);
}


status_t InputPublisher::publishMotionEvent(
        uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, int32_t displayId,
        std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
        int32_t edgeFlags, int32_t metaState, int32_t buttonState,
        MotionClassification classification, const ui::Transform& transform, float xPrecision,
        float yPrecision, float xCursorPosition, float yCursorPosition, int32_t displayWidth,
        int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
   
    ...
    //声明一个 `InputMessage` 结构体实例,用于承载所有事件数据
    InputMessage msg;
    msg.header.type = InputMessage::Type::MOTION;
    msg.header.seq = seq;
    msg.body.motion.eventId = eventId;
    msg.body.motion.deviceId = deviceId;
    msg.body.motion.source = source;
    msg.body.motion.displayId = displayId;
    msg.body.motion.hmac = std::move(hmac);
    msg.body.motion.action = action;
    msg.body.motion.actionButton = actionButton;
    msg.body.motion.flags = flags;
    msg.body.motion.edgeFlags = edgeFlags;
    msg.body.motion.metaState = metaState;
    msg.body.motion.buttonState = buttonState;
    msg.body.motion.classification = classification;
    msg.body.motion.dsdx = transform.dsdx();
    msg.body.motion.dtdx = transform.dtdx();
    msg.body.motion.dtdy = transform.dtdy();
    msg.body.motion.dsdy = transform.dsdy();
    msg.body.motion.tx = transform.tx();
    msg.body.motion.ty = transform.ty();
    msg.body.motion.xPrecision = xPrecision;
    msg.body.motion.yPrecision = yPrecision;
    msg.body.motion.xCursorPosition = xCursorPosition;
    msg.body.motion.yCursorPosition = yCursorPosition;
    msg.body.motion.displayWidth = displayWidth;
    msg.body.motion.displayHeight = displayHeight;
    msg.body.motion.downTime = downTime;
    msg.body.motion.eventTime = eventTime;
    msg.body.motion.pointerCount = pointerCount;
    for (uint32_t i = 0; i < pointerCount; i++) {
        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
    }

    //调用InputChannel::sendMessage` 将构建好的 `InputMessage` 发送到目标应用进程
    return mChannel->sendMessage(&msg);
}

publishMotionEventpublishKeyEvent只是数据发送的开端。最终,事件会通过Socket发送到应用进程。应用端的 NativeInputEventReceiver 会监听Socket,当有数据可读时,其 handleEvent 被回调,进而调用 InputConsumer::consume 从Socket中读取 InputMessage 并还原成 MotionEventKeyEvent 对象,最后通过JNI回调到Java层的 InputEventReceiver.dispatchInputEvent,交由应用处理。

scss 复制代码
//frameworks/base/core/jni/android_view_InputEventReceiver.cpp
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
    ...
    if (events & ALOOPER_EVENT_INPUT) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        //核心
        status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
        //会将 JNI 环境中可能发生的异常抛回 Java 层,
        并以 `handleReceiveCallback` 作为上下文
        mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
        return status == OK || status == NO_MEMORY ? KEEP_CALLBACK : REMOVE_CALLBACK;
    }

    ... 
  
    return KEEP_CALLBACK;
}


status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
        bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
    
    ...
    for (;;) {
        uint32_t seq;
        InputEvent* inputEvent;
        //从 `InputChannel` 的 Socket 中读取一个 `InputMessage`,
        解析并构建 `InputEvent` 对象。
        status_t status = mInputConsumer.consume(&mInputEventFactory,
                consumeBatches, frameTime, &seq, &inputEvent);
        //OK成功消费一个事件,WOULD_BLOCK没有更多事件可读
        if (status != OK && status != WOULD_BLOCK) {
            return status;
        }
        //无事件可读时
        if (status == WOULD_BLOCK) {
            //检查是否有批量事件等待处理(系统端可能会将多个 `ACTION_MOVE` 
            事件打包)。
            if (!skipCallbacks && !mBatchedInputEventPending && mInputConsumer.hasPendingBatch()) {
                // There is a pending batch.  Come back later.
                //通过弱引用获取 `InputEventReceiver` 对象
                if (!receiverObj.get()) {
                    receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
                    if (!receiverObj.get()) {
                        
                        return DEAD_OBJECT;
                    }
                }

                mBatchedInputEventPending = true;
                if (kDebugDispatchCycle) {
                    ALOGD("channel '%s' ~ Dispatching batched input event pending notification.",
                          getInputChannelName().c_str());
                }
                //通知 Java 层有批量事件待处理,Java 层会在下一个
                VSYNC 时主动调用 `consumeBatchedInputEvents` 来消费
                env->CallVoidMethod(receiverObj.get(),
                                    gInputEventReceiverClassInfo.onBatchedInputEventPending,
                                    mInputConsumer.getPendingBatchSource());
                if (env->ExceptionCheck()) {
                  //如果回调发生异常,重置 `mBatchedInputEventPending`
                    mBatchedInputEventPending = false; // try again later
                }
            }
            return OK;
        }
        assert(inputEvent);

        if (!skipCallbacks) {
            //获取 Java 层 InputEventReceiver 对象
            if (!receiverObj.get()) {
                receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
                if (!receiverObj.get()) {
                    ALOGW("channel '%s' ~ Receiver object was finalized "
                            "without being disposed.", getInputChannelName().c_str());
                    return DEAD_OBJECT;
                }
            }

            jobject inputEventObj;
            //事件类型
            switch (inputEvent->getType()) {
            //按键事件
            case AINPUT_EVENT_TYPE_KEY:
                //通过 JNI 辅助函数创建一个 Java `KeyEvent` 对象。
                inputEventObj = android_view_KeyEvent_fromNative(env,
                        static_cast<KeyEvent*>(inputEvent));
                break;
            //触摸事件
            case AINPUT_EVENT_TYPE_MOTION: {
                
                MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent);
                //如果是 `ACTION_MOVE` 事件,标记 `outConsumedBatch = true`
                (表示消费了批量事件)。

                
                if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) {
                    *outConsumedBatch = true;
                }
                //创建 Java `MotionEvent` 对象
                inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
                break;
            }
            
            ...
            

            if (inputEventObj) {
                //将 C++ 的 `InputEvent` 转换为 Java 对象。
                //调用 Java 层的 `dispatchInputEvent` 方法,将事件传递给应用
                env->CallVoidMethod(receiverObj.get(),
                        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
                if (env->ExceptionCheck()) {
                //如果发生异常,设置 `skipCallbacks = true`,并立即
                发送 `finished` 信号(`handled = false`)告知系统服务端事件
                已处理(无论应用是否消费)。
                    skipCallbacks = true;
                }
                env->DeleteLocalRef(inputEventObj);
            } else {
              
                skipCallbacks = true;
            }
        }

        if (skipCallbacks) {
        //应用端在消费完输入事件后,**向系统侧的 `InputDispatcher` 发送
        "事件已处理"确认信号**的关键步骤。这个信号是实现整个输入系统"同步-反馈"闭环
        的核心,也是 ANR(应用无响应)检测机制的基础
            mInputConsumer.sendFinishedSignal(seq, false);
        }
    }
}



//frameworks/base/core/java/android/view/InputEventReceiver.java
//InputEventReceiver是抽象类,WindowInputEventReceiver实现了InputEventReceiver
private void dispatchInputEvent(int seq, InputEvent event) {
    mSeqMap.put(event.getSequenceNumber(), seq);
    onInputEvent(event);
}


//frameworks/base/core/java/android/view/ViewRootImpl.java
@Override
public void onInputEvent(InputEvent event) {
   
    List<InputEvent> processedEvents;
    try {
        //负责处理输入事件的兼容性适配
        processedEvents =
            mInputCompatProcessor.processInputEventForCompatibility(event);
    } finally {
        
    }
    if (processedEvents != null) {
        if (processedEvents.isEmpty()) {
            //表示兼容性处理器已消费该事件(例如,事件被转换为其他行为),
            直接调用 `finishInputEvent(event, true)` 通知 Native 层事件已处理
            finishInputEvent(event, true);
        } else {
            for (int i = 0; i < processedEvents.size(); i++) {
                //将处理后的每个事件依次入队,
                并标记 `FLAG_MODIFIED_FOR_COMPATIBILITY`(
                表示该事件已被兼容性修改),最后一个参数 `true` 表示这是
                一个**异步**事件(不会阻塞等待)
                enqueueInputEvent(
                        processedEvents.get(i), this,
                        QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
            }
        }
    } else {
        //直接使用原始事件入队,无特殊标记
        enqueueInputEvent(event, this, 0, true);
    }
}


//输入事件加入待处理队列的核心逻辑
void enqueueInputEvent(InputEvent event,
        InputEventReceiver receiver, int flags, boolean processImmediately) {
        
    //从对象池中获取或新创建一个 `QueuedInputEvent` 对象,
    将事件、接收器和标志封装进去。
    QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
    ...
    QueuedInputEvent last = mPendingInputEventTail;
    if (last == null) {
        //队首指针
        mPendingInputEventHead = q;
        //队尾指针
        mPendingInputEventTail = q;
    } else {
        last.mNext = q;
        mPendingInputEventTail = q;
    }
    mPendingInputEventCount += 1;
   

    if (processImmediately) {
        //立即调用 `doProcessInputEvents()` 同步处理队列中的所有事件。
        这通常用于触摸事件,需要尽可能快地响应用户交互
        doProcessInputEvents();
    } else {
        //通过 Handler 发送消息,异步调度处理。这通常用于按键事件
        或一些不需要立即响应的场景,避免阻塞当前正在执行的操作
        scheduleProcessInputEvents();
    }
}



void doProcessInputEvents() {
    // Deliver all pending input events in the queue.
    while (mPendingInputEventHead != null) {
        //从队首取出一个 `QueuedInputEvent`
        QueuedInputEvent q = mPendingInputEventHead;
        //更新头指针指向下一个节点
        mPendingInputEventHead = q.mNext;
        //如果队列变空,同时将尾指针置为 `null`
        if (mPendingInputEventHead == null) {
            mPendingInputEventTail = null;
        }
        //将取出的节点的 `mNext` 置为 `null`(断开与原队列的链接)
        q.mNext = null;
        mPendingInputEventCount -= 1;
        

       //将事件信息设置到帧信息中,用于后续的渲染调度
       //为事件分配一个 `EventReceiver`(用于 Choreographer 的帧调度,
       确保输入事件与渲染帧对齐)
      mViewFrameInfo.setInputEvent(mInputEventAssigner.processEvent(q.mEvent));

        //将事件实际分发给 View 树
        deliverInputEvent(q);
    }

    
    if (mProcessInputEventsScheduled) {
        mProcessInputEventsScheduled = false;
        //现在清除该标志并移除消息。避免重复处理
        mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);
    }
}

private void deliverInputEvent(QueuedInputEvent q) {
    ...
    try {
        ...

        InputStage stage;
        //`mSyntheticInputStage`:合成输入阶段(处理游戏手柄等)。
       //`mFirstPostImeInputStage`:IME 之后的阶段(通常用于 View 树分发)。
       //`mFirstInputStage`:默认阶段(经过 IME)。
        //是否应发送到合成器(用于处理游戏手柄、传感器等模拟输入
        if (q.shouldSendToSynthesizer()) {
            stage = mSyntheticInputStage;
        } else {
            //是否跳过 IME(输入法)处理。例如,某些系统按键或注入事件不需要经过输入法。
            stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
        }

        if (q.mEvent instanceof KeyEvent) {
            
            try {
                //按键事件进行预分发
                mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }

        if (stage != null) {
            //在分发事件前确保窗口焦点状态是最新的
            handleWindowFocusChanged();
            //将事件传递给选定的 `InputStage` 进行处理
            stage.deliver(q);
        } else {
            //如果没有可用 Stage(异常情况),直接完成事件。
            finishInputEvent(q);
        }
    } finally {
       
    }
}
相关推荐
zhangguojia72 小时前
从一个窗口覆盖问题出发,理解 Android Window 的层级与权限
android
古法安卓4 小时前
Android-SELinux 策略调试实战:从 AVC 日志到策略修复
android·java·android studio
Dovis(誓平步青云)5 小时前
DevEco Studio 6.1.1 Windows 安装实录:从下载校验到首次启动
android·开发语言·数据库·人工智能·windows·harmonyos
Zender Han5 小时前
Flutter 自适应(Adaptive)与响应式(Responsive)设计实践:官方推荐方案详解
android·flutter·ios
我命由我123456 小时前
Android 开发问题:TopAppBar 和 topAppBarColors API is experimental...
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
造火箭6 小时前
Android UI自动化测试可行性评估SKILL
android·功能测试·ui
hunterandroid8 小时前
[Android 从零到一] ViewPager2 与 Fragment 生命周期协同:从预加载到状态一致性
android·前端
mmsx8 小时前
一个黑边 Bug 修了两版:自己算矩阵直接黑屏,借库重建只用了一行 setZoom
android·前端
枢影Kernel8 小时前
Android CLI 与 Android Skills 最佳实践:把 AI Agent 接入可验证的 Android 开发流程
android