覆盖范围:硬件中断 → EventHub → InputReader → InputDispatcher → Socket → ViewRootImpl → View 树


一、整体架构分层

┌──────────────────────────────────────────────────────────┐
│                        硬件层                             │
│   触摸屏产生中断 → 内核 input 子系统                       │
│   写入 /dev/input/eventX                                 │
└───────────────────────────┬──────────────────────────────┘
                            ↓
┌──────────────────────────────────────────────────────────┐
│                       Native 层                           │
│                                                          │
│  ┌─────────┐   ┌─────────────┐   ┌──────────────────┐  │
│  │EventHub │──▶│ InputReader │──▶│ InputDispatcher  │  │
│  │读硬件事件│   │  加工事件   │   │ 找窗口 发Socket  │  │
│  └─────────┘   └─────────────┘   └──────────────────┘  │
└───────────────────────────┬──────────────────────────────┘
                            ↓  Unix Domain Socket
┌──────────────────────────────────────────────────────────┐
│                      应用进程层                            │
│                                                          │
│  InputEventReceiver → ViewRootImpl → InputStage 责任链   │
│  DecorView → Activity → ViewGroup → View                 │
└──────────────────────────────────────────────────────────┘

二、第一层:EventHub 读取硬件事件

文件frameworks/native/services/inputflinger/reader/EventHub.cpp

input_event 结构体(Linux 内核定义)

struct input_event {
    struct timeval time;  // 时间戳
    __u16 type;           // EV_ABS(触摸)/ EV_KEY(按键)/ EV_SYN(同步)
    __u16 code;           // ABS_MT_POSITION_X/Y / KEY_POWER 等
    __s32 value;          // 坐标值或按键状态(1=按下 0=抬起)
};

getEvents() 核心流程

std::vector<RawEvent> EventHub::getEvents(int timeoutMillis) {
    std::scoped_lock _l(mLock);  // 加锁

    for (;;) {
        // ① 处理待关闭设备,生成 DEVICE_REMOVED 事件
        for (auto it = mClosingDevices.begin(); ...) {
            events.push_back({ .when=now, .deviceId=id, .type=DEVICE_REMOVED });
        }

        // ② 扫描新设备(/dev/input/ 目录)
        if (mNeedToScanDevices) {
            scanDevicesLocked();  // 打开新设备 fd,注册到 epoll
        }

        // ③ 上报新打开的设备,生成 DEVICE_ADDED 事件
        while (!mOpeningDevices.empty()) {
            events.push_back({ .when=now, .deviceId=id, .type=DEVICE_ADDED });
            mDevices.insert_or_assign(device->id, std::move(device));
        }

        // ④ 遍历 epoll 就绪的 fd,读取真实输入事件
        while (mPendingEventIndex < mPendingEventCount) {
            const epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];

            if (eventItem.data.fd == mINotifyFd) {
                mPendingINotify = true;  // 设备插拔通知,延迟处理
                continue;
            }
            if (eventItem.data.fd == mWakeReadPipeFd) {
                awoken = true;           // 被主动唤醒(配置变化等)
                continue;
            }

            // 读取输入设备数据
            int32_t readSize = read(device->fd, readBuffer.data(), bufferBytes);

            const size_t count = readSize / sizeof(struct input_event);
            for (size_t i = 0; i < count; i++) {
                struct input_event& iev = readBuffer[i];
                events.push_back({
                    .when     = processEventTimestamp(iev),  // 时间戳校正
                    .readTime = systemTime(SYSTEM_TIME_MONOTONIC),
                    .deviceId = deviceId,
                    .type     = iev.type,   // EV_ABS / EV_KEY
                    .code     = iev.code,   // ABS_MT_POSITION_X 等
                    .value    = iev.value,  // 坐标值
                });
            }
        }

        // ⑤ 有事件就返回,没有就 epoll_wait 阻塞等待
        if (!events.empty() || awoken) break;

        mLock.unlock();
        int pollResult = epoll_wait(mEpollFd, mPendingEventItems,
                                    EPOLL_MAX_EVENTS, timeoutMillis);
        mLock.lock();

        if (pollResult == 0) break;           // 超时
        mPendingEventCount = size_t(pollResult);
    }
    return events;
}

EventHub 关键设计

机制 作用
epoll_wait 阻塞等待,有事件才唤醒,不空转
inotify 监听 /dev/input/ 目录变化,检测设备插拔
mWakeReadPipeFd 特殊管道,配置变化时主动唤醒 epoll
EPOLLWAKEUP 持有 wake lock 直到下次 epoll_wait,防止休眠丢事件
buffer 满回退 mPendingEventIndex -= 1,下次从当前设备继续读,不丢事件

三、第二层:InputReader 加工事件

文件frameworks/native/services/inputflinger/reader/InputReader.cpp

loopOnce() 主循环

