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

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

am 1da8d4d1: Merge "Fix an event injection bug when the policy is bypassed." into gingerbread

Merge commit '1da8d4d1697cec871dea8c30dad67e90db10bde6' into gingerbread-plus-aosp

* commit '1da8d4d1697cec871dea8c30dad67e90db10bde6':
  Fix an event injection bug when the policy is bypassed.
parents 082299a7 b6af9cc2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -95,6 +95,10 @@ enum {
    // Indicates that the input event was injected.
    POLICY_FLAG_INJECTED = 0x01000000,

    // Indicates that the input event is from a trusted source such as a directly attached
    // input device or an application with system-wide event injection permission.
    POLICY_FLAG_TRUSTED = 0x02000000,

    /* These flags are set by the input reader policy as it intercepts each event. */

    // Indicates that the screen was off when the event was received and the event
+2 −3
Original line number Diff line number Diff line
@@ -913,7 +913,6 @@ private:
    void drainInboundQueueLocked();
    void releasePendingEventLocked();
    void releaseInboundEventLocked(EventEntry* entry);
    bool isEventFromTrustedSourceLocked(EventEntry* entry);

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

+30 −33
Original line number Diff line number Diff line
@@ -370,7 +370,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
            }
        }
        done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
                dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
                &dropReason, nextWakeupTime);
        break;
    }

@@ -380,7 +380,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
            dropReason = DROP_REASON_APP_SWITCH;
        }
        done = dispatchMotionLocked(currentTime, typedEntry,
                dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
                &dropReason, nextWakeupTime);
        break;
    }

@@ -431,6 +431,9 @@ void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropR
    const char* reason;
    switch (dropReason) {
    case DROP_REASON_POLICY:
#if DEBUG_INBOUND_EVENT_DETAILS
        LOGD("Dropped event because policy requested that it not be delivered to the application.");
#endif
        reason = "inbound event was dropped because the policy requested that it not be "
                "delivered to the application";
        break;
@@ -473,7 +476,7 @@ bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
            && isAppSwitchKeyCode(keyEntry->keyCode)
            && isEventFromTrustedSourceLocked(keyEntry)
            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
            && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
}

@@ -541,12 +544,6 @@ void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
    mAllocator.releaseEventEntry(entry);
}

bool InputDispatcher::isEventFromTrustedSourceLocked(EventEntry* entry) {
    InjectionState* injectionState = entry->injectionState;
    return ! injectionState
            || hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid);
}

void InputDispatcher::resetKeyRepeatLocked() {
    if (mKeyRepeatState.lastKeyEntry) {
        mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
@@ -559,7 +556,8 @@ InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;

    // Reuse the repeated key entry if it is otherwise unreferenced.
    uint32_t policyFlags = entry->policyFlags & (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER);
    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
    if (entry->refCount == 1) {
        mAllocator.recycleKeyEntry(entry);
        entry->eventTime = currentTime;
@@ -608,19 +606,13 @@ bool InputDispatcher::dispatchConfigurationChangedLocked(

bool InputDispatcher::dispatchKeyLocked(
        nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
        bool dropEvent, nsecs_t* nextWakeupTime) {
        DropReason* dropReason, 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->injectionState);
        } else {
            trusted = isEventFromTrustedSourceLocked(entry);
        }
        if (trusted) {
        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
            CommandEntry* commandEntry = postCommandLocked(
                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
            if (! dropEvent && mFocusedWindow) {
            if (mFocusedWindow) {
                commandEntry->inputChannel = mFocusedWindow->inputChannel;
            }
            commandEntry->keyEntry = entry;
@@ -630,13 +622,16 @@ bool InputDispatcher::dispatchKeyLocked(
            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
        }
    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
        if (*dropReason == DROP_REASON_NOT_DROPPED) {
            *dropReason = DROP_REASON_POLICY;
        }
        resetTargetsLocked();
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
        return true;
    }

    // Clean up if dropping the event.
    if (dropEvent) {
    if (*dropReason != DROP_REASON_NOT_DROPPED) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
        return true;
@@ -648,6 +643,7 @@ bool InputDispatcher::dispatchKeyLocked(

        if (entry->repeatCount == 0
                && entry->action == AKEY_EVENT_ACTION_DOWN
                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
                && !entry->isInjected()) {
            if (mKeyRepeatState.lastKeyEntry
                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
@@ -713,9 +709,9 @@ void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyE
}

bool InputDispatcher::dispatchMotionLocked(
        nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
    // Clean up if dropping the event.
    if (dropEvent) {
    if (*dropReason != DROP_REASON_NOT_DROPPED) {
        resetTargetsLocked();
        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
        return true;
@@ -2085,6 +2081,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t sou
        return;
    }

    policyFlags |= POLICY_FLAG_TRUSTED;
    mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
            keyCode, scanCode, /*byref*/ policyFlags);

@@ -2130,6 +2127,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
        return;
    }

    policyFlags |= POLICY_FLAG_TRUSTED;
    mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);

    bool needWake;
@@ -2263,6 +2261,7 @@ void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t swi
            switchCode, switchValue, policyFlags);
#endif

    policyFlags |= POLICY_FLAG_TRUSTED;
    mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
}

@@ -2275,7 +2274,11 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
#endif

    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
    bool trusted = hasInjectionPermission(injectorPid, injectorUid);

    uint32_t policyFlags = POLICY_FLAG_INJECTED;
    if (hasInjectionPermission(injectorPid, injectorUid)) {
        policyFlags |= POLICY_FLAG_TRUSTED;
    }

    EventEntry* injectedEntry;
    switch (event->getType()) {
@@ -2291,11 +2294,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
        int32_t flags = keyEvent->getFlags();
        int32_t keyCode = keyEvent->getKeyCode();
        int32_t scanCode = keyEvent->getScanCode();
        uint32_t policyFlags = POLICY_FLAG_INJECTED;
        if (trusted) {
        mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
                keyCode, scanCode, /*byref*/ policyFlags);
        }

        mLock.lock();
        injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
@@ -2314,10 +2314,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
        }

        nsecs_t eventTime = motionEvent->getEventTime();
        uint32_t policyFlags = POLICY_FLAG_INJECTED;
        if (trusted) {
        mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
        }

        mLock.lock();
        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();