[Android 13]Input系列--InputDispatcher事件分发

hongxi.zhu 2023-7-20
Android 13

InputDispatcher::dispatchOnce()

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

void InputDispatcher::dispatchOnce() {
    
    
    nsecs_t nextWakeupTime = LONG_LONG_MAX;
    {
    
     // acquire lock
        std::scoped_lock _l(mLock);
        mDispatcherIsAlive.notify_all();  //唤醒在这个condition上wait的所有地方

        // Run a dispatch loop if there are no pending commands.
        // The dispatch loop might enqueue commands to run afterwards.
        // 如果当前没有待办的command需要处理(command一般是需要处理一些异常情况,比如ANR)
        // 就进行事件的分发
        if (!haveCommandsLocked()) {
    
    
            dispatchOnceInnerLocked(&nextWakeupTime);  //事件分发
        }

        // Run all pending commands if there are any.
        // If any commands were run then force the next poll to wake up immediately.
        // 如果mCommandQueue不为空,就执行完所有command,并将下次唤醒时间设置为最小值,强制下一次poll唤醒线程
        if (runCommandsLockedInterruptable()) {
    
    
            nextWakeupTime = LONG_LONG_MIN;
        }

        // If we are still waiting for ack on some events,
        // we might have to wake up earlier to check if an app is anr'ing.
        // 如果此时正在等待分发出去的事件的ack(目标应用的响应),我们需要早点唤醒去检查这个应用是否正在ANR
        const nsecs_t nextAnrCheck = processAnrsLocked();
        nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);

        // We are about to enter an infinitely long sleep, because we have no commands or
        // pending or queued events
        // 如果唤醒时间还是LONG_LONG_MAX没有被修改
        // 说明上面没有待处理的事件也没有待处理的command,那么将进入无限期的休眠中
        if (nextWakeupTime == LONG_LONG_MAX) {
    
    
            mDispatcherEnteredIdle.notify_all();  //唤醒等待进入idle状态的condition
        }
    } // release lock

    // Wait for callback or timeout or wake.  (make sure we round up, not down)
    nsecs_t currentTime = now();
    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
    mLooper->pollOnce(timeoutMillis);  //进入阻塞等待唤醒或者timeout或者callback回调
}