void InputReader::loopOnce() {
    // ① 加锁,计算超时时间
    {
        std::scoped_lock _l(mLock);
        oldGeneration = mGeneration;
        timeoutMillis = -1;  // 默认无限等待

        auto changes = mConfigurationChangesToRefresh;
        if (changes.any()) {
            timeoutMillis = 0;                   // 有配置变化,立即处理
            refreshConfigurationLocked(changes); // 刷新灵敏度/键映射等配置
        } else if (mNextTimeout != LLONG_MAX) {
            // 有定时任务(长按检测等),计算剩余等待时间
            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
        }
    } // 解锁,避免阻塞期间其他线程无法访问

    // ② 阻塞读取原始事件(无锁)
    std::vector<RawEvent> events = mEventHub->getEvents(timeoutMillis);

    // ③ 加锁,处理事件
    {
        std::scoped_lock _l(mLock);
        mReaderIsAliveCondition.notify_all();  // 心跳

        if (!events.empty()) {
            mPendingArgs += processEventsLocked(events.data(), events.size());
        }

        // 处理定时超时(如长按触发)
        if (mNextTimeout != LLONG_MAX && now >= mNextTimeout) {
            mNextTimeout = LLONG_MAX;
            mPendingArgs += timeoutExpiredLocked(now);
        }

        // 设备列表有变化,通知上层
        if (oldGeneration != mGeneration) {
            inputDevicesChanged = true;
            inputDevices = getInputDevicesLocked();
        }
        std::swap(notifyArgs, mPendingArgs);
    } // 解锁

    // ④ 锁外通知 InputDispatcher(防止死锁)
    for (const NotifyArgs& args : notifyArgs) {
        mNextListener.notify(args);
    }
}

processEventsLocked() 批量处理

std::list<NotifyArgs> InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count;) {
        int32_t type = rawEvent->type;
        size_t batchSize = 1;

        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
            // 真实硬件事件:把同一设备的连续事件打包批量处理
            int32_t deviceId = rawEvent->deviceId;
            while (batchSize < count) {
                if (rawEvent[batchSize].type >= FIRST_SYNTHETIC_EVENT
                        || rawEvent[batchSize].deviceId != deviceId) break;
                batchSize++;
            }
            // 交给对应设备的 InputMapper 处理
            out += processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
        } else {
            // 合成事件:设备增删
            switch (rawEvent->type) {
                case DEVICE_ADDED:   addDeviceLocked(...);    break;
                case DEVICE_REMOVED: removeDeviceLocked(...); break;
                case FINISHED_DEVICE_SCAN: handleConfigurationChangedLocked(...); break;
            }
        }
        count -= batchSize;
        rawEvent += batchSize;  // 指针后移
    }
    return out;
}

InputMapper:核心加工逻辑

原始 RawEvent(只有 type/code/value)
         ↓
TouchInputMapper(触摸屏专属)
  - 多点触摸协议解析(A 协议:绝对坐标 / B 协议:Slot 追踪)
  - 坐标归一化(原始值 → 屏幕像素坐标)
  - 屏幕方向变换(横竖屏旋转校正)
  - 手势预识别(区分 TAP / LONG_PRESS / SCROLL)
         ↓
NotifyMotionArgs(包含完整触摸信息)
  - action(DOWN/MOVE/UP)
  - pointerCount(手指数量)
  - pointerCoords[](每个手指的 x/y/pressure/size)
  - eventTime / deviceId / source / displayId

notify() 的类型分发

// InputListenerInterface::notify() 是非虚函数,基类写死
void InputListenerInterface::notify(const NotifyArgs& generalArgs) {
    Visitor v{
        [&](const NotifyMotionArgs& args) { notifyMotion(args); },
        [&](const NotifyKeyArgs& args)    { notifyKey(args); },
        [&](const NotifyInputDevicesChangedArgs& args) { notifyInputDevicesChanged(args); },
        // ... 其他类型
    };
    std::visit(v, generalArgs);
    // std::visit = 识别 variant 的实际类型,调用对应 lambda
    // 等价于 Java 的 instanceof 判断
}
// notifyMotion/notifyKey 是虚函数 → 实际调用 InputDispatcher 的实现

// mNextListener 的真实类型(InputManager.cpp):
// mDispatcher = createInputDispatcher(mPolicy);
// mReader = new InputReader(mEventHub, mPolicy, *mDispatcher);
//                                                ↑ 直接传入 InputDispatcher
// 继承链:InputDispatcher : InputDispatcherInterface : InputListenerInterface

为什么锁外 notify?

InputReader 和 InputDispatcher 互相可能回调对方的方法:
  Dispatcher 处理事件时可能查询 InputReader 的 getScanCodeState()
  如果持锁调用 notify,Dispatcher 回调时需要再次加锁 → 死锁

设计原则:
  加锁:处理事件、修改内部状态
  解锁:阻塞等待、跨组件通知

四、第三层:InputDispatcher 路由与分发

文件frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

4.1 notifyMotion():校验 + 入队

void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
    // ① 合法性校验
    Result<void> motionCheck = validateMotionEvent(
            args.action, args.actionButton,
            args.getPointerCount(), args.pointerProperties.data());
    if (!motionCheck.ok()) { return; }  // 非法事件丢弃

    // ② 标记可信(来自硬件,非注入伪造)
    policyFlags |= POLICY_FLAG_TRUSTED;

    // ③ Policy 入队前拦截(锁外,因为可能做 Binder 调用)
    mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
    // 屏幕熄灭时:移除 POLICY_FLAG_PASS_TO_USER,事件只用于亮屏

    { // 加锁
        // ④ 处理进行中的手势(即使 Policy 拒绝,手势中的事件也要继续)
        if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
            if (touchState.hasTouchingPointers(args.deviceId)) {
                policyFlags |= POLICY_FLAG_PASS_TO_USER;
            }
        }

        // ⑤ InputFilter 过滤(无障碍服务)
        if (shouldSendMotionToInputFilterLocked(args)) {
            mLock.unlock();
            if (!mPolicy.filterInputEvent(event, policyFlags)) return; // 被消费
            mLock.lock();
        }

        // ⑥ 构造 MotionEntry 入队
        auto newEntry = std::make_unique<MotionEntry>(
                args.id, args.eventTime, args.deviceId, args.source,
                args.displayId, policyFlags, args.action, ...);
        needWake = enqueueInboundEventLocked(std::move(newEntry));
    } // 解锁

    if (needWake) mLooper->wake();  // 唤醒 Dispatcher 线程
}

