派发循环是指 InputDispatcher 不断地派发队列取出事件,寻找合适的窗口并进行发送的过程,是 InputDispatcher 线程的主要工作
事件发送循环是 InputDispatcher 通过 Connection 对象将事件发送给窗口,并接受其反馈的过程
InputDispatcher —> dispatchEventLocked:dispatchEventLocked 根据 InputTarget 中的 InputChannel 找到对应的Connection
@frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
//1. InputReader将事件注入派发队列
InputDispatcher::notifyMotion
mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
needWake = enqueueInboundEventLocked(std::move(newEntry));
mInboundQueue.push_back(std::move(newEntry));
//2.派发线程的线程循环
InputDispatcher::dispatchOnce
//3. 为事件寻找合适的窗口,窗口分为普通窗口和监听窗口,普通通过按点和焦点查找,监听窗口则无条件监听所有输入事件
dispatchOnceInnerLocked(&nextWakeupTime);
mPendingEvent = mInboundQueue.front();
case EventEntry::Type::FOCUS:
dispatchFocusLocked(currentTime, typedEntry);
//dispatchFocusLocked: message=Focus entering 76ac74c com/com.MainActivity (server), reason=reason=Window became focusable. Previous reason: NOT_FOCUSABLE
//dispatchFocusLocked: message=Focus leaving f81ce53 org.mozilla.firefox/org.mozilla.fenix.HomeActivity (server), reason=reason=NOT_FOCUSABLE
//dispatchFocusLocked: message=Focus leaving 76ac74c com/com.MainActivity (server), reason=reason=NOT_FOCUSABLE
//dispatchFocusLocked: message=Focus entering f81ce53 org.mozilla.firefox/org.mozilla.fenix.HomeActivity (server), reason=reason=Window became focusable. Previous reason: NOT_FOCUSABLE
std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
auto connectionIt = mConnectionsByToken.find(token);
return connectionIt->second->inputChannel;
InputTarget target;
target.inputChannel = channel;
dispatchEventLocked(currentTime, entry, {target});
case EventEntry::Type::MOTION:
done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
//寻找事件接受窗口的inputTargets
std::vector<InputTarget> inputTargets;
if (isPointerEvent) { injectionResult = findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime, &conflictingPointerActions); }
else { injectionResult = findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime); }
dispatchEventLocked(currentTime, entry, inputTargets);
for (const InputTarget& inputTarget : inputTargets) {
sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
//输入事件被 InputPublisher 以 InputMessage 的形式写入 InputChannel,然后将事件转存到 waitQueue 中等待窗口的反馈
startDispatchCycleLocked(currentTime, connection);
case EventEntry::Type::FOCUS: {
status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq, focusEntry.id, focusEntry.hasFocus, mInTouchMode);
case EventEntry::Type::MOTION: {
status = connection->inputPublisher.publishMotionEvent(motionEntry.deviceId, motionEntry.source, motionEntry.displayId,
@frameworks/native/libs/input/InputTransport.cpp
mChannel->sendMessage(&msg);
nWrite = ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); //向socket写入输入事件