InputDispatcher::dispatchOnceInnerLocked

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    
    
    nsecs_t currentTime = now();

    // Reset the key repeat timer whenever normal dispatch is suspended while the
    // device is in a non-interactive state.  This is to ensure that we abort a key
    // repeat if the device is just coming out of sleep.
    // 如果设备处于不可交互时,则不进行事件的分发
    // 如果处于不可分发状态则重置按键重复计时器
    if (!mDispatchEnabled) {
    
    
        resetKeyRepeatLocked();
    }

    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
    // 如果处于frozen状态,则不处理任何有关目标进程是否有简单窗口的timeout行为,也不会进行事件的分发
    if (mDispatchFrozen) {
    
    
        if (DEBUG_FOCUS) {
    
    
            ALOGD("Dispatch frozen.  Waiting some more.");
        }
        return;
    }

    // Optimize latency of app switches.
    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
    // 对APP切换时的优化措施,当按下类似HOME键时,启动一个超时机制(0.5s),当timeout时,会立即分发事件并抛弃其他的未处理事件
    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
    if (mAppSwitchDueTime < *nextWakeupTime) {
    
    
        *nextWakeupTime = mAppSwitchDueTime;
    }

    // Ready to start a new event.
    // If we don't already have a pending event, go grab one.
    if (!mPendingEvent) {
    
      //正常一次分发前mPendingEvent = nullptr
        if (mInboundQueue.empty()) {
    
    
			...
        } else {
    
      //因为inputReader已经往Inbound queue中添加了事件,所以不为空
            // Inbound queue has at least one entry.
            mPendingEvent = mInboundQueue.front(); //拿出一个待分发的事件
            mInboundQueue.pop_front(); //从mInboundQueue中移除这个事件
            traceInboundQueueLengthLocked();  //systrace、perfetto中可以看到这个队列size发生变化
        }

        // Poke user activity for this event.
        // 每次分发事件时都调PMS的updatePowerStateLocked更新电源的状态
        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
    
    
            pokeUserActivityLocked(*mPendingEvent);
        }
    }

    // Now we have an event to dispatch.
    // All events are eventually dequeued and processed this way, even if we intend to drop them.
    ALOG_ASSERT(mPendingEvent != nullptr);
    bool done = false;
    DropReason dropReason = DropReason::NOT_DROPPED;
    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
    
      //如果事件不是分发给用户的则抛弃drop
        dropReason = DropReason::POLICY;
    } else if (!mDispatchEnabled) {
    
      //如果当前属于不可交互的状态则drop
        dropReason = DropReason::DISABLED;
    }

    if (mNextUnblockedEvent == mPendingEvent) {
    
    
        mNextUnblockedEvent = nullptr;
    }

    switch (mPendingEvent->type) {
    
    
		...
        case EventEntry::Type::KEY: {
    
    
			...
        }

        case EventEntry::Type::MOTION: {
    
    
            std::shared_ptr<MotionEntry> motionEntry =
                    std::static_pointer_cast<MotionEntry>(mPendingEvent);
            if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
    
    
                dropReason = DropReason::APP_SWITCH;  //处于APP切换情形drop的事件
            }
            if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
    
    
           	    //事件超过了一个事件允许分发的最大时间(10s)(事件太老)则drop这个事件
           	    //时间计算:currentTime - entry.eventTime
                dropReason = DropReason::STALE;
            }
            if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
    
    
            	//当焦点将要移到到新的应用上,则抛弃期间的事件
                dropReason = DropReason::BLOCKED;
            }
            //事件的分发(无论这个事件要分发还是要drop都要走这里)
            done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
            break;
        }
		...
    }

    if (done) {
    
    
        if (dropReason != DropReason::NOT_DROPPED) {
    
    
            dropInboundEventLocked(*mPendingEvent, dropReason);
        }
        mLastDropReason = dropReason;

        releasePendingEventLocked();  //将mPendingEvent设置为nullptr,重置为下一个事件分发准备
        //  强制下一个poll中立即唤醒inputDispatcher线程来干活
        *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
    }
}

InputDispatcher::dispatchMotionLocked

bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
                                           DropReason* dropReason, nsecs_t* nextWakeupTime) {
    
    
    ATRACE_CALL();
    // Preprocessing.
    //将当前事件的dispatchInProgress设置为true表示处理中
    if (!entry->dispatchInProgress) {
    
    
        entry->dispatchInProgress = true;

        logOutboundMotionDetails("dispatchMotion - ", *entry);
    }

    // Clean up if dropping the event.
    //如果事件需要抛弃
    if (*dropReason != DropReason::NOT_DROPPED) {
    
    
        setInjectionResult(*entry,
                           *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
                                                             : InputEventInjectionResult::FAILED);
        return true;
    }
	//从entry->source判断事件的源类型
    const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);

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

    bool conflictingPointerActions = false;
    InputEventInjectionResult injectionResult;
    if (isPointerEvent) {
    
      //触屏这这里
        // Pointer event.  (eg. touchscreen)
        //重要的方法,获取当前焦点窗口,后续单独展开分析这个,这里就展开
        //获取到的焦点窗口为inputTargets
        injectionResult =
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                                               &conflictingPointerActions);
    } else {
    
    
		...
    }
	...

    setInjectionResult(*entry, injectionResult);
	...

    // Add monitor channels from event's or focused display.
    //将全局的监视器窗口加入分发的目标窗口列表中(举个例子:开发者选项中的显示触摸轨迹图层就一个全局监视器)
    //只要事件在前面没有被抛弃,那么无论后面的流程是否拦截事件,这些全局监视器都能收到事件
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));

    // Dispatch the motion.
	...
    dispatchEventLocked(currentTime, entry, inputTargets);  //往目标窗口分发事件
    return true;  //return true就可以进行下一次从iq中读取新事件并分发
}