4.2 enqueueInboundEventLocked():队列管理

bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
    bool needWake = mInboundQueue.empty();  // 队列空才需要唤醒
    mInboundQueue.push_back(std::move(newEntry));

    // MOVE 事件堆积优化:直接跳到最新,避免触摸响应滞后(跳帧)
    if (shouldPruneInboundQueueLocked(motionEntry)) {
        mNextUnblockedEvent = mInboundQueue.back();
        needWake = true;
    }

    // AppSwitch 优化:HOME/ENDCALL 设置超时,超时后丢弃其他事件
    if (isAppSwitchKeyEvent(keyEntry)) {
        mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
    }

    return needWake;
}

4.3 dispatchOnce():Dispatcher 线程主循环

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

        if (!haveCommandsLocked()) {
            dispatchOnceInnerLocked(&nextWakeupTime);  // 处理事件
        }

        if (runCommandsLockedInterruptable()) {
            nextWakeupTime = LLONG_MIN;  // 有命令,立即再次处理
        }

        const nsecs_t nextAnrCheck = processAnrsLocked();  // ANR 超时检查
        nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
    }

    // 阻塞等待:mLooper->wake() 调用后从这里醒来
    mLooper->pollOnce(toMillisecondTimeoutDelay(currentTime, nextWakeupTime));
}

4.4 dispatchOnceInnerLocked():出队与路由

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    // 从队列取出事件
    if (!mPendingEvent) {
        if (mInboundQueue.empty()) {
            // 队列空:检查是否需要生成按键重复事件
            if (mKeyRepeatState.lastKeyEntry) {
                mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
            }
            if (!mPendingEvent) return;
        } else {
            mPendingEvent = mInboundQueue.front();
            mInboundQueue.pop_front();
        }
    }

    // 丢弃判断
    DropReason dropReason = DropReason::NOT_DROPPED;
    if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) dropReason = DropReason::POLICY;
    if (!mDispatchEnabled)                         dropReason = DropReason::DISABLED;
    if (isStaleEvent(currentTime, entry))          dropReason = DropReason::STALE;
    if (isAppSwitchDue && !isAppSwitchKey)         dropReason = DropReason::APP_SWITCH;

    // 按类型路由
    switch (mPendingEvent->type) {
        case EventEntry::Type::MOTION:
            done = dispatchMotionLocked(currentTime, motionEntry,
                                        &dropReason, nextWakeupTime);
            break;
        case EventEntry::Type::KEY:
            done = dispatchKeyLocked(currentTime, keyEntry,
                                     &dropReason, nextWakeupTime);
            break;
        case EventEntry::Type::FOCUS:
            dispatchFocusLocked(currentTime, focusEntry);
            break;
    }
}

4.5 dispatchMotionLocked():找目标窗口

bool InputDispatcher::dispatchMotionLocked(...) {
    if (*dropReason != DropReason::NOT_DROPPED) {
        setInjectionResult(*entry, ...);
        return true;  // 需要丢弃,直接返回
    }

    std::vector<InputTarget> inputTargets;
    const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);

    if (isPointerEvent) {
        // 触摸/鼠标事件:找触摸坐标命中的窗口
        inputTargets = findTouchedWindowTargetsLocked(
                currentTime, *entry,
                &conflictingPointerActions, injectionResult);
        // 遍历所有窗口 Z 序
        // 检查 FLAG_NOT_TOUCHABLE / FLAG_NOT_FOCUSABLE 等标志
        // 处理分割屏、画中画等多窗口场景
    } else {
        // 键盘/轨迹球:找当前焦点窗口
        sp<WindowInfoHandle> focusedWindow =
                findFocusedWindowTargetLocked(currentTime, *entry,
                                              nextWakeupTime, injectionResult);
        if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
            addWindowTargetLocked(focusedWindow,
                    InputTarget::Flags::FOREGROUND |
                    InputTarget::Flags::DISPATCH_AS_IS,
                    {}, getDownTime(*entry), inputTargets);
        }
    }

    // 添加全局监听者(无障碍服务、屏幕录制等)
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));

    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}

4.6 dispatchEventLocked():向目标发送

void InputDispatcher::dispatchEventLocked(...) {
    processInteractionsLocked(*eventEntry, inputTargets);
    // 触摸不在焦点窗口时,可能需要转移焦点

    pokeUserActivityLocked(*eventEntry);
    // 通知 PowerManager 有用户活动,防止熄屏

    for (const InputTarget& inputTarget : inputTargets) {
        std::shared_ptr<Connection> connection =
                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
        if (connection != nullptr) {
            prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
        }
        // connection 为 null:窗口已销毁,丢弃
    }
}

