Android13-Input事件派發(fā)(單指move)

1 InputDispatcher代碼解析第一部分

void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
    //條件編譯指令
#if DEBUG_INBOUND_EVENT_DETAILS
    if (args->action != AMOTION_EVENT_ACTION_MOVE) {
        //當(dāng)前動作不是AMOTION_EVENT_ACTION_MOVE
        ALOGD("Cnt:%d notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
            "displayId=%" PRId32 ", policyFlags=0x%x, "
            "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
            "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
            "yCursorPosition=%f, downTime=%" PRId64,
            (((args->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) ||
             ((args->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN))
                ? (mMotionCntByDisplay[args->displayId] == INT_MAX
                    ? INT_MAX : (mMotionCntByDisplay[args->displayId]++))
                : -1,
            args->id, args->eventTime, args->deviceId, args->source, args->displayId,
            args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
            args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
            args->xCursorPosition, args->yCursorPosition, args->downTime);
        for (uint32_t i = 0; i < args->pointerCount; i++) {
            //遍歷多指,每個(gè)觸控點(diǎn)的數(shù)據(jù)
            ALOGD("  Pointer %d: id=%d, toolType=%d, "
                "x=%f, y=%f, pressure=%f, size=%f, "
                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
                "orientation=%f",
                i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
        }
    }
#endif
    //驗(yàn)證是否是有效motion事件
    if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
                             args->pointerProperties)) {
        return;
    }

    uint32_t policyFlags = args->policyFlags;
    //定義InputReader上來的事件是值得信任的
    policyFlags |= POLICY_FLAG_TRUSTED;

    android::base::Timer t;
    //事件入隊(duì)前通過策略是java端(InputManagerService)進(jìn)行攔截
    mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
    if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
        ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
              std::to_string(t.duration().count()).c_str());
    }

    bool needWake;
    { // acquire lock
        mLock.lock();
        //判斷事件是否需要過濾 可以通過setInputFilterEnabled設(shè)置
        if (shouldSendMotionToInputFilterLocked(args)) {
            mLock.unlock();

            MotionEvent event;
            event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
                             args->action, args->actionButton, args->flags, args->edgeFlags,
                             args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
                             1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
                             args->yPrecision, args->xCursorPosition, args->yCursorPosition,
                             args->downTime, args->eventTime, args->pointerCount,
                             args->pointerProperties, args->pointerCoords);
          //添加過濾flag
            policyFlags |= POLICY_FLAG_FILTERED;
            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
                //policy消費(fèi)了當(dāng)次事件
                return; // event was consumed by the filter
            }

            mLock.lock();
        }

        // Just enqueue a new motion event.
        //構(gòu)建觸摸事件
        MotionEntry* newEntry =
                new MotionEntry(args->id, args->eventTime, args->deviceId, args->source,
                                args->displayId, policyFlags, args->action, args->actionButton,
                                args->flags, args->metaState, args->buttonState,
                                args->classification, args->edgeFlags, args->xPrecision,
                                args->yPrecision, args->xCursorPosition, args->yCursorPosition,
                                args->downTime, args->pointerCount, args->pointerProperties,
                                args->pointerCoords, 0, 0);
        //進(jìn)入dispatcher的隊(duì)列等待dispatcher處理派發(fā)
        needWake = enqueueInboundEventLocked(newEntry);
        mLock.unlock();
    } // release lock

    if (needWake) {
        //派發(fā)隊(duì)列來事件了,喚醒InputDispatcher
        mLooper->wake();
    }
}

1 根據(jù)inputReader上來的數(shù)據(jù)參數(shù)action判斷如果不是AMOTION_EVENT_ACTION_MOVE
打印inputReader上報(bào)上來的數(shù)據(jù)信息,如果涉及多指
會遍歷每一個(gè)觸控點(diǎn)數(shù)據(jù)打印。
2 驗(yàn)證是否是有效事件
3 設(shè)置事件是值得信任的
4 事件進(jìn)入隊(duì)列前通過dispatchPolicy進(jìn)行事件攔截
5 判斷事件是否需要過濾需要就添加POLICY_FLAG_FILTERED標(biāo)記,如果事件被過濾掉了就直接return了,如果事件沒被過濾掉。
6 根據(jù)inputreader上來的數(shù)據(jù)構(gòu)建觸摸事件
7 觸摸事件構(gòu)建成功 喚醒InputDispatcher線程處理事件

