AOSP15 Input专题InputDispatcher源码分析

0 阅读7分钟

InputReader 依然是输入系统(Input System)的核心组件,负责从内核读取原始事件数据。需要将其放在 InputDispatcher 进行派发处理。

一、 核心流程概览

  1. 系统事件流程
InputDispatcher::dispatchOnce() 
  -> dispatchOnceInnerLocked() 
    -> dispatchMotionLocked() // 处理 Motion 事件
      -> findTouchedWindowTargetsLocked(currentTime, motionEntry, inputTargets, nextWakeupTime) //计算目标窗口 (核心算法),该函数决定了事件最终去向哪里窗口
      -> dispatchEventLocked(nsecs_t currentTime,std::shared_ptr<const EventEntry> eventEntry,const std::vector<InputTarget>& inputTargets) 
        -> prepareDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection>& connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget& inputTarget) 
          -> enqueueDispatchEntryAndStartDispatchCycleLocked(nsecs_t currentTime, const std::shared_ptr<Connection>& connection,std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) 
            -> enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget& inputTarget)//构建DispatchEntry,将事件封装进每个目标窗口的 outboundQueue
            -> startDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection>& connection)//实际执行 Socket 发送
  1. 应用层接收反馈
InputDispatcher
  -> InputChannel
     -> WindowInputEventReceiver
         -> ViewRootImpl.enqueueInputEvent
            -> ViewRootImpl.doProcessInputEvents
               -> deliverInputEvent
                  -> InputStage pipeline
                     -> View.dispatchTouchEvent
                        -> View.onTouchEvent
                           -> finishInputEvent

二、 详细调用链路分析

1. dispatchOnce(): 主循环入口

void InputDispatcher::dispatchOnce() {
    nsecs_t nextWakeupTime = LLONG_MAX;
    { 
        std::scoped_lock _l(mLock);
        mDispatcherIsAlive.notify_all();

        // 省略代码
        if (!haveCommandsLocked()) {
            dispatchOnceInnerLocked(/*byref*/ nextWakeupTime);
        }

        // 省略代码
    } 
    // 省略代码
}

2. dispatchOnceInnerLocked(): 事件分发的核心逻辑所在

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    // [步骤 1] 检查 ANR: 在派发新事件前,必须先处理超时的连接
    processAnrsLocked();

    // [步骤 2] 获取并处理队列中的事件 (mPendingEvent)
    if (mPendingEvent) {
        // ... (省略部分逻辑) ...
        // [步骤 3] 分发 Motion 事件
        if (dispatchMotionLocked(currentTime, static_cast<MotionEntry*>(mPendingEvent), ...)) {
            // ...
        }
    }
}

3. dispatchMotionLocked() (以触摸事件为例):

bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
                                           std::shared_ptr<const MotionEntry> entry,
                                           DropReason* dropReason, nsecs_t& nextWakeupTime) {
    // 省略代码
    if (isPointerEvent) {
       // 省略代码

        // 根据当前所有窗口的层级 (Z-order)、坐标范围、以及 WindowInfo 的标志位(如 FLAG_NOT_TOUCH_MODAL)来计算谁该接收这个触摸
        Result<std::vector<InputTarget>, InputEventInjectionResult> result =
                findTouchedWindowTargetsLocked(currentTime, *entry);

        // 省略代码
    } else {
       // 省略代码
        addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
                                  InputTarget::Flags::FOREGROUND, getDownTime(*entry),
                                  inputTargets);
        // 省略代码
    }
    // 省略代码
    // 开始处理DispatchEntry数据
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}

4. dispatchEventLocked()

void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
                                          std::shared_ptr<const EventEntry> eventEntry,
                                          const std::vector<InputTarget>& inputTargets) {
    ATRACE_CALL();
    // 省略代码
    for (const InputTarget& inputTarget : inputTargets) {
        std::shared_ptr<Connection> connection = inputTarget.connection;
        prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
    }
}

5. prepareDispatchCycleLocked()

void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
                                                 const std::shared_ptr<Connection>& connection,
                                                 std::shared_ptr<const EventEntry> eventEntry,
                                                 const InputTarget& inputTarget) {
     // 省略代码
    if (connection->status != Connection::Status::NORMAL) {
        if (DEBUG_DISPATCH_CYCLE) {
            ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
                  connection->getInputChannelName().c_str(),
                  ftl::enum_string(connection->status).c_str());
        }
        return;
    }

    // 分屏split
    if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {

        const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
        if (inputTarget.getPointerIds().count() != originalMotionEntry.getPointerCount()) {
            // 省略代码
            enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
                                                            std::move(splitMotionEntry),
                                                            inputTarget);
            return;
        }
    }
    // 单屏
    enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
                                                    inputTarget);
}