4.7 startDispatchCycleLocked():ANR 计时 + 发送

void InputDispatcher::startDispatchCycleLocked(...) {
    while (connection->status == Connection::Status::NORMAL
           && !connection->outboundQueue.empty()) {

        DispatchEntry* dispatchEntry = connection->outboundQueue.front();

        // ANR 计时开始(默认 5 秒,这是 Input ANR 的起点)
        const auto timeout = getDispatchingTimeoutLocked(connection);
        dispatchEntry->timeoutTime = currentTime + timeout.count();

        status_t status;
        switch (eventEntry.type) {
            case EventEntry::Type::MOTION:
                status = publishMotionEvent(*connection, *dispatchEntry);
                break;
            case EventEntry::Type::KEY:
                status = connection->inputPublisher.publishKeyEvent(...);
                break;
        }

        if (status == WOULD_BLOCK) {
            break;  // Socket 缓冲区满,等应用消费后继续
        }

        // 移入 waitQueue,等待应用 finish 回执
        // 超时没收到 finish → processAnrsLocked() 触发 ANR
        connection->outboundQueue.pop_front();
        connection->waitQueue.push_back(dispatchEntry);
    }
}

4.8 publishMotionEvent():坐标变换 + Socket 发送

status_t InputDispatcher::publishMotionEvent(Connection& connection,
                                             DispatchEntry& dispatchEntry) const {
    // 坐标缩放(处理多屏幕、不同密度)
    if (globalScaleFactor != 1.0f) {
        for (uint32_t i = 0; i < pointerCount; i++) {
            scaledCoords[i].scale(globalScaleFactor, 1, 1);
        }
    }

    // HMAC 签名,防止应用伪造注入事件
    std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);

    // 通过 InputPublisher 发送(内部调用 InputChannel::sendMessage)
    return connection.inputPublisher.publishMotionEvent(
            dispatchEntry.seq,           // 序列号,finish 回执配对用
            dispatchEntry.resolvedAction,
            dispatchEntry.transform,     // 窗口坐标变换矩阵
            motionEntry.pointerCount,
            motionEntry.pointerProperties,
            scaledCoords);
}

五、第四层:InputTransport 跨进程传输

文件frameworks/native/libs/input/InputTransport.cpp

InputChannel 的创建与传递

应用调用 WindowManager.addView()
    → ViewRootImpl.setView()
    → mWindowSession.addToDisplayAsUser()    Binder 调用 WMS
    → WMS.addWindow()
    → InputChannel::openInputChannelPair(name)
        创建一对 Unix Domain Socket:
        serverChannel → 注册到 InputDispatcher
        clientChannel → 通过 Binder 传回应用进程
    → ViewRootImpl 用 clientChannel 创建 WindowInputEventReceiver

InputPublisher::publishMotionEvent()

status_t InputPublisher::publishMotionEvent(...) {
    // 打包成 InputMessage 二进制结构
    InputMessage msg;
    msg.header.type = InputMessage::Type::MOTION;
    msg.header.seq = seq;
    msg.body.motion.action = action;
    msg.body.motion.pointerCount = pointerCount;
    // 填充所有 pointer 的坐标、压力、尺寸等数据

    return mChannel->sendMessage(&msg);
}

InputChannel::sendMessage()