1.1 驗(yàn)證是否是有效事件
static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
                                const PointerProperties* pointerProperties) {
    if (!isValidMotionAction(action, actionButton, pointerCount)) {
        //驗(yàn)證action是否有效
        ALOGE("Motion event has invalid action code 0x%x", action);
        return false;
    }
    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
        //驗(yàn)證觸控點(diǎn)數(shù)量是否正常
        ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
              pointerCount, MAX_POINTERS);
        return false;
    }
    BitSet32 pointerIdBits;
    for (size_t i = 0; i < pointerCount; i++) {
        int32_t id = pointerProperties[i].id;
        if (id < 0 || id > MAX_POINTER_ID) {
            //驗(yàn)證Pointer Id是否正常
            ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
                  MAX_POINTER_ID);
            return false;
        }
        if (pointerIdBits.hasBit(id)) {
            //驗(yàn)證pointer的id 是否有對應(yīng)的bit
            ALOGE("Motion event has duplicate pointer id %d", id);
            return false;
        }
        pointerIdBits.markBit(id);
    }
    return true;
}

1 isValidMotionAction 驗(yàn)證事件的action類型是否有效
2 驗(yàn)證觸控點(diǎn)數(shù)量正常
3 驗(yàn)證觸控點(diǎn)id是否正常

1.2 dispatchPolicy進(jìn)行事件攔截
void NativeInputManager::interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
        uint32_t& policyFlags) {
    ATRACE_CALL();
    // Policy:
    // - Ignore untrusted events and pass them along.
    // - No special filtering for injected events required at this time.
    // - Filter normal events based on screen state.
    // - For normal events brighten (but do not wake) the screen if currently dim.
    bool interactive = mInteractive.load();
    if (interactive) {
        //flag定義當(dāng)一個(gè)輸入事件攜帶了 POLICY_FLAG_INTERACTIVE 標(biāo)志時(shí),
        //系統(tǒng)可能會將其視為需要交互式處理的事件,這意味著該事件可能需要立即響應(yīng)
        //事件是否需要立即響應(yīng)
        policyFlags |= POLICY_FLAG_INTERACTIVE;
    }
    //攜帶了 POLICY_FLAG_INJECTED 標(biāo)志時(shí),
    //系統(tǒng)會將其視為是由應(yīng)用程序或者其他實(shí)體主動注入(inject)到輸入事件流中的事件
    if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
        if (policyFlags & POLICY_FLAG_INTERACTIVE) {
            //當(dāng)輸入事件攜帶了這個(gè)標(biāo)志時(shí),系統(tǒng)會將其視為需要將事件傳遞給用戶進(jìn)行處理。
            policyFlags |= POLICY_FLAG_PASS_TO_USER;
        } else {
            JNIEnv* env = jniEnv();
            jint wmActions = env->CallIntMethod(mServiceObj,
                        gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
                        displayId, when, policyFlags);
            if (checkAndClearExceptionFromCallback(env,
                    "interceptMotionBeforeQueueingNonInteractive")) {
                wmActions = 0;
            }

            handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
        }
    } else {
        if (interactive) {
            //如果是其他注入的事件(滿足可交互)  也可以發(fā)給用戶
            policyFlags |= POLICY_FLAG_PASS_TO_USER;
        }
    }
}

策略過濾會回調(diào)到上層InputManagerService最后通過windowCallBack來考慮

1.3 InputFilter過濾
bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
    ATRACE_CALL();
    jobject inputEventObj;

    JNIEnv* env = jniEnv();
    //判斷事件類型
    switch (inputEvent->getType()) {
    case AINPUT_EVENT_TYPE_KEY:
    //轉(zhuǎn)換成key事件
        inputEventObj = android_view_KeyEvent_fromNative(env,
                static_cast<const KeyEvent*>(inputEvent));
        break;
    case AINPUT_EVENT_TYPE_MOTION:
    //轉(zhuǎn)換成motion事件
        inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
                static_cast<const MotionEvent*>(inputEvent));
        break;
    default:
        return true; // dispatch the event normally
    }

    if (!inputEventObj) {
        ALOGE("Failed to obtain input event object for filterInputEvent.");
        return true; // dispatch the event normally
    }

    // The callee is responsible for recycling the event.
    //來到j(luò)ava層的InputManagerService
    jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
            inputEventObj, policyFlags);
    if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
        pass = true;
    }
    env->DeleteLocalRef(inputEventObj);
    return pass;
}

native層根據(jù)事件類型將事件對象由c++轉(zhuǎn)換成java給到InputManagerService

    final boolean filterInputEvent(InputEvent event, int policyFlags) {
        synchronized (mInputFilterLock) {
            if (mInputFilter != null) {
                try {
                    mInputFilter.filterInputEvent(event, policyFlags);
                } catch (RemoteException e) {
                    /* ignore */
                }
                return false;
            }
        }
        event.recycle();
        return true;
    }

將事件給到InputFilter

