派發循環是指 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);//尋找事件接受窗口的inputTargetsstd::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.cppmChannel->sendMessage(&msg);nWrite = ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); //向socket寫入輸入事件