status_t InputChannel::sendMessage(const InputMessage* msg) {
    const size_t msgLength = msg->size();
    ssize_t nWrite;
    do {
        // MSG_DONTWAIT:非阻塞,缓冲区满时立即返回 EAGAIN
        // MSG_NOSIGNAL:写入关闭的 fd 不触发 SIGPIPE 信号
        nWrite = ::send(mFd.get(), msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
    } while (nWrite == -1 && errno == EINTR);

    if (errno == EAGAIN || errno == EWOULDBLOCK) {
        return WOULD_BLOCK;  // 缓冲区满,Dispatcher 暂停发送,等 finish 后继续
    }
    return OK;
}

六、第五层:应用进程接收

文件frameworks/base/core/java/android/view/ViewRootImpl.java

InputEventReceiver:Socket 可读回调

// 底层 JNI 把 client fd 注册到主线程 Looper 的 epoll
// Socket 有数据时在主线程回调:
private void dispatchInputEvent(int seq, InputEvent event) {
    mSeqMap.put(event.getSequenceNumber(), seq);
    onInputEvent(event);  // 子类 WindowInputEventReceiver 重写
}

// 处理完成后必须调用,通知 Dispatcher 继续发送
public final void finishInputEvent(InputEvent event, boolean handled) {
    nativeFinishInputEvent(mReceiverPtr, seq, handled);
    // JNI → InputConsumer::sendFinishedSignal()
    //      → InputChannel::sendMessage(FINISHED)
    //      → Dispatcher waitQueue 移除事件,ANR 计时取消
}

WindowInputEventReceiver

final class WindowInputEventReceiver extends InputEventReceiver {
    @Override
    public void onInputEvent(InputEvent event) {
        // 兼容性处理(旧版 API 适配)
        List<InputEvent> processedEvents =
                mInputCompatProcessor.processMotionEventForCompatibility(event);

        if (processedEvents != null) {
            for (InputEvent e : processedEvents) {
                enqueueInputEvent(e, this,
                        QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
            }
        } else {
            enqueueInputEvent(event, this, 0, true);
            //                              ↑ processImmediately=true 立即处理
        }
    }

    @Override
    public void onBatchedInputEventPending(int source) {
        // 批量 MOVE 事件积累,注册 Choreographer 回调
        // 下一帧 vsync 时统一处理,提升绘制效率
        if (!mUnbufferedInputDispatch) {
            scheduleConsumeBatchedInput();
        }
    }
}

enqueueInputEvent() + deliverInputEvent()

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++;

    if (processImmediately) {
        doProcessInputEvents();  // 立即处理
    } else {
        scheduleProcessInputEvents();  // 发 Message 到主线程
    }
}

void doProcessInputEvents() {
    while (mPendingInputEventHead != null) {
        QueuedInputEvent q = mPendingInputEventHead;
        mPendingInputEventHead = q.mNext;
        deliverInputEvent(q);
    }
}

private void deliverInputEvent(QueuedInputEvent q) {
    InputStage stage = q.shouldSkipIme()
            ? mFirstPostImeInputStage   // 跳过 IME
            : mFirstInputStage;         // 从责任链头部开始

    if (stage != null) {
        handleWindowFocusChanged();
        stage.deliver(q);  // 进入 InputStage 责任链
    } else {
        finishInputEvent(q);
    }
}

七、第六层:InputStage 责任链

责任链结构(ViewRootImpl.setView() 中构建)

mFirstInputStage:

① NativePreImeInputStage      native 层预处理
           ↓
② ViewPreImeInputStage         View 在 IME 前拦截按键
           ↓
③ ImeInputStage                发给输入法,IME 可消费
           ↓
④ EarlyPostImeInputStage       音量键/媒体键等全局快捷键
           ↓
⑤ ViewPostImeInputStage  ←── 触摸事件主路径(最重要)
           ↓
⑥ NativePostImeInputStage      native 后处理
           ↓
⑦ SyntheticInputStage          合成事件(轨迹球/无障碍注入)

InputStage 基类模板

abstract class InputStage {
    private final InputStage mNext;

    public final void deliver(QueuedInputEvent q) {
        if ((q.mFlags & FLAG_FINISHED) != 0) {
            forward(q);              // 已处理,跳过传递
        } else if (shouldDropInputEvent(q)) {
            finish(q, false);        // 丢弃(窗口不可见等)
        } else {
            apply(q, onProcess(q));  // 调用子类处理
        }
    }

    protected int onProcess(QueuedInputEvent q) {
        return FORWARD;  // 默认不处理,向下传
    }

    protected void finish(QueuedInputEvent q, boolean handled) {
        q.mFlags |= FLAG_FINISHED;
        forward(q);  // 标记完成后继续传递,让链路正常收尾
    }
}

ViewPostImeInputStage:进入 View 树

final class ViewPostImeInputStage extends InputStage {
    @Override
    protected int onProcess(QueuedInputEvent q) {
        if (q.mEvent instanceof KeyEvent) {
            return processKeyEvent(q);
        } else {
            final int source = q.mEvent.getSource();
            if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
                return processPointerEvent(q);  // 触摸/鼠标 ← 主路径
            } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
                return processTrackballEvent(q);
            } else {
                return processGenericMotionEvent(q);  // 游戏手柄等
            }
        }
    }

    private int processPointerEvent(QueuedInputEvent q) {
        final MotionEvent event = (MotionEvent) q.mEvent;
        mAttachInfo.mHandlingPointerEvent = true;

        boolean handled = mView.dispatchPointerEvent(event);
        // mView 就是 DecorView,进入 View 树

        maybeUpdatePointerIcon(event);   // 更新鼠标光标
        maybeUpdateTooltip(event);       // 更新悬浮提示
        mAttachInfo.mHandlingPointerEvent = false;

        return handled ? FINISH_HANDLED : FORWARD;
    }
}

八、第七层:DecorView → Activity → ViewGroup

文件DecorView.java / Activity.java / PhoneWindow.java

入口调用链

// DecorView.java
public boolean dispatchTouchEvent(MotionEvent ev) {
    final Window.Callback cb = mWindow.getCallback();
    // cb 就是 Activity(implements Window.Callback)
    return cb != null && !isDestroyed() && mFeatureId < 0
            ? cb.dispatchTouchEvent(ev)      // 先给 Activity
            : super.dispatchTouchEvent(ev);  // 直接走 ViewGroup
}

// Activity.java
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();  // 用户交互回调(可重写,如重置屏保)
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;   // View 树消费了
    }
    return onTouchEvent(ev);  // View 树没消费,Activity 最后兜底
}

// PhoneWindow.java
public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);  // 绕回 DecorView
}

// DecorView.java
public boolean superDispatchTouchEvent(MotionEvent event) {
    return super.dispatchTouchEvent(event);  // 调用 ViewGroup.dispatchTouchEvent()
}

九、第八层:ViewGroup.dispatchTouchEvent() 核心

文件frameworks/base/core/java/android/view/ViewGroup.java