final public void filterInputEvent(InputEvent event, int policyFlags) {
        mH.obtainMessage(MSG_INPUT_EVENT, policyFlags, 0, event).sendToTarget();
    }

通過Handler發(fā)送MSG_INPUT_EVENT消息

   private final class H extends Handler {
        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_INSTALL:
                    mHost = (IInputFilterHost) msg.obj;
                    if (mInboundInputEventConsistencyVerifier != null) {
                        mInboundInputEventConsistencyVerifier.reset();
                    }
                    if (mOutboundInputEventConsistencyVerifier != null) {
                        mOutboundInputEventConsistencyVerifier.reset();
                    }
                    onInstalled();
                    break;

                case MSG_UNINSTALL:
                    try {
                        onUninstalled();
                    } finally {
                        mHost = null;
                    }
                    break;

                case MSG_INPUT_EVENT: {
                    final InputEvent event = (InputEvent)msg.obj;
                    try {
                        if (mInboundInputEventConsistencyVerifier != null) {
                            mInboundInputEventConsistencyVerifier.onInputEvent(event, 0);
                        }
                    //處理輸入事件
                        onInputEvent(event, msg.arg1);
                    } finally {
                        event.recycle();
                    }
                    break;
                }
            }
        }

最后由view的InputFilter處理事件

1.4 事件入派發(fā)隊(duì)列
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
    //事件加入之前如果之前隊(duì)列是空的 要喚醒InputDispatcher
    bool needWake = mInboundQueue.empty();
    //添加隊(duì)列末尾
    mInboundQueue.push_back(entry);
    traceInboundQueueLengthLocked();

    switch (entry->type) {
        case EventEntry::Type::KEY: {
            // Optimize app switch latency.
            // If the application takes too long to catch up then we drop all events preceding
            // the app switch key.
            const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
            if (isAppSwitchKeyEvent(keyEntry)) {
                if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
                    mAppSwitchSawKeyDown = true;
                } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
                    if (mAppSwitchSawKeyDown) {
#if DEBUG_APP_SWITCH
                        ALOGD("App switch is pending!");
#endif
                        mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
                        mAppSwitchSawKeyDown = false;
                        needWake = true;
                    }
                }
            }
            break;
        }

        case EventEntry::Type::MOTION: {
            //檢查和修剪輸入事件隊(duì)列中的 Motion 事件
            if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(*entry))) {
                //mNextUnblockedEvent 保證下次事件可以及時(shí)響應(yīng)
                mNextUnblockedEvent = entry;
                needWake = true;
            }
            break;
        }
        case EventEntry::Type::FOCUS: {
            LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
            break;
        }
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET: {
            // nothing to do
            break;
        }
    }

    return needWake;
}

如果添加事件到派發(fā)隊(duì)列時(shí) 當(dāng)前隊(duì)列如果沒有事件那么needWake = true

2 InputDispatcher第二部分