6. enqueueDispatchEntryAndStartDispatchCycleLockeds()

void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
        nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
        std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
   
    // 构建DispatchEntry,将事件封装进每个目标窗口的 
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);

    // 发送分发消息给应用
    if (wasEmpty && !connection->outboundQueue.empty()) {
        startDispatchCycleLocked(currentTime, connection);
    }
}

7. enqueueDispatchEntryLocked()

构建DispatchEntry,塞入outboundQueue

void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
                                                 std::shared_ptr<const EventEntry> eventEntry,
                                                 const InputTarget& inputTarget) {
    // 省略代码
    eventEntry = dispatchEntry->eventEntry;
    switch (eventEntry->type) {
        // 省略代码
        case EventEntry::Type::MOTION: {
            std::shared_ptr<const MotionEntry> resolvedMotion =
                    std::static_pointer_cast<const MotionEntry>(eventEntry);
            {
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
                int32_t resolvedAction = motionEntry.action;
                int32_t resolvedFlags = motionEntry.flags;

                if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
                    resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
                } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
                    resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
                } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
                    resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
                } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
                    resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
                } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
                    resolvedAction = AMOTION_EVENT_ACTION_DOWN;
                }
                if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
                    !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
                                                       motionEntry.displayId)) {
                    if (DEBUG_DISPATCH_CYCLE) {
                        LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
                                   << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
                                      "enter event";
                    }
                    resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
                }

                if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
                    resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
                }
                if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
                    resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
                }
                if (dispatchEntry->targetFlags.test(
                            InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
                    resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
                }
                if (dispatchEntry->targetFlags.test(InputTarget::Flags::NO_FOCUS_CHANGE)) {
                    resolvedFlags |= AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
                }

                dispatchEntry->resolvedFlags = resolvedFlags;
                if (resolvedAction != motionEntry.action) {
                    std::optional<std::vector<PointerProperties>> usingProperties;
                    std::optional<std::vector<PointerCoords>> usingCoords;
                    if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT ||
                        resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
                        const bool hovering = resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT;
                        std::optional<std::pair<std::vector<PointerProperties>,
                                                std::vector<PointerCoords>>>
                                pointerInfo =
                                        connection->inputState.getPointersOfLastEvent(motionEntry,
                                                                                      hovering);
                        if (pointerInfo) {
                            usingProperties = pointerInfo->first;
                            usingCoords = pointerInfo->second;
                        }
                    }
                    {
                        // Generate a new MotionEntry with a new eventId using the resolved action
                        // and flags, and set it as the resolved entry.
                        auto newEntry = std::make_shared<
                                MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
                                             motionEntry.eventTime, motionEntry.deviceId,
                                             motionEntry.source, motionEntry.displayId,
                                             motionEntry.policyFlags, resolvedAction,
                                             motionEntry.actionButton, resolvedFlags,
                                             motionEntry.metaState, motionEntry.buttonState,
                                             motionEntry.classification, motionEntry.edgeFlags,
                                             motionEntry.xPrecision, motionEntry.yPrecision,
                                             motionEntry.xCursorPosition,
                                             motionEntry.yCursorPosition, motionEntry.downTime,
                                             usingProperties.value_or(
                                                     motionEntry.pointerProperties),
                                             usingCoords.value_or(motionEntry.pointerCoords));
                        if (mTracer) {
                            ensureEventTraced(motionEntry);
                            newEntry->traceTracker =
                                    mTracer->traceDerivedEvent(*newEntry,
                                                               *motionEntry.traceTracker);
                        }
                        resolvedMotion = newEntry;
                    }
                    if (ATRACE_ENABLED()) {
                        std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
                                                           ") to MotionEvent(id=0x%" PRIx32 ").",
                                                           motionEntry.id, resolvedMotion->id);
                        ATRACE_NAME(message.c_str());
                    }
                    dispatchEntry->eventEntry = resolvedMotion;
                    eventEntry = resolvedMotion;
                }
            }
            std::unique_ptr<EventEntry> cancelEvent =
                    connection->inputState.cancelConflictingInputStream(*resolvedMotion);
            if (cancelEvent != nullptr) {
                LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
                          << connection->getInputChannelName() << " with event "
                          << cancelEvent->getDescription();
                if (mTracer) {
                    static_cast<MotionEntry&>(*cancelEvent).traceTracker =
                            mTracer->traceDerivedEvent(*cancelEvent, *resolvedMotion->traceTracker);
                }
                std::unique_ptr<DispatchEntry> cancelDispatchEntry =
                        createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent),
                                            ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId,
                                            mTracer.get());

                // 生成cancel事件,加入队列
                connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
            }

            // 省略代码

            break;
        }
        // 省略代码
    }

    // 省略代码

    // 塞入waitQueue
    connection->outboundQueue.emplace_back(std::move(dispatchEntry));
    traceOutboundQueueLength(*connection);
}