InputDispatcher::dispatchEventLocked

void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
                                          std::shared_ptr<EventEntry> eventEntry,
                                          const std::vector<InputTarget>& inputTargets) {
    
    
    ATRACE_CALL();

    updateInteractionTokensLocked(*eventEntry, inputTargets);

    ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true

    pokeUserActivityLocked(*eventEntry);  //再次更新电源状态,避免进入息屏等行为

	//遍历所有找到的目标窗口inputTargets,通过他们的向他们inputChannel分发当前的事件
    for (const InputTarget& inputTarget : inputTargets) {
    
    
        sp<Connection> connection =
                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
        if (connection != nullptr) {
    
    
            prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
        } else {
    
    
            if (DEBUG_FOCUS) {
    
    
                ALOGD("Dropping event delivery to target with channel '%s' because it "
                      "is no longer registered with the input dispatcher.",
                      inputTarget.inputChannel->getName().c_str());
            }
        }
    }
}

InputDispatcher::prepareDispatchCycleLocked

void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
                                                 const sp<Connection>& connection,
                                                 std::shared_ptr<EventEntry> eventEntry,
                                                 const InputTarget& inputTarget) {
    
    
	...
    // Skip this event if the connection status is not normal.
    // We don't want to enqueue additional outbound events if the connection is broken.
	// 如果目标窗口的连接状态不正常,比如进程已经死了,那么就不向它分发了
    if (connection->status != Connection::Status::NORMAL) {
    
    
        return;
    }

    // Split a motion event if needed.
    // 如果当前系统处于分屏的状态,就需要考虑分离触摸的情形,检查目标窗口是否设置分离触摸标志
    if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
    
    
        const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
        if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
    
    
            std::unique_ptr<MotionEntry> splitMotionEntry =
                    splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
            if (!splitMotionEntry) {
    
    
                return; // split event was dropped
            }
            if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
    
    
                std::string reason = std::string("reason=pointer cancel on split window");
                android_log_event_list(LOGTAG_INPUT_CANCEL)
                        << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
            }

            enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
                                         inputTarget);
            return;
        }
    }

    // Not splitting.  Enqueue dispatch entries for the event as is.
    //一般走这里,继续事件的分发,将事件加入目标窗口的即将分发的队列中
    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
}

InputDispatcher::enqueueDispatchEntriesLocked

void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
                                                   const sp<Connection>& connection,
                                                   std::shared_ptr<EventEntry> eventEntry,
                                                   const InputTarget& inputTarget) {
    
    

    bool wasEmpty = connection->outboundQueue.empty();

    // Enqueue dispatch entries for the requested modes.
    // 将事件加入分发队列outboundQueue,这里有些复杂
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);  //2048
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_OUTSIDE);  //512
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);  //1024
    //FLAG_DISPATCH_AS_IS表示事件按原样分发,不改变事件的分发模式,一般都是走这里,其他的是特殊情形
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_IS);  //256  
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);  //4096
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);  //8192

    // If the outbound queue was previously empty, start the dispatch cycle going.
    if (wasEmpty && !connection->outboundQueue.empty()) {
    
    
        startDispatchCycleLocked(currentTime, connection);  //outboundQueue中已经有事件,可以分发
    }
}

InputDispatcher::enqueueDispatchEntryLocked