void InputDispatcher::dispatchOnce() {
    //下次喚醒時(shí)間 默認(rèn)無限長
    nsecs_t nextWakeupTime = LONG_LONG_MAX;
    { // acquire lock
        std::scoped_lock _l(mLock);
        mDispatcherIsAlive.notify_all();

        // Run a dispatch loop if there are no pending commands.
        // The dispatch loop might enqueue commands to run afterwards.
        if (!haveCommandsLocked()) {
            //保證命令隊(duì)列(一次事件處理完整結(jié)束)無事件才會執(zhí)行
            dispatchOnceInnerLocked(&nextWakeupTime);
        }

        // Run all pending commands if there are any.
        // If any commands were run then force the next poll to wake up immediately.
        //根據(jù)遍歷CommandQueue里的元素執(zhí)行command函數(shù)決定是否立刻喚醒
        if (runCommandsLockedInterruptible()) {
            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.
        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
        if (nextWakeupTime == LONG_LONG_MAX) {
            mDispatcherEnteredIdle.notify_all();
        }
    } // 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);
}

1 當(dāng)前commandQueue無command 或者一次事件完整處理完
執(zhí)行下一次事件處理
2 考慮遍歷commandQueue的元素來決定是否立刻喚醒派發(fā)線程

2.1 一次事件處理
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    //記錄當(dāng)前時(shí)間
    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.
    //查看是否開啟派發(fā)處理
    if (!mDispatchEnabled) {
        resetKeyRepeatLocked();
    }

    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
    //如果派發(fā)凍結(jié)退出當(dāng)次派發(fā) 等待下次派發(fā)
    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.
    //如果應(yīng)用切換時(shí)間<當(dāng)前時(shí)間
    //下次喚醒時(shí)間等于應(yīng)用切換時(shí)間
    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是null
        if (mInboundQueue.empty()) {
            //派發(fā)隊(duì)列也是空
            if (isAppSwitchDue) {
                //存在app切換操作
                // The inbound queue is empty so the app switch key we were waiting
                // for will never arrive.  Stop waiting for it.
                //清除AppSwitch事件應(yīng)用切換標(biāo)志為false
                //為什么事件隊(duì)列為空 就不需要在等了呢
                //原因 isAppSwitchDue 為 true
                //代表下次事件一定是app切換事件 但是事件隊(duì)列沒有
                //那么他肯定就不會再來了
                resetPendingAppSwitchLocked(false);
                isAppSwitchDue = false;
            }

            // Synthesize a key repeat if appropriate.
            if (mKeyRepeatState.lastKeyEntry) {
                if (currentTime >= mKeyRepeatState.nextRepeatTime) {
                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
                } else {
                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
                    }
                }
            }

            // Nothing to do if there is no pending event.
            if (!mPendingEvent) {
                //如果經(jīng)歷了應(yīng)用切換和重復(fù)按鍵情況都沒有事件那就可以退出
                //等待下次隊(duì)列存在事件
                return;
            }
        } else {
            // Inbound queue has at least one entry.
            //事件隊(duì)列不為空從事件隊(duì)列取出緩存事件
            mPendingEvent = mInboundQueue.front();
            //事件隊(duì)列移除取出的事件    
            mInboundQueue.pop_front();
            traceInboundQueueLengthLocked();
        }

        // Poke user activity for this event.
        //檢查緩存事件的flag是否有POLICY_FLAG_PASS_TO_USER flag
        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;
    //POLICY_FLAG_PASS_TO_USER
    //標(biāo)記表示輸入法在處理用戶輸入時(shí),會充分尊重用戶的交互需求,
    //讓用戶能夠參與到輸入過程并及時(shí)調(diào)整
    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
        //policyFlags沒有 POLICY_FLAG_PASS_TO_USER 
        //丟棄策略問題
        dropReason = DropReason::POLICY;
    } else if (!mDispatchEnabled) {
        //如果未開啟派發(fā) 丟棄原因未啟用
        dropReason = DropReason::DISABLED;
    }

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

    switch (mPendingEvent->type) {
        case EventEntry::Type::CONFIGURATION_CHANGED: {
            ConfigurationChangedEntry* typedEntry =
                    static_cast<ConfigurationChangedEntry*>(mPendingEvent);
            done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
            dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
            break;
        }

        case EventEntry::Type::DEVICE_RESET: {
            DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
            done = dispatchDeviceResetLocked(currentTime, typedEntry);
            dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
            break;
        }

        case EventEntry::Type::FOCUS: {
            FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
            dispatchFocusLocked(currentTime, typedEntry);
            done = true;
            dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
            break;
        }

        case EventEntry::Type::KEY: {
            KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
            if (isAppSwitchDue) {
                if (isAppSwitchKeyEvent(*typedEntry)) {
                    resetPendingAppSwitchLocked(true);
                    isAppSwitchDue = false;
                } else if (dropReason == DropReason::NOT_DROPPED) {
                    dropReason = DropReason::APP_SWITCH;
                }
            }
            if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
                dropReason = DropReason::STALE;
            }
            if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
                dropReason = DropReason::BLOCKED;
            }
            done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
            break;
        }

        case EventEntry::Type::MOTION: {
            MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
            //因?yàn)閼?yīng)用切換丟棄當(dāng)前事件 并且聲明丟棄原因
            if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
                dropReason = DropReason::APP_SWITCH;
            }
            if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
                dropReason = DropReason::STALE;
            }
            //如果存在mNextUnblockedEvent事件 需要丟棄當(dāng)次事件
            if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
                dropReason = DropReason::BLOCKED;
            }
            //處理motion事件
            done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
            break;
        }
    }

    if (done) {
        //如果事件被丟棄
        if (dropReason != DropReason::NOT_DROPPED) {
            //Log打印事件丟棄原因
            dropInboundEventLocked(*mPendingEvent, dropReason);
        }
        //記錄上次丟棄原因
        mLastDropReason = dropReason;
        //清除當(dāng)次緩存事件 開啟下一次事件循環(huán)
        releasePendingEventLocked();
        *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
    }
}

1 查看派發(fā)是否開啟
2 查看派發(fā)是否被凍結(jié) 例如橫豎屏轉(zhuǎn)換
3 檢查當(dāng)前是否處于應(yīng)用切換按鍵操作
4 獲取緩存事件
4.1 事件隊(duì)列有事件
直接從隊(duì)列頭部取出事件

