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

Commit bec4e2cf authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 9c258710: Merge "Fix app switch latency optimization." into gingerbread

Merge commit '9c2587104ae259b9fa6a3525063197cc08e8820b' into gingerbread-plus-aosp

* commit '9c2587104ae259b9fa6a3525063197cc08e8820b':
  Fix app switch latency optimization.
parents 3a22b2da 42f6ea4f
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -851,8 +851,8 @@ private:

    // Inbound event processing.
    void drainInboundQueueLocked();
    void releasePendingEventLocked(bool wasDropped);
    void releaseInboundEventLocked(EventEntry* entry, bool wasDropped);
    void releasePendingEventLocked();
    void releaseInboundEventLocked(EventEntry* entry);
    bool isEventFromReliableSourceLocked(EventEntry* entry);

    // Dispatch state.
@@ -886,10 +886,10 @@ private:
            nsecs_t currentTime, ConfigurationChangedEntry* entry);
    bool dispatchKeyLocked(
            nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
            nsecs_t* nextWakeupTime);
            bool dropEvent, nsecs_t* nextWakeupTime);
    bool dispatchMotionLocked(
            nsecs_t currentTime, MotionEntry* entry,
            nsecs_t* nextWakeupTime);
            bool dropEvent, nsecs_t* nextWakeupTime);
    void dispatchEventToCurrentInputTargetsLocked(
            nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);

@@ -914,8 +914,8 @@ private:
    bool mInputTargetWaitTimeoutExpired;

    // Finding targets for input events.
    void startFindingTargetsLocked();
    void finishFindingTargetsLocked(const InputWindow* window);
    void resetTargetsLocked();
    void commitTargetsLocked(const InputWindow* window);
    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
            const InputApplication* application, const InputWindow* window,
            nsecs_t* nextWakeupTime);
+75 −48
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ InputDispatcher::~InputDispatcher() {
        AutoMutex _l(mLock);

        resetKeyRepeatLocked();
        releasePendingEventLocked(true);
        releasePendingEventLocked();
        drainInboundQueueLocked();
    }

