Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9bb9be9 authored by Jeff Brown's avatar Jeff Brown
Browse files

Simplify input target handling in the dispatcher.

Since we no longer stream events to the application, we don't need to
keep the current list of input targets around longer than it takes
to begin the dispatch cycle.

This is part of a series of changes to improve input system pipelining.

Bug: 5963420

Change-Id: I5824b04e564c8a4dec991598292441e46c331905
parent cbee6d6e
Loading
Loading
Loading
Loading
+58 −88
Original line number Diff line number Diff line
@@ -178,7 +178,6 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic
    mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
    mNextUnblockedEvent(NULL),
    mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
    mCurrentInputTargetsValid(false),
    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
    mLooper = new Looper(false);

@@ -270,21 +269,20 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {

            // Nothing to do if there is no pending event.
            if (!mPendingEvent) {
                if (mActiveConnections.isEmpty()) {
                    dispatchIdleLocked();
                }
                return;
            }
        } else {
            // Inbound queue has at least one entry.
            EventEntry* entry = mInboundQueue.dequeueAtHead();
            mPendingEvent = entry;
            mPendingEvent = mInboundQueue.dequeueAtHead();
        }

        // Poke user activity for this event.
        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
            pokeUserActivityLocked(mPendingEvent);
        }

        // Get ready to dispatch the event.
        resetANRTimeoutsLocked();
    }

    // Now we have an event to dispatch.
@@ -372,16 +370,6 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    }
}

void InputDispatcher::dispatchIdleLocked() {
#if DEBUG_FOCUS
    ALOGD("Dispatcher idle.  There are no pending events or active connections.");
#endif

    // Reset targets when idle, to release input channels and other resources
    // they are holding onto.
    resetTargetsLocked();
}

bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
    bool needWake = mInboundQueue.isEmpty();
    mInboundQueue.enqueueAtTail(entry);
@@ -582,6 +570,7 @@ void InputDispatcher::drainInboundQueueLocked() {

void InputDispatcher::releasePendingEventLocked() {
    if (mPendingEvent) {
        resetANRTimeoutsLocked();
        releaseInboundEventLocked(mPendingEvent);
        mPendingEvent = NULL;
    }
@@ -704,7 +693,6 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
        }

        entry->dispatchInProgress = true;
        resetTargetsLocked();

        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
    }
@@ -743,16 +731,15 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,

    // Clean up if dropping the event.
    if (*dropReason != DROP_REASON_NOT_DROPPED) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
        return true;
    }

    // Identify targets.
    if (! mCurrentInputTargetsValid) {
    Vector<InputTarget> inputTargets;
    int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
                entry, nextWakeupTime);
            entry, inputTargets, nextWakeupTime);
    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
        return false;
    }
@@ -762,12 +749,10 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
        return true;
    }

        addMonitoringTargetsLocked();
        commitTargetsLocked();
    }
    addMonitoringTargetsLocked(inputTargets);

    // Dispatch the key.
    dispatchEventToCurrentInputTargetsLocked(currentTime, entry);
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}

@@ -788,14 +773,12 @@ bool InputDispatcher::dispatchMotionLocked(
    // Preprocessing.
    if (! entry->dispatchInProgress) {
        entry->dispatchInProgress = true;
        resetTargetsLocked();

        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
    }

    // Clean up if dropping the event.
    if (*dropReason != DROP_REASON_NOT_DROPPED) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
        return true;
@@ -804,17 +787,18 @@ bool InputDispatcher::dispatchMotionLocked(
    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;

    // Identify targets.
    Vector<InputTarget> inputTargets;

    bool conflictingPointerActions = false;
    if (! mCurrentInputTargetsValid) {
    int32_t injectionResult;
    if (isPointerEvent) {
        // Pointer event.  (eg. touchscreen)
        injectionResult = findTouchedWindowTargetsLocked(currentTime,
                    entry, nextWakeupTime, &conflictingPointerActions);
                entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
    } else {
        // Non touch event.  (eg. trackball)
        injectionResult = findFocusedWindowTargetsLocked(currentTime,
                    entry, nextWakeupTime);
                entry, inputTargets, nextWakeupTime);
    }
    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
        return false;
@@ -825,9 +809,7 @@ bool InputDispatcher::dispatchMotionLocked(
        return true;
    }

        addMonitoringTargetsLocked();
        commitTargetsLocked();
    }
    addMonitoringTargetsLocked(inputTargets);

    // Dispatch the motion.
    if (conflictingPointerActions) {
@@ -835,7 +817,7 @@ bool InputDispatcher::dispatchMotionLocked(
                "conflicting pointer actions");
        synthesizeCancelationEventsForAllConnectionsLocked(options);
    }
    dispatchEventToCurrentInputTargetsLocked(currentTime, entry);
    dispatchEventLocked(currentTime, entry, inputTargets);
    return true;
}

@@ -873,8 +855,8 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M
#endif
}