4.2 事件隊(duì)列無事件
1 如果當(dāng)前是應(yīng)用切換狀態(tài) 那么可以直接重置應(yīng)用切換相關(guān)緩存
2 如果存在重復(fù)事件 則根據(jù)上次事件生成當(dāng)次事件
緩存事件為空 直接返回 等待下一次事件處理
5 檢查緩存事件Flag
POLICY_FLAG_PASS_TO_USER
標(biāo)記表示輸入法在處理用戶輸入時(shí),會充分尊重用戶的交互需求,
讓用戶能夠參與到輸入過程并及時(shí)調(diào)整 及時(shí)交互反饋
6 根據(jù)事件類型 強(qiáng)制轉(zhuǎn)換相關(guān)事件
7 根據(jù)應(yīng)用是否切換isAppSwitchDue
是否為stale event
下一次事件是否提前執(zhí)行mNextUnblockedEvent
來定義當(dāng)次事件丟棄原因
8 執(zhí)行dispatchMotionLocked 處理當(dāng)次motion事件
9 處理完成 根據(jù)dropReason 打印相關(guān)丟棄事件原因log
對丟棄原因進(jìn)行記錄
釋放當(dāng)次緩存事件
設(shè)置下次喚醒時(shí)間為LONG_LONG_MIN

2.2 dispatchMotionLocked函數(shù)處理
bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
                                           DropReason* dropReason, nsecs_t* nextWakeupTime) {
    ATRACE_CALL();
    // Preprocessing.
    //如果當(dāng)前未處于派發(fā)中 那就設(shè)置當(dāng)次事件處于派發(fā)中
    if (!entry->dispatchInProgress) {
        entry->dispatchInProgress = true;

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

    // Clean up if dropping the event.
    if (*dropReason != DropReason::NOT_DROPPED) {
        //根據(jù)DropReason設(shè)置注入結(jié)果
        setInjectionResult(entry,
                           *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
                                                             : INPUT_EVENT_INJECTION_FAILED);
        return true;
    }
    //確認(rèn)當(dāng)次事件是否為手指事件
    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;

    // Identify targets.
    //派發(fā)目標(biāo)集合
    std::vector<InputTarget> inputTargets;

    bool conflictingPointerActions = false;
    int32_t injectionResult;
    if (isPointerEvent) {
        // Pointer event.  (eg. touchscreen)
        //手指事件 根據(jù)touch找到合適窗口
        injectionResult =
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                                               &conflictingPointerActions);
    } else {
        // Non touch event.  (eg. trackball)
        //非手指觸摸事件 通過窗口焦點(diǎn)找到合適窗口
        injectionResult =
                findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
    }
    //注入結(jié)果為INPUT_EVENT_INJECTION_PENDING
    //退出當(dāng)次事件派發(fā) 等待下一次
    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
        return false;
    }
    //設(shè)置對應(yīng)事件的注入結(jié)果
    setInjectionResult(entry, injectionResult);
    if (injectionResult == INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
        //如果注入結(jié)果為INPUT_EVENT_INJECTION_PERMISSION_DENIED
        ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
        return true;
    }
    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
        //如果注入的結(jié)果不是成功 那么根據(jù)是否是手指觸摸事件生成cancel事件
        //注入到事件隊(duì)列
        CancelationOptions::Mode mode(isPointerEvent
                                              ? CancelationOptions::CANCEL_POINTER_EVENTS
                                              : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
        CancelationOptions options(mode, "input event injection failed");
        synthesizeCancelationEventsForMonitorsLocked(options);
        return true;
    }

    // Add monitor channels from event's or focused display.
    //查看當(dāng)前是否屬于touch的down事件
    bool isShowTouchDump = false;
        if ((entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN
        || (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
        isShowTouchDump = true;
    }
     //根據(jù)touch事件或者key事件 打印相關(guān)log 窗口信息 等等
    ALOGD("addGlobalMonitoringTargetsLocked isShowTouchDump: %s", isShowTouchDump ? "true" : "false");
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry), isShowTouchDump, false);

    if (isPointerEvent) {
        std::unordered_map<int32_t, TouchState>::iterator it =
                mTouchStatesByDisplay.find(entry->displayId);
        if (it != mTouchStatesByDisplay.end()) {
            const TouchState& state = it->second;
            if (!state.portalWindows.empty()) {
                // The event has gone through these portal windows, so we add monitoring targets of
                // the corresponding displays as well.
                for (size_t i = 0; i < state.portalWindows.size(); i++) {
                    const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
                    addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId, false, false,
                                                     -windowInfo->frameLeft, -windowInfo->frameTop);
                }
            }
        }
    }

    // Dispatch the motion.
    //如果手指行為action存在沖突 那會生成cancel事件加入事件隊(duì)列在分發(fā)到窗口
    if (conflictingPointerActions) {
        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                                   "conflicting pointer actions");
        synthesizeCancelationEventsForAllConnectionsLocked(options);
    }
    //派發(fā)事件到指定窗口
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}