public boolean dispatchTouchEvent(MotionEvent ev) {

    // ① 安全检查
    if (!onFilterTouchEventForSecurity(ev)) {
        return false;
        // 窗口被遮挡(FLAG_WINDOW_IS_OBSCURED)
        // 且开启了 filterTouchesWhenObscured → 拦截
    }

    // ② 是否拦截
    final boolean intercepted;
    if (actionMasked == ACTION_DOWN || mFirstTouchTarget != null) {
        final boolean disallowIntercept =
                (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
        // 子 View 通过 requestDisallowInterceptTouchEvent(true) 设置此标志
        if (!disallowIntercept) {
            intercepted = onInterceptTouchEvent(ev);  // 默认返回 false
        } else {
            intercepted = false;  // 子 View 禁止拦截
        }
    } else {
        // 无子 View 接手 + 非 DOWN → 直接拦截,自己处理
        intercepted = true;
    }

    // ③ ACTION_DOWN 时寻找处理者
    if (!canceled && !intercepted) {
        if (actionMasked == ACTION_DOWN || actionMasked == ACTION_POINTER_DOWN) {

            // 反序遍历子 View(后绘制的在顶层,优先接收触摸)
            final ArrayList<View> preorderedList = buildTouchDispatchChildList();
            for (int i = childrenCount - 1; i >= 0; i--) {
                final View child = getAndVerifyPreorderedView(preorderedList, i);

                // 子 View 必须可见 + 触摸点在其范围内
                if (!child.canReceivePointerEvents()
                        || !isTransformedTouchPointInView(x, y, child, null)) {
                    continue;
                }

                // 已有其他手指在此 View,加入同一 TouchTarget
                newTouchTarget = getTouchTarget(child);
                if (newTouchTarget != null) {
                    newTouchTarget.pointerIdBits |= idBitsToAssign;
                    break;
                }

                // 尝试分发 DOWN 给子 View
                if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
                    // 子 View 消费了 DOWN → 记录为 mFirstTouchTarget
                    newTouchTarget = addTouchTarget(child, idBitsToAssign);
                    alreadyDispatchedToNewTouchTarget = true;
                    break;
                }
                // 没消费 → 继续遍历下一个
            }
        }
    }

    // ④ 分发后续事件
    if (mFirstTouchTarget == null) {
        // 无子 View 接手,自己处理
        handled = dispatchTransformedTouchEvent(ev, canceled, null,
                TouchTarget.ALL_POINTER_IDS);
    } else {
        // MOVE/UP 直接发给 mFirstTouchTarget,不再遍历
        TouchTarget target = mFirstTouchTarget;
        while (target != null) {
            final boolean cancelChild = resetCancelNextUpFlag(target.child) || intercepted;
            // intercepted=true:父 View 中途拦截,给子 View 发 CANCEL

            if (dispatchTransformedTouchEvent(ev, cancelChild,
                    target.child, target.pointerIdBits)) {
                handled = true;
            }
            if (cancelChild) {
                // 发了 CANCEL,从链表移除
                mFirstTouchTarget = target.next;
                target.recycle();
            }
            target = target.next;
        }
    }

    // ⑤ UP/CANCEL 时清理
    if (canceled || actionMasked == ACTION_UP) {
        resetTouchState();  // 清空 mFirstTouchTarget 链表
    }

    return handled;
}

dispatchTransformedTouchEvent():坐标变换 + 递归

private boolean dispatchTransformedTouchEvent(MotionEvent event,
        boolean cancel, View child, int desiredPointerIdBits) {

    if (cancel || oldAction == ACTION_CANCEL) {
        event.setAction(ACTION_CANCEL);
        if (child == null) return super.dispatchTouchEvent(event);
        return child.dispatchTouchEvent(event);  // 发 CANCEL
    }

    if (child == null) {
        // 自己处理(ViewGroup 作为 View)
        return super.dispatchTouchEvent(event);
    }

    // 坐标系转换到子 View 局部坐标
    final float offsetX = mScrollX - child.mLeft;
    final float offsetY = mScrollY - child.mTop;
    event.offsetLocation(offsetX, offsetY);

    boolean handled = child.dispatchTouchEvent(event);  // 递归分发
    // child 可能是 ViewGroup → 继续递归
    // child 是 View → 进入 View.dispatchTouchEvent()

    event.offsetLocation(-offsetX, -offsetY);  // 还原坐标
    return handled;
}

十、第九层:View.dispatchTouchEvent() + onTouchEvent()

文件frameworks/base/core/java/android/view/View.java

public boolean dispatchTouchEvent(MotionEvent event) {
    boolean result = false;

    if (onFilterTouchEventForSecurity(event)) {
        // 优先级① OnTouchListener(setOnTouchListener 注册)
        if ((mViewFlags & ENABLED_MASK) == ENABLED
                && mListenerInfo != null
                && mListenerInfo.mOnTouchListener != null
                && mListenerInfo.mOnTouchListener.onTouch(this, event)) {
            result = true;
            // 返回 true → onTouchEvent 不再调用
        }

        // 优先级② onTouchEvent
        if (!result && onTouchEvent(event)) {
            result = true;
        }
    }
    return result;
}

onTouchEvent():点击与长按的产生