8. startDispatchCycleLocked()

发送消息个应用侧

oid InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                               const std::shared_ptr<Connection>& connection) {
    ATRACE_NAME_IF(ATRACE_ENABLED(),
                   StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
                                connection->getInputChannelName().c_str()));
    if (DEBUG_DISPATCH_CYCLE) {
        ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
    }

    while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
        std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
        dispatchEntry->deliveryTime = currentTime;
        const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
        dispatchEntry->timeoutTime = currentTime + timeout.count();

        // Publish the event.
        status_t status;
        const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
        switch (eventEntry.type) {
            // 省略代码
            case EventEntry::Type::MOTION: {
                if (DEBUG_OUTBOUND_EVENT_DETAILS) {
                    LOG(INFO) << "Publishing " << *dispatchEntry << " to "
                              << connection->getInputChannelName();
                }
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
                // 发送sockets给应用侧
                status = publishMotionEvent(*connection, *dispatchEntry);
                if (status == BAD_VALUE) {
                    logDispatchStateLocked();
                    LOG(FATAL) << "Publisher failed for " << motionEntry;
                }
                if (mTracer) {
                    ensureEventTraced(motionEntry);
                    mTracer->traceEventDispatch(*dispatchEntry, *motionEntry.traceTracker);
                }
                break;
            }

           // 省略代码
        }

        // 省略代码

        const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
        // 加入等待队列,用于判断ANR
        connection->waitQueue.emplace_back(std::move(dispatchEntry));
        //移除oq中数据
        connection->outboundQueue.erase(connection->outboundQueue.begin());
        traceOutboundQueueLength(*connection);
        if (connection->responsive) {
            // 加入等待队列,用于判断ANR
            mAnrTracker.insert(timeoutTime, connection->getToken());
        }
        traceWaitQueueLength(*connection);
    }
}

三、ANR的产生分析

1、ANR 主要分为 4 类:

类型触发位置超时时间
Input ANRInputDispatcher默认 5s
Broadcast ANRAMS前台 10s / 后台 60s
Service ANRAMS20s
ContentProvider ANRAMS10s

2、我们看最常碰到Input ANR

  • startDispatchCycleLocked()构建DispatchEntry时候加入waitQueuemAnrTracher用于判断超时:
oid InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                               const std::shared_ptr<Connection>& connection) {
    ATRACE_NAME_IF(ATRACE_ENABLED(),
                   StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
                                connection->getInputChannelName().c_str()));
    if (DEBUG_DISPATCH_CYCLE) {
        ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
    }

    while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
        std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
        // 省略代码
        const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
        switch (eventEntry.type) {
            // 省略代码
            case EventEntry::Type::MOTION: {
                // 省略代码
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
                // 发送sockets给应用侧
                status = publishMotionEvent(*connection, *dispatchEntry);
                // 省略代码
                break;
            }

           // 省略代码
        }

        // 省略代码
        const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
        // 加入等待队列,用于判断ANR
        connection->waitQueue.emplace_back(std::move(dispatchEntry));
        //移除oq中数据
        connection->outboundQueue.erase(connection->outboundQueue.begin());
        traceOutboundQueueLength(*connection);
        if (connection->responsive) {
            // 加入等待队列,用于判断ANR
            mAnrTracker.insert(timeoutTime, connection->getToken());
        }
        traceWaitQueueLength(*connection);
    }
}
  • processAnrsLocked()判断是否ANR

系统通过 mAnrTracker 维护每一个 Connection 的超时定时器。