1 查看當(dāng)前事件是否處于派發(fā)中
2 根據(jù)丟棄原因設(shè)置注入結(jié)果
3 判斷當(dāng)前事件是否為觸摸事件
4 查找touch窗口
5 根據(jù)查找窗口的結(jié)果進(jìn)行下一步動作
1 INPUT_EVENT_INJECTION_PENDING
當(dāng)前事件處于緩存狀態(tài)
退出當(dāng)前事件,等待下一次派發(fā)
2 INPUT_EVENT_INJECTION_PERMISSION_DENIED
當(dāng)前事件沒有權(quán)限
退出當(dāng)次事件
3 != INPUT_EVENT_INJECTION_SUCCEEDED
注入結(jié)果失敗
根據(jù)是否touch事件 生成對應(yīng)cancel 事件
加入事件隊(duì)列 等待下一次事件派發(fā)循環(huán)將事件給到對應(yīng)窗口
6 根據(jù)得到的輸入目標(biāo)窗口 遍歷打印相關(guān)log
7 如果touch事件存在沖突 和5.3一樣
8 將事件注入指定窗口

2.3 輸入事件進(jìn)入派發(fā)隊(duì)列
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
                                          const std::vector<InputTarget>& inputTargets) {
    ATRACE_CALL();
#if DEBUG_DISPATCH_CYCLE
    ALOGD("dispatchEventToCurrentInputTargets");
#endif

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

    pokeUserActivityLocked(*eventEntry);
    //遍歷touch的窗口
    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());
            }
        }
    }
}
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
                                                 const sp<Connection>& connection,
                                                 EventEntry* eventEntry,
                                                 const InputTarget& inputTarget) {
    if (ATRACE_ENABLED()) {
        std::string message =
                StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
                             connection->getInputChannelName().c_str(), eventEntry->id);
        ATRACE_NAME(message.c_str());
    }
#if DEBUG_DISPATCH_CYCLE
    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
          "globalScaleFactor=%f, pointerIds=0x%x %s",
          connection->getInputChannelName().c_str(), inputTarget.flags,
          inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
          inputTarget.getPointerInfoString().c_str());
#endif

    // 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) {
#if DEBUG_DISPATCH_CYCLE
        ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
              connection->getInputChannelName().c_str(), connection->getStatusLabel());
#endif
        return;
    }

    // Split a motion event if needed.
    //需要拆分的事件
    if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
        LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
                            "Entry type %s should not have FLAG_SPLIT",
                            EventEntry::typeToString(eventEntry->type));

        const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
        if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
            MotionEntry* splitMotionEntry =
                    splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
            if (!splitMotionEntry) {
                return; // split event was dropped
            }
            if (DEBUG_FOCUS) {
                ALOGD("channel '%s' ~ Split motion event.",
                      connection->getInputChannelName().c_str());
                logOutboundMotionDetails("  ", *splitMotionEntry);
            }
            enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
            splitMotionEntry->release();
            return;
        }
    }
    //不需要拆分的事件
    // Not splitting.  Enqueue dispatch entries for the event as is.
    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
}

檢查輸入目標(biāo)的標(biāo)志中是否包含InputTarget::FLAG_SPLIT。如果是拆分事件,會對事件類型進(jìn)行檢查,然后對原始的運(yùn)動事件進(jìn)行拆分處理,生成新的拆分事件,并將其加入到事件派發(fā)隊(duì)列中。最后釋放拆分事件的資源。

void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
                                                   const sp<Connection>& connection,
                                                   EventEntry* eventEntry,
                                                   const InputTarget& inputTarget) {
    if (ATRACE_ENABLED()) {
        std::string message =
                StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
                             connection->getInputChannelName().c_str(), eventEntry->id);
        ATRACE_NAME(message.c_str());
    }

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

    // Enqueue dispatch entries for the requested modes.
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_IS);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);

    // If the outbound queue was previously empty, start the dispatch cycle going.
    if (wasEmpty && !connection->outboundQueue.empty()) {
        startDispatchCycleLocked(currentTime, connection);
    }
}