public boolean onTouchEvent(MotionEvent event) {
    if (!isClickable() && !isLongClickable()) return false;

    // DISABLED 的 View 也消费事件(但不响应)
    if ((viewFlags & ENABLED_MASK) == DISABLED) return clickable;

    // TouchDelegate:扩大点击热区
    if (mTouchDelegate != null && mTouchDelegate.onTouchEvent(event)) {
        return true;
    }

    switch (action) {
        case ACTION_DOWN:
            boolean isInScrollingContainer = isInScrollingContainer();
            if (isInScrollingContainer) {
                // 滚动容器内:延迟 100ms 确认(避免滚动误触)
                mPrivateFlags |= PFLAG_PREPRESSED;
                postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
            } else {
                // 立即 PRESSED 状态(触发波纹视觉反馈)
                setPressed(true, x, y);
                // 开启长按计时器(默认 400ms)
                checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y, ...);
            }
            break;

        case ACTION_MOVE:
            drawableHotspotChanged(x, y);  // 波纹中心跟手指
            if (!pointInView(x, y, touchSlop)) {
                // 滑出 touchSlop 范围(默认 8dp)
                removeTapCallback();       // 取消 TAP
                removeLongPressCallback(); // 取消长按
                setPressed(false);         // 取消按下状态
            }
            break;

        case ACTION_UP:
            if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
                if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
                    removeLongPressCallback();
                    // post 到主线程下一帧执行(让波纹先显示)
                    if (!post(mPerformClick)) {
                        performClickInternal();  // post 失败则同步执行
                    }
                }
                setPressed(false);
            }
            break;

        case ACTION_CANCEL:
            setPressed(false);
            removeTapCallback();
            removeLongPressCallback();
            break;
    }
    return true;
}

// performClick() 触发 onClick
public boolean performClick() {
    final ListenerInfo li = mListenerInfo;
    if (li != null && li.mOnClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
        li.mOnClickListener.onClick(this);  // ← onClick 最终在这里调用!
        return true;
    }
    return false;
}

// 长按检测 Runnable
private final class CheckForLongPress implements Runnable {
    public void run() {
        if (isPressed() && mParent != null) {
            if (performLongClick(mX, mY)) {
                mHasPerformedLongPress = true;
                // 标记已长按,ACTION_UP 时不再触发 onClick
            }
        }
    }
}

十一、finish 回执:ANR 计时取消

// ViewRootImpl.java
void finishInputEvent(QueuedInputEvent q) {
    boolean handled = (q.mFlags & FLAG_FINISHED_HANDLED) != 0;
    q.mReceiver.finishInputEvent(q.mEvent, handled);
}

// InputEventReceiver.java
public final void finishInputEvent(InputEvent event, boolean handled) {
    nativeFinishInputEvent(mReceiverPtr, seq, handled);
}

// JNI → InputConsumer::sendFinishedSignal(seq, handled)
//      → InputChannel::sendMessage({FINISHED, seq, handled})
//      → send(client fd, msg)

// Dispatcher 侧收到 FINISHED:
//   handleReceiveCallback()
//     → 从 waitQueue 移除对应 seq 的事件
//     → ANR 计时取消(dispatchEntry->timeoutTime 失效)
//     → startDispatchCycleLocked() 继续发下一个事件

十二、完整链路总图

触摸屏硬件中断
        ↓
内核 input 子系统 → /dev/input/eventX
        ↓
EventHub::getEvents()
    epoll_wait 阻塞监听 → 有事件唤醒
    read(device->fd) → input_event[]
    转换成 RawEvent(加 deviceId/readTime)
        ↓
InputReader::loopOnce()
    processEventsLocked()
        同一设备事件打包批量处理
        → TouchInputMapper
            多点协议解析、坐标归一化、屏幕方向校正
            → 生成 NotifyMotionArgs
    mNextListener.notify(args)(锁外)
        ↓
InputListenerInterface::notify()
    std::visit 识别类型 → notifyMotion()
        ↓
InputDispatcher::notifyMotion()
    validateMotionEvent() 合法性校验
    interceptMotionBeforeQueueing() Policy 拦截
    filterInputEvent() InputFilter 过滤
    构造 MotionEntry → enqueueInboundEventLocked()
        mInboundQueue.push_back()
        MOVE 堆积时跳帧优化
    mLooper->wake() 唤醒 Dispatcher 线程
        ↓
InputDispatcher 线程从 pollOnce() 醒来
    dispatchOnceInnerLocked()
        mInboundQueue.pop_front()
        过期/AppSwitch 丢弃判断
        dispatchMotionLocked()
            isPointerEvent ?
            → findTouchedWindowTargetsLocked()  遍历窗口Z序找命中窗口
            → findFocusedWindowTargetLocked()   键盘找焦点窗口
            addGlobalMonitoringTargetsLocked()  加入无障碍等全局监听
            dispatchEventLocked(inputTargets)
                processInteractionsLocked()  焦点转移处理
                pokeUserActivityLocked()     通知 PowerManager
                for each inputTarget:
                    prepareDispatchCycleLocked()
                        splitMotionEvent()  多指分割
                        enqueueDispatchEntriesLocked()
                            startDispatchCycleLocked()
                                timeoutTime = now + 5s  ← ANR 计时开始
                                publishMotionEvent()
                                    坐标缩放 + HMAC 签名
                                    inputPublisher.publishMotionEvent()
                                        InputMessage 序列化
                                        InputChannel::sendMessage()
                                            send(server fd, msg)
                                outboundQueue → waitQueue
        ↓  Unix Domain Socket