@@ -174,7 +174,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
    if (! mDispatchEnabled) {
        if (mPendingEvent || ! mInboundQueue.isEmpty()) {
            LOGI("Dropping pending events because input dispatch is disabled.");
            releasePendingEventLocked(true);
            releasePendingEventLocked();
            drainInboundQueueLocked();
        }
        return;
@@ -281,51 +281,50 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,

    // Now we have an event to dispatch.
    assert(mPendingEvent != NULL);
    bool wasDispatched = false;
    bool wasDropped = false;
    bool done = false;
    switch (mPendingEvent->type) {
    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
        ConfigurationChangedEntry* typedEntry =
                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
        wasDispatched = dispatchConfigurationChangedLocked(currentTime, typedEntry);
        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
        break;
    }

    case EventEntry::TYPE_KEY: {
        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
        if (isAppSwitchPendingLocked()) {
            if (isAppSwitchKey(typedEntry->keyCode)) {
        bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
        bool dropEvent = isAppSwitchDue && ! appSwitchKey;
        done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
                nextWakeupTime);
        if (done) {
            if (dropEvent) {
                LOGI("Dropped key because of pending overdue app switch.");
            } else if (appSwitchKey) {
                resetPendingAppSwitchLocked(true);
            } else if (isAppSwitchDue) {
                LOGI("Dropping key because of pending overdue app switch.");
                wasDropped = true;
                break;
            }
        }
        wasDispatched = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
                nextWakeupTime);
        break;
    }

    case EventEntry::TYPE_MOTION: {
        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
        if (isAppSwitchDue) {
            LOGI("Dropping motion because of pending overdue app switch.");
            wasDropped = true;
            break;
        bool dropEvent = isAppSwitchDue;
        done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
        if (done) {
            if (dropEvent) {
                LOGI("Dropped motion because of pending overdue app switch.");
            }
        }
        wasDispatched = dispatchMotionLocked(currentTime, typedEntry, nextWakeupTime);
        break;
    }

    default:
        assert(false);
        wasDropped = true;
        break;
    }

    if (wasDispatched || wasDropped) {
        releasePendingEventLocked(wasDropped);
    if (done) {
        releasePendingEventLocked();
        *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
    }
}
@@ -403,21 +402,21 @@ InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command comman
void InputDispatcher::drainInboundQueueLocked() {
    while (! mInboundQueue.isEmpty()) {
        EventEntry* entry = mInboundQueue.dequeueAtHead();
        releaseInboundEventLocked(entry, true /*wasDropped*/);
        releaseInboundEventLocked(entry);
    }
}

void InputDispatcher::releasePendingEventLocked(bool wasDropped) {
void InputDispatcher::releasePendingEventLocked() {
    if (mPendingEvent) {
        releaseInboundEventLocked(mPendingEvent, wasDropped);
        releaseInboundEventLocked(mPendingEvent);
        mPendingEvent = NULL;
    }
}

void InputDispatcher::releaseInboundEventLocked(EventEntry* entry, bool wasDropped) {
    if (wasDropped) {
void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
    if (entry->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
#if DEBUG_DISPATCH_CYCLE
        LOGD("Pending event was dropped.");
        LOGD("Inbound event was dropped.  Setting injection result to failed.");
#endif
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
    }
@@ -492,7 +491,41 @@ bool InputDispatcher::dispatchConfigurationChangedLocked(

bool InputDispatcher::dispatchKeyLocked(
        nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
        nsecs_t* nextWakeupTime) {
        bool dropEvent, nsecs_t* nextWakeupTime) {
    // Give the policy a chance to intercept the key.
    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
        bool trusted;
        if (! dropEvent && mFocusedWindow) {
            trusted = checkInjectionPermission(mFocusedWindow,
                    entry->injectorPid, entry->injectorUid);
        } else {
            trusted = isEventFromReliableSourceLocked(entry);
        }
        if (trusted) {
            CommandEntry* commandEntry = postCommandLocked(
                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
            if (! dropEvent && mFocusedWindow) {
                commandEntry->inputChannel = mFocusedWindow->inputChannel;
            }
            commandEntry->keyEntry = entry;
            entry->refCount += 1;
            return false; // wait for the command to run
        } else {
            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
        }
    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
        return true;
    }

    // Clean up if dropping the event.
    if (dropEvent) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
        return true;
    }

    // Preprocessing.
    if (! entry->dispatchInProgress) {
        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
@@ -521,7 +554,7 @@ bool InputDispatcher::dispatchKeyLocked(
        }

        entry->dispatchInProgress = true;
        startFindingTargetsLocked(); // resets mCurrentInputTargetsValid
        resetTargetsLocked();
    }

    // Identify targets.
@@ -539,20 +572,7 @@ bool InputDispatcher::dispatchKeyLocked(
        }

        addMonitoringTargetsLocked();
        finishFindingTargetsLocked(window);
    }

    // Give the policy a chance to intercept the key.
    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
        CommandEntry* commandEntry = postCommandLocked(
                & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
        commandEntry->inputChannel = mCurrentInputChannel;
        commandEntry->keyEntry = entry;
        entry->refCount += 1;
        return false; // wait for the command to run
    }
    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
        return true;
        commitTargetsLocked(window);
    }

    // Dispatch the key.
@@ -576,13 +596,20 @@ void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyE
}

bool InputDispatcher::dispatchMotionLocked(
        nsecs_t currentTime, MotionEntry* entry, nsecs_t* nextWakeupTime) {
        nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
    // Clean up if dropping the event.
    if (dropEvent) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
        return true;
    }

    // Preprocessing.
    if (! entry->dispatchInProgress) {
        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);

        entry->dispatchInProgress = true;
        startFindingTargetsLocked(); // resets mCurrentInputTargetsValid
        resetTargetsLocked();
    }

    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
@@ -610,7 +637,7 @@ bool InputDispatcher::dispatchMotionLocked(
        }

        addMonitoringTargetsLocked();
        finishFindingTargetsLocked(window);
        commitTargetsLocked(window);
    }

    // Dispatch the motion.
@@ -705,14 +732,14 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
    }
}

void InputDispatcher::startFindingTargetsLocked() {
void InputDispatcher::resetTargetsLocked() {
    mCurrentInputTargetsValid = false;
    mCurrentInputTargets.clear();
    mCurrentInputChannel.clear();
    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
}

void InputDispatcher::finishFindingTargetsLocked(const InputWindow* window) {
void InputDispatcher::commitTargetsLocked(const InputWindow* window) {
    mCurrentInputWindowType = window->layoutParamsType;
    mCurrentInputChannel = window->inputChannel;
    mCurrentInputTargetsValid = true;