輸入事件進(jìn)入派發(fā)隊(duì)列
這里涉及請求模式
InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT
,表示將事件派發(fā)到輸入窗口,并將其標(biāo)記為鼠標(biāo)懸停退出事件。這通常用于處理鼠標(biāo)懸停操作。當(dāng)鼠標(biāo)從一個(gè)窗口的可接收懸停事件的區(qū)域移出時(shí),會觸發(fā)該標(biāo)志位對應(yīng)的派發(fā)操作,通知窗口處理鼠標(biāo)懸停退出的邏輯。
InputTarget::FLAG_DISPATCH_AS_OUTSIDE
表示將事件派發(fā)到輸入窗口,并將其標(biāo)記為外部觸摸事件。這通常用于處理觸摸事件在窗口之外的情況。當(dāng)觸摸事件發(fā)生在窗口之外時(shí),會觸發(fā)該標(biāo)志位對應(yīng)的派發(fā)操作,通知窗口處理外部觸摸事件的邏輯

InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER
表示將事件派發(fā)到輸入窗口,并將其標(biāo)記為鼠標(biāo)懸停進(jìn)入事件。這通常用于處理鼠標(biāo)懸停操作。當(dāng)可接收懸停事件進(jìn)入一個(gè)窗口時(shí),會觸發(fā)該標(biāo)志位對應(yīng)的派發(fā)操作,通知窗口處理鼠標(biāo)懸停進(jìn)入的邏輯。

InputTarget::FLAG_DISPATCH_AS_IS
表示將事件派發(fā)到輸入窗口,并將其標(biāo)記為普通的輸入事件。這通常用于處理普通的輸入操作,如鍵盤輸入、鼠標(biāo)點(diǎn)擊等。當(dāng)普通的輸入事件發(fā)生時(shí),會觸發(fā)該標(biāo)志位對應(yīng)的派發(fā)操作,通知窗口處理普通的輸入事件的邏輯。

InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT
表示將事件派發(fā)到輸入窗口,但是不會造成焦點(diǎn)的變化。這通常用于處理“滑動”場景,在滑動過程中,我們需要不斷向當(dāng)前焦點(diǎn)窗口發(fā)送滑動事件,但是不能改變窗口的焦點(diǎn)狀態(tài)

InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER
表示將事件派發(fā)到輸入窗口,并且在派發(fā)事件時(shí)不會改變窗口的焦點(diǎn)狀態(tài)。這通常用于處理“滑動”場景,在滑動過程中,我們需要不斷向當(dāng)前焦點(diǎn)窗口發(fā)送滑動事件,但是不能改變窗口的焦點(diǎn)狀態(tài),直到滑動結(jié)束才能改變焦點(diǎn)狀態(tài)

void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
                                                 EventEntry* eventEntry,
                                                 const InputTarget& inputTarget,
                                                 int32_t dispatchMode) {
std::unique_ptr<DispatchEntry> dispatchEntry =
            createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);

 switch (newEntry->type) {
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 {
                dispatchEntry->resolvedAction = motionEntry.action;
                dispatchEntry->resolvedEventId = motionEntry.id;
            }

}

// Enqueue the dispatch entry.
    //通過調(diào)用dispatchEntry.release()方法,我們釋放了dispatchEntry智能指針的所有權(quán),
    //并返回一個(gè)指向該對象的裸指針。然后,使用push_back()方法將該裸指針
    //添加到connection對象的outboundQueue隊(duì)列的末尾。

    //這樣做的目的是將dispatchEntry對象添加到outboundQueue隊(duì)列中,
    //以便后續(xù)進(jìn)行處理或發(fā)送給其他組件。注意,由于我們已經(jīng)釋放了dispatchEntry的所有權(quán),
    //所以在outboundQueue中存儲的是裸指針,而不是智能指針。
    //需要確保在適當(dāng)?shù)臅r(shí)候管理和釋放這些指針,以避免內(nèi)存泄漏。
    connection->outboundQueue.push_back(dispatchEntry.release());
}

1 根據(jù)InputTarget eventEntry InputTargetFlags 構(gòu)建dispatchEntry對象
2 根據(jù)EventEntry的類型是MOTION 構(gòu)建motionEntry
來設(shè)置dispatchEntry->resolvedAction dispatchEntry->resolvedEventId
3 dispatchEntry對象添加到outboundQueue隊(duì)列中