应用进程 client fd epoll 可读(主线程)
    InputEventReceiver::dispatchInputEvent()  JNI 回调
    WindowInputEventReceiver::onInputEvent()
    ViewRootImpl::enqueueInputEvent()
        构造 QueuedInputEvent 链表
        doProcessInputEvents()
        deliverInputEvent()
        ↓ InputStage 责任链
    NativePreImeInputStage → ViewPreImeInputStage → ImeInputStage
    → EarlyPostImeInputStage → ViewPostImeInputStage
        processPointerEvent()
        mView.dispatchPointerEvent()  mView = DecorView
        ↓
    DecorView.dispatchTouchEvent()
        cb.dispatchTouchEvent()  cb = Activity
        ↓
    Activity.dispatchTouchEvent()
        onUserInteraction()
        getWindow().superDispatchTouchEvent()
        ↓
    PhoneWindow → DecorView.superDispatchTouchEvent()
        ↓
    ViewGroup.dispatchTouchEvent()
        onFilterTouchEventForSecurity()   安全检查
        onInterceptTouchEvent()           父 View 拦截判断
        ACTION_DOWN: 反序遍历子 View
            isTransformedTouchPointInView()  坐标命中
            dispatchTransformedTouchEvent()
                event.offsetLocation()  坐标系转换
                child.dispatchTouchEvent()  递归
        ACTION_MOVE/UP: 直接发 mFirstTouchTarget
        intercepted=true: 发 CANCEL 给子 View
        ↓
    View.dispatchTouchEvent()
        OnTouchListener.onTouch()    优先级①
        onTouchEvent()               优先级②
            DOWN → setPressed(波纹) + 长按计时(400ms)
            MOVE → 检查 touchSlop(8dp),超出取消长按
            UP   → performClick() → onClick()
            CANCEL → 清理所有状态
        ↓
    finishInputEvent()
        InputEventReceiver.finishInputEvent()
        JNI → InputConsumer::sendFinishedSignal()
        InputChannel::sendMessage(FINISHED)
        Dispatcher::handleReceiveCallback()
            waitQueue 移除事件
            ANR 计时取消
            startDispatchCycleLocked() 继续下一个

十三、关键机制总结

ANR 触发机制

startDispatchCycleLocked() 设置:
    dispatchEntry->timeoutTime = currentTime + 5秒

事件进入 waitQueue 等待 finish 回执
processAnrsLocked() 每次循环检查:
    now >= dispatchEntry->timeoutTime → 触发 ANR
    → onAnrLocked() → 弹出 ANR 对话框 / 结束进程

mFirstTouchTarget 决定事件归属

ACTION_DOWN:遍历子 View,找到第一个消费的记为 mFirstTouchTarget
ACTION_MOVE/UP:直接发给 mFirstTouchTarget,不重新遍历

→ 子 View 的 onTouchEvent(DOWN) 返回 false
  → mFirstTouchTarget = null
  → 后续 MOVE/UP 全由父 ViewGroup 的 onTouchEvent 处理

事件优先级

高 ─────────────────────────────────────── 低

TouchDelegate > OnTouchListener > onTouchEvent > onClick/onLongClick
(扩大热区)    (set方法注册)    (重写方法)    (最终回调)

防死锁设计

InputReader:
  getEvents()    无锁(阻塞等待期间允许其他线程访问)
  notify()       无锁(Dispatcher 回调可能反查 InputReader)

InputDispatcher:
  Policy 拦截    锁外(可能做耗时 Binder 调用)
  入队操作       锁内(修改队列必须加锁)
  发送事件       锁外(Dispatcher 回调可能反查自身)

十四、关键常量速查

常量 说明
Input ANR 超时 5 秒 startDispatchCycleLocked 设置
前台 Service ANR 20 秒 ActiveServices
前台 Broadcast ANR 10 秒 BroadcastQueue
longPressTimeout 400ms 长按触发时间(Android 9+)
tapTimeout 100ms 滚动容器内确认点击延迟
touchSlop 8dp 超出此范围视为滑动而非点击
Binder 线程数 最多 16 1主线程 + 15个 Binder 线程

十五、关键源码文件索引

文件 路径 作用
EventHub.cpp inputflinger/reader/EventHub.cpp epoll 读取硬件事件
InputReader.cpp inputflinger/reader/InputReader.cpp 事件加工主循环
TouchInputMapper.cpp inputflinger/reader/mapper/ 触摸协议解析、坐标变换
InputListener.cpp inputflinger/InputListener.cpp notify() 类型分发
InputDispatcher.cpp inputflinger/dispatcher/InputDispatcher.cpp 路由、ANR、发送
InputTransport.cpp libs/input/InputTransport.cpp Socket 收发、序列化
InputChannel.cpp libs/input/InputChannel.cpp Unix Socket 封装
InputEventReceiver.java core/java/android/view/InputEventReceiver.java 应用侧接收入口
ViewRootImpl.java core/java/android/view/ViewRootImpl.java 入队、InputStage 责任链
DecorView.java core/java/com/android/internal/policy/DecorView.java 窗口根 View
Activity.java core/java/android/app/Activity.java dispatchTouchEvent 兜底
ViewGroup.java core/java/android/view/ViewGroup.java 核心分发、拦截、寻找目标
View.java core/java/android/view/View.java onClick/onLongClick 产生
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