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

Commit c3c0a7d8 authored by The Android Automerger's avatar The Android Automerger
Browse files

Merge branch 'master' into honeycomb-release

parents 909106e5 ed99838a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -111,10 +111,10 @@ enum {
    /* The input device is a multi-touch touchscreen. */
    INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,

    /* The input device is a directional pad. */
    /* The input device is a directional pad (implies keyboard, has DPAD keys). */
    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,

    /* The input device is a gamepad (implies keyboard). */
    /* The input device is a gamepad (implies keyboard, has BUTTON keys). */
    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040,

    /* The input device has switches. */
+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);
+16 −2
Original line number Diff line number Diff line
@@ -70,9 +70,13 @@ ssize_t SensorEventQueue::write(ASensorEvent const* events, size_t numEvents)
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents)
{
    ssize_t size = mSensorChannel->read(events, numEvents*sizeof(events[0]));
    LOGE_IF(size<0 && size!=-EAGAIN,
            "SensorChannel::read error (%s)", strerror(-size));
    if (size >= 0) {
        if (size % sizeof(events[0])) {
            // partial read!!! should never happen.
            LOGE("SensorEventQueue partial read (event-size=%u, read=%d)",
                    sizeof(events[0]), int(size));
            return -EINVAL;
        }
        // returns number of events read
@@ -95,8 +99,18 @@ status_t SensorEventQueue::waitForEvent() const
{
    const int fd = getFd();
    sp<Looper> looper(getLooper());
    int32_t result = looper->pollOnce(-1);
    return (result == fd) ? status_t(NO_ERROR) : status_t(-1);

    int32_t result;
    do {
        result = looper->pollOnce(-1);
        if (result == ALOOPER_EVENT_ERROR) {
            LOGE("SensorChannel::waitForEvent error (errno=%d)", errno);
            result = -EPIPE; // unknown error, so we make up one
            break;
        }
    } while (result != fd);

    return  (result == fd) ? status_t(NO_ERROR) : result;
}

status_t SensorEventQueue::wake() const
+8 −0
Original line number Diff line number Diff line
@@ -30,7 +30,11 @@ ANDROID_SINGLETON_STATIC_INSTANCE(GraphicLog)

static inline
void writeInt32(uint8_t* base, size_t& pos, int32_t value) {
#ifdef HAVE_LITTLE_ENDIAN
    int32_t v = value;
#else
    int32_t v = htole32(value);
#endif
    base[pos] = EVENT_TYPE_INT;
    memcpy(&base[pos+1], &v, sizeof(int32_t));
    pos += 1+sizeof(int32_t);
@@ -38,7 +42,11 @@ void writeInt32(uint8_t* base, size_t& pos, int32_t value) {

static inline
void writeInt64(uint8_t* base,  size_t& pos, int64_t value) {
#ifdef HAVE_LITTLE_ENDIAN
    int64_t v = value;
#else
    int64_t v = htole64(value);
#endif
    base[pos] = EVENT_TYPE_LONG;
    memcpy(&base[pos+1], &v, sizeof(int64_t));
    pos += 1+sizeof(int64_t);
+81 −52
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;
@@ -780,6 +807,7 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout
        releaseTouchedWindowLocked();

        // Input state will not be realistic.  Mark it out of sync.
        if (inputChannel.get()) {
            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
            if (connectionIndex >= 0) {
                sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
@@ -787,6 +815,7 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout
            }
        }
    }
}

nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
        nsecs_t currentTime) {
Loading