2.4 從派發(fā)隊(duì)列派發(fā)事件
if (wasEmpty && !connection->outboundQueue.empty()) {
        startDispatchCycleLocked(currentTime, connection);
    }
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                               const sp<Connection>& connection) {

 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
        DispatchEntry* dispatchEntry = connection->outboundQueue.front();
        dispatchEntry->deliveryTime = currentTime;
        const nsecs_t timeout =
                getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
        dispatchEntry->timeoutTime = currentTime + timeout;

        // Publish the event.
        status_t status;
        EventEntry* eventEntry = dispatchEntry->eventEntry;
        switch (eventEntry->type) {
case EventEntry::Type::MOTION: {
                MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
                //調(diào)整為窗口可用的指針數(shù)組
                PointerCoords scaledCoords[MAX_POINTERS];
                //當(dāng)前屏幕使用的坐標(biāo)數(shù)組
                const PointerCoords* usingCoords = motionEntry->pointerCoords;

                // Set the X and Y offset and X and Y scale depending on the input source.
                float xOffset = 0.0f, yOffset = 0.0f;
                float xScale = 1.0f, yScale = 1.0f;
                if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
                    !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
                    float globalScaleFactor = dispatchEntry->globalScaleFactor;
                    xScale = dispatchEntry->windowXScale;
                    yScale = dispatchEntry->windowYScale;
                    xOffset = dispatchEntry->xOffset * xScale;
                    yOffset = dispatchEntry->yOffset * yScale;
                    //代表設(shè)備無關(guān)的坐標(biāo)轉(zhuǎn)換設(shè)備相關(guān)的坐標(biāo)
                    if (globalScaleFactor != 1.0f) {
                        //遍歷指針數(shù)量
                        for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
                            //將當(dāng)前motionEntry->pointerCoords[i]賦值到scaledCoords[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.
                            //坐標(biāo)縮放調(diào)整
                            scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
                                                  1 /* windowYScale */);
                        }
                        //將scaledCoords給到usingCoords
                        usingCoords = scaledCoords;
                    }
                } else {
                    // We don't want the dispatch target to know.
                    //輸入目標(biāo)需要將坐標(biāo)歸零,清空scaledCoords數(shù)組
                    if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
                        for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
                            scaledCoords[i].clear();
                        }
                        //賦值給usingCoords
                        usingCoords = scaledCoords;
                    }
                }

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

                // Publish the motion event.
                //上傳該motion事件
                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, xScale, yScale,
                                                     xOffset, yOffset, motionEntry->xPrecision,
                                                     motionEntry->yPrecision,
                                                     motionEntry->xCursorPosition,
                                                     motionEntry->yCursorPosition,
                                                     motionEntry->downTime, motionEntry->eventTime,
                                                     motionEntry->pointerCount,
                                                     motionEntry->pointerProperties, usingCoords);
                reportTouchEventForStatistics(*motionEntry);
                break;
            }

}
        // Re-enqueue the event on the wait queue.
        //從派發(fā)隊(duì)列中移除該事件
        connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
                                                    connection->outboundQueue.end(),
                                                    dispatchEntry));
        traceOutboundQueueLength(connection);
        //在等待隊(duì)列中添加該事件
        connection->waitQueue.push_back(dispatchEntry);
        if (connection->responsive) {
            //如果窗口無響應(yīng)將派發(fā)事件的超時(shí)時(shí)間和派發(fā)窗口token加入到ANR觸發(fā)器
            mAnrTracker.insert(dispatchEntry->timeoutTime,
                               connection->inputChannel->getConnectionToken());
        }
        traceWaitQueueLength(connection);
    }
}

}

1 確認(rèn)連接通道正常 且派發(fā)隊(duì)列事件不為空
2 outboundQueue頭部取出數(shù)據(jù)
設(shè)置分發(fā)時(shí)間 當(dāng)前時(shí)間
獲取超時(shí)時(shí)間間隔
設(shè)置超時(shí)時(shí)間
3 根據(jù)事件類型MOTION
創(chuàng)建窗口可用指針數(shù)組scaledCoords
usingCoords指向motion事件的pointerCoords
4 設(shè)置默認(rèn)x y 偏移 和 x y 縮放
5 判斷當(dāng)前source是POINTER 并且targetFlaget 不是InputTarget::FLAG_ZERO_COORDS標(biāo)志
6 全局縮放因子globalScaleFactor == 1.0f代表不需要調(diào)整設(shè)備坐標(biāo)
7 全局縮放因子globalScaleFactor != 1.0f 需要將當(dāng)前motionEntry->pointerCoords[i]通過縮放調(diào)整為scaledCoords[i]
同時(shí) usingCoords也被賦值為scaledCoords
8 如果targetFlaget 是InputTarget::FLAG_ZERO_COORDS標(biāo)志
需要將 scaledCoords數(shù)組信息清空 賦值給usingCoords
9 通過connection->inputPublisher 將motionEvent發(fā)布出去
10 connection->outboundQueue 派發(fā)隊(duì)列刪除該事件
11connection->waitQueue 等待隊(duì)列加入該事件
12 如果窗口無響應(yīng)將派發(fā)事件的超時(shí)時(shí)間和派發(fā)窗口token加入到ANR觸發(fā)器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容