返回值含义
LLONG_MIN立即重新循环(刚触发 ANR)
某个时间戳下一次应检查 ANR 的时间
LLONG_MAX当前没有任何需要检查的 ANR
nsecs_t InputDispatcher::processAnrsLocked() {
    const nsecs_t currentTime = now();
    nsecs_t nextAnrCheck = LLONG_MAX;
    // 没焦点anr
    if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
        if (currentTime >= *mNoFocusedWindowTimeoutTime) {
            processNoFocusedWindowAnrLocked();
            mAwaitedFocusedApplication.reset();
            mNoFocusedWindowTimeoutTime = std::nullopt;
            return LLONG_MIN;
        } else {
            nextAnrCheck = *mNoFocusedWindowTimeoutTime;
        }
    }
    // 来获取最早的一个超时时间
    nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
    // 没超时直接返回
    if (currentTime < nextAnrCheck) { 
        return nextAnrCheck;         
    }
    std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
    // 没有等待的connection
    if (connection == nullptr) {
        return nextAnrCheck;
    }
    connection->responsive = false;
    // 从监控列表中移除该连接,防止重复触发。
    mAnrTracker.eraseToken(connection->getToken());
    // 触发ANR
    onAnrLocked(connection);
    return LLONG_MIN;
}
  • 应用侧接收 (Native 接入点) App 进程中的 NativeInputEventReceiver 通过 Looper 监听到 Socket 可读。
// frameworks/native/android/native_input_event_receiver.cpp
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
    if (events & ALOOPER_EVENT_INPUT) {
        // 1. 从 Socket 读取数据
        // 2. 调用 JNI 方法通知 Java 层
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        env->CallVoidMethod(mReceiverObjGlobal.get(), gInputEventReceiverClassInfo.dispatchInputEvent, ...);
    }
    return 1; // Keep monitoring
}
  • Java 层调度 (ViewRootImpl 入口) 通过 JNI,事件进入 Java 层的 WindowInputEventReceiver。
// frameworks/base/core/java/android/view/InputEventReceiver.java

// JNI 调用此方法
public void dispatchInputEvent(int seq, InputEvent event) {
    // 放入 MessageQueue,唤醒 App 主线程
    onInputEvent(event, seq);
}
  • 事件处理分发 deliverInputEvent 被调用的地方。
// frameworks/base/core/java/android/view/ViewRootImpl.java

final class WindowInputEventReceiver extends InputEventReceiver {
    public void onInputEvent(InputEvent event, int seq) {
        enqueueInputEvent(event, this, seq, true); // 放入主线程队列
    }
}

// 最终由主线程 Handler 执行:
void doProcessInputEvents() {
    while (mPendingInputEventHead != null) {
        QueuedInputEvent q = mPendingInputEventHead;
        // 核心调用链在此:
        deliverInputEvent(q);
    }
}

void deliverInputEvent(QueuedInputEvent q) {
    // 这一步将事件交给第一个 Stage (流水线处理)
    q.mStage.deliver(q);
}
  • finishInputEvent回调
final class WindowInputEventReceiver extends InputEventReceiver {
        public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
            super(inputChannel, looper);
        }

        @Override
        public void onInputEvent(InputEvent event) {
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");
            List<InputEvent> processedEvents;
            try {
                processedEvents =
                    mInputCompatProcessor.processInputEventForCompatibility(event);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
            if (processedEvents != null) {
                if (processedEvents.isEmpty()) {
                    // 告诉InputDispatcher完成事件,不然可能导致,Input dispatching timed out (ANR)
                    finishInputEvent(event, true);
                } else {
                    for (int i = 0; i < processedEvents.size(); i++) {
                        // 生成新事件,兼容层把 一个事件变成多个事件。deliverInputEvent()
                        enqueueInputEvent(
                                processedEvents.get(i), this,
                                QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
                    }
                }
            } else {
                // 生成新事件,兼容层把 一个事件变成多个事件。最终调用deliverInputEvent()
                enqueueInputEvent(event, this, 0, true);
            }
        }
}
  • deliverInputEvent()
private void deliverInputEvent(QueuedInputEvent q) {
        // 省略代码
        try {
            if (mInputEventConsistencyVerifier != null) {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "verifyEventConsistency");
                try {
                    mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                }
            }

            InputStage stage;
            if (q.shouldSendToSynthesizer()) {
                stage = mSyntheticInputStage;
            } else {
                stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
            }

            if (q.mEvent instanceof KeyEvent) {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "preDispatchToUnhandledKeyManager");
                try {
                    // key事件预派发处理
                    mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                }
            }

            if (stage != null) {
                // 窗口焦点处理
                handleWindowFocusChanged();
                stage.deliver(q);
            } else {
                 // 告诉InputDispatcher完成事件,不然可能导致,Input dispatching timed out (ANR)
                finishInputEvent(q);
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
}

3、流程图概况