void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
                                                 std::shared_ptr<EventEntry> eventEntry,
                                                 const InputTarget& inputTarget,
                                                 int32_t dispatchMode) {
    
    
                                                 
    int32_t inputTargetFlags = inputTarget.flags;
	//这里很关键,enqueueDispatchEntryLocked从上面来看,貌似会调五次,但是
	// 这里有限制条件,根据inputTargetFlags是否等于本次传入的dispatchMode,不同则return
	// 所以是否入队还是由inputTargetFlags决定,正常事件都是inputTargetFlags = FLAG_DISPATCH_AS_IS
	// 所以一般只有dispatchMode = FLAG_DISPATCH_AS_IS时才会往下执行
    if (!(inputTargetFlags & dispatchMode)) {
    
    
        return;
    }
    inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;

    // This is a new event.
    // Enqueue a new dispatch entry onto the outbound queue for this connection.
    // 创建DispatchEntry,DispatchEntry是对EventEntry的包装,加入分发的一些跟踪状态属性值
    // 关联eventEntry,inputTarget,inputTarget,
    std::unique_ptr<DispatchEntry> dispatchEntry =
            createDispatchEntry(inputTarget, eventEntry, inputTarget);

    // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
    // different EventEntry than what was passed in.
    EventEntry& newEntry = *(dispatchEntry->eventEntry);
    // Apply target flags and update the connection's input state.
    switch (newEntry.type) {
    
    
        case EventEntry::Type::KEY: {
    
    
			...
            break;
        }

        case EventEntry::Type::MOTION: {
    
    
            const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
            // Assign a default value to dispatchEntry that will never be generated by InputReader,
            // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
            constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
                    static_cast<int32_t>(IdGenerator::Source::OTHER);
            dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
            
            if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
    
    
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
    
    
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
    
    
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
    
    
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
    
    
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
            } else {
    
      //由上面可知dispatchMode = FLAG_DISPATCH_AS_IS所以走else,保留事件原本的action和id
                dispatchEntry->resolvedAction = motionEntry.action;
                dispatchEntry->resolvedEventId = motionEntry.id;
            }
            
            if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
				...
            }

            dispatchEntry->resolvedFlags = motionEntry.flags;
            //判断当前目标窗口是否被其他可见窗口遮挡的情况并设置到dispatchEntry->resolvedFlags, 全遮挡还是部分遮挡
            if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
    
    
                dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
            }
            if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
    
    
                dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
            }
			...
			// 从上面可知,当dispatchMode = FLAG_DISPATCH_AS_IS时
			// 事件的resolvedEventId仍然保留原有motionEntry.id
            dispatchEntry->resolvedEventId =
                    dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
                    ? mIdGenerator.nextId()
                    : motionEntry.id;

            if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
                (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
    
    
                // Skip reporting pointer down outside focus to the policy.
                break;
            }
			//处理分发事件目标窗口不是当前焦点窗口的情况
            dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
                                            inputTarget.inputChannel->getConnectionToken());

            break;
        }
		...
    }

    // Remember that we are waiting for this dispatch to complete.
    if (dispatchEntry->hasForegroundTarget()) {
    
    
        incrementPendingForegroundDispatches(newEntry);
    }

    // Enqueue the dispatch entry.
    // 将dispatchEntry加入当前目标窗口的outboundQueue
    connection->outboundQueue.push_back(dispatchEntry.release());
    traceOutboundQueueLength(*connection);  //systrace可以看到outboundQueue的size发生改变
}

InputDispatcher::startDispatchCycleLocked