void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
        EventEntry* eventEntry) {
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
        EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
#if DEBUG_DISPATCH_CYCLE
    ALOGD("dispatchEventToCurrentInputTargets");
#endif
@@ -883,8 +865,8 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi

    pokeUserActivityLocked(eventEntry);

    for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
        const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
    for (size_t i = 0; i < inputTargets.size(); i++) {
        const InputTarget& inputTarget = inputTargets.itemAt(i);

        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
        if (connectionIndex >= 0) {
@@ -900,16 +882,6 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
    }
}

void InputDispatcher::resetTargetsLocked() {
    mCurrentInputTargetsValid = false;
    mCurrentInputTargets.clear();
    resetANRTimeoutsLocked();
}

void InputDispatcher::commitTargetsLocked() {
    mCurrentInputTargetsValid = true;
}

int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
        const EventEntry* entry,
        const sp<InputApplicationHandle>& applicationHandle,
@@ -1024,9 +996,7 @@ void InputDispatcher::resetANRTimeoutsLocked() {
}

int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
        const EventEntry* entry, nsecs_t* nextWakeupTime) {
    mCurrentInputTargets.clear();

        const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
    int32_t injectionResult;

    // If there is no currently focused window and no focused application
@@ -1077,7 +1047,8 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
    // Success!  Output targets.
    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
    addWindowTargetLocked(mFocusedWindowHandle,
            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0));
            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
            inputTargets);

    // Done.
Failed:
@@ -1094,15 +1065,14 @@ Unresponsive:
}

int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
        const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
        bool* outConflictingPointerActions) {
    enum InjectionPermission {
        INJECTION_PERMISSION_UNKNOWN,
        INJECTION_PERMISSION_GRANTED,
        INJECTION_PERMISSION_DENIED
    };

    mCurrentInputTargets.clear();

    nsecs_t startTime = now();

    // For security reasons, we defer updating the touch state until we are sure that
@@ -1468,7 +1438,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
        addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
                touchedWindow.pointerIds);
                touchedWindow.pointerIds, inputTargets);
    }

    // Drop the outside or hover touch windows since we will not care about them
@@ -1573,11 +1543,11 @@ Unresponsive:
}

void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
        int32_t targetFlags, BitSet32 pointerIds) {
    mCurrentInputTargets.push();
        int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
    inputTargets.push();

    const InputWindowInfo* windowInfo = windowHandle->getInfo();
    InputTarget& target = mCurrentInputTargets.editTop();
    InputTarget& target = inputTargets.editTop();
    target.inputChannel = windowInfo->inputChannel;
    target.flags = targetFlags;
    target.xOffset = - windowInfo->frameLeft;
@@ -1586,11 +1556,11 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH
    target.pointerIds = pointerIds;
}

void InputDispatcher::addMonitoringTargetsLocked() {
void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
        mCurrentInputTargets.push();
        inputTargets.push();

        InputTarget& target = mCurrentInputTargets.editTop();
        InputTarget& target = inputTargets.editTop();
        target.inputChannel = mMonitoringChannels[i];
        target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
        target.xOffset = 0;
@@ -2819,13 +2789,13 @@ void InputDispatcher::setFocusedApplication(
        if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
            if (mFocusedApplicationHandle != inputApplicationHandle) {
                if (mFocusedApplicationHandle != NULL) {
                    resetTargetsLocked();
                    resetANRTimeoutsLocked();
                    mFocusedApplicationHandle->releaseInfo();
                }
                mFocusedApplicationHandle = inputApplicationHandle;
            }
        } else if (mFocusedApplicationHandle != NULL) {
            resetTargetsLocked();
            resetANRTimeoutsLocked();
            mFocusedApplicationHandle->releaseInfo();
            mFocusedApplicationHandle.clear();
        }
@@ -2978,7 +2948,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
    resetKeyRepeatLocked();
    releasePendingEventLocked();
    drainInboundQueueLocked();
    resetTargetsLocked();
    resetANRTimeoutsLocked();

    mTouchState.reset();
    mLastHoverWindowHandle.clear();
+9 −12
Original line number Diff line number Diff line
@@ -834,7 +834,6 @@ private:
    Vector<EventEntry*> mTempCancelationEvents;

    void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
    void dispatchIdleLocked();

    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
    bool enqueueInboundEventLocked(EventEntry* entry);
@@ -955,15 +954,13 @@ private:
    bool dispatchMotionLocked(
            nsecs_t currentTime, MotionEntry* entry,
            DropReason* dropReason, nsecs_t* nextWakeupTime);
    void dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime, EventEntry* entry);
    void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
            const Vector<InputTarget>& inputTargets);

    void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
    void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);

    // The input targets that were most recently identified for dispatch.
    bool mCurrentInputTargetsValid; // false while targets are being recomputed
    Vector<InputTarget> mCurrentInputTargets;

    // Keeping track of ANR timeouts.
    enum InputTargetWaitCause {
        INPUT_TARGET_WAIT_CAUSE_NONE,
        INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
@@ -980,8 +977,6 @@ private:
    sp<InputWindowHandle> mLastHoverWindowHandle;

    // Finding targets for input events.
    void resetTargetsLocked();
    void commitTargetsLocked();
    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
            const sp<InputApplicationHandle>& applicationHandle,
            const sp<InputWindowHandle>& windowHandle,
@@ -992,13 +987,15 @@ private:
    void resetANRTimeoutsLocked();

    int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
            nsecs_t* nextWakeupTime);
            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime);
    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
            nsecs_t* nextWakeupTime, bool* outConflictingPointerActions);
            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
            bool* outConflictingPointerActions);

    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
            int32_t targetFlags, BitSet32 pointerIds);
    void addMonitoringTargetsLocked();
            int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
    void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);

    void pokeUserActivityLocked(const EventEntry* eventEntry);
    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
            const InjectionState* injectionState);