void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                               const sp<Connection>& connection) {
    
    

	//循环从outboundQueue中取出事件通过目标窗口的inputchannel向目标窗口分发
    while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
    
    
        DispatchEntry* dispatchEntry = connection->outboundQueue.front();  //取出DispatchEntry
        dispatchEntry->deliveryTime = currentTime;  //记录分发事件
        const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
         //事件处理的超时时间点 = currentTime + 5s  超时会引发ANR
        dispatchEntry->timeoutTime = currentTime + timeout.count();

        // Publish the event.
        status_t status;
        const EventEntry& eventEntry = *(dispatchEntry->eventEntry);  //获取EventEntry
        switch (eventEntry.type) {
    
    
            case EventEntry::Type::KEY: {
    
    
				...
            }

            case EventEntry::Type::MOTION: {
    
    
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);  //转化为触摸对应MotionEntry

                PointerCoords scaledCoords[MAX_POINTERS];
                const PointerCoords* usingCoords = motionEntry.pointerCoords;

                // Set the X and Y offset and X and Y scale depending on the input source.
                //根据输入源设置 X 和 Y 偏移以及 X 和 Y 比例。
                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];
                            // Don't apply window scale here since we don't want scale to affect raw
                            // coordinates. The scale will be sent back to the client and applied
                            // later when requesting relative coordinates.
                            //如果当前窗口的全局坐标比例不是1.0f,那么这里先把每个pointer的比例设置为1.0f
                            scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
                                                  1 /* windowYScale */);
                        }
                        usingCoords = scaledCoords;
                    }
                } else {
    
    
					...
                }

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

                // Publish the motion event.
                // 向目标窗口分发触摸事件
                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->rawTransform,
                                                     motionEntry.downTime, motionEntry.eventTime,
                                                     motionEntry.pointerCount,
                                                     motionEntry.pointerProperties, usingCoords);
                break;
            }
			...
        }

        // Check the result.
        // 检测分发的结果,正常时status = 0
        if (status) {
    
    
            if (status == WOULD_BLOCK) {
    
    
                if (connection->waitQueue.empty()) {
    
    
                	// 当前waitQueue是空的,说明socket中也应该是空的,但是却是WOULD_BLOCK,说明这时一个异常的情况,中断分发
                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
                } else {
    
    
                    // Pipe is full and we are waiting for the app to finish process some events
                    // before sending more events to it.
                    // socket满了,等待应用进程处理掉一些事件
                }
            } else {
    
    
            	//其他异常的情况
                abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
            }
            return;
        }

        // Re-enqueue the event on the wait queue.
        // 将已经分发的事件dispatchEntry从outboundQueue中移除
        connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
                                                    connection->outboundQueue.end(),
                                                    dispatchEntry));
        traceOutboundQueueLength(*connection); //systrace中跟踪outboundQueue的长度
        
        // 将已经分发的事件dispatchEntry加入目标窗口waitQueue中,记录下已经分发到目标窗口侧的事件,便于监控ANR等行为
        connection->waitQueue.push_back(dispatchEntry);

	  //如果目标窗口进程(例如应用进程)可响应,则将这个事件超时事件点和目标窗口连接对象token加入mAnrTracker中监控
	  //如果不可响应,则不再向它分发更多的事件,直到它消耗了已经分发给它的事件
        if (connection->responsive) {
    
    
            mAnrTracker.insert(dispatchEntry->timeoutTime,
                               connection->inputChannel->getConnectionToken());
        }
        traceWaitQueueLength(*connection); //systrace中跟踪waitQueue的长度
    }
}

InputPublisher::publishMotionEvent

frameworks/native/libs/input/InputTransport.cpp

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,
        const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
        uint32_t pointerCount, const PointerProperties* pointerProperties,
        const PointerCoords* pointerCoords) {
    
    

	//创建InputMessage,将dispatchEntry转化为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.dsdxRaw = rawTransform.dsdx();
    msg.body.motion.dtdxRaw = rawTransform.dtdx();
    msg.body.motion.dtdyRaw = rawTransform.dtdy();
    msg.body.motion.dsdyRaw = rawTransform.dsdy();
    msg.body.motion.txRaw = rawTransform.tx();
    msg.body.motion.tyRaw = rawTransform.ty();
    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]);
    }

    return mChannel->sendMessage(&msg);  //通过socketpair传递到目标窗口所在的进程中
}

到这里InputDispatcher的分发就分析完了。

猜你喜欢

转载自blog.csdn.net/qq_40731414/article/details/131827584