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

Commit 820a542d authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge "Change input injection security model to require INJECT_EVENTS permission" into tm-dev

parents 33bef8d9 985a1b2d
Loading
Loading
Loading
Loading
+2 −3
Original line number Original line Diff line number Diff line
@@ -29,9 +29,8 @@ enum InputEventInjectionResult {
    /* Injection succeeded. */
    /* Injection succeeded. */
    SUCCEEDED = 0,
    SUCCEEDED = 0,


    /* Injection failed because the injector did not have permission to inject
    /* Injection failed because the injected event did not target the appropriate window. */
     * into the application with input focus. */
    TARGET_MISMATCH = 1,
    PERMISSION_DENIED = 1,


    /* Injection failed because there were no available input targets. */
    /* Injection failed because there were no available input targets. */
    FAILED = 2,
    FAILED = 2,
+10 −12
Original line number Original line Diff line number Diff line
@@ -31,11 +31,11 @@ using android::os::InputEventInjectionSync;
namespace android::inputdispatcher {
namespace android::inputdispatcher {


// An arbitrary device id.
// An arbitrary device id.
static const int32_t DEVICE_ID = 1;
constexpr int32_t DEVICE_ID = 1;


// An arbitrary injector pid / uid pair that has permission to inject events.
// The default pid and uid for windows created by the test.
static const int32_t INJECTOR_PID = 999;
constexpr int32_t WINDOW_PID = 999;
static const int32_t INJECTOR_UID = 1001;
constexpr int32_t WINDOW_UID = 1001;


static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 5s;
static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 5s;
static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 100ms;
static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 100ms;
@@ -108,8 +108,6 @@ private:


    void pokeUserActivity(nsecs_t, int32_t, int32_t) override {}
    void pokeUserActivity(nsecs_t, int32_t, int32_t) override {}


    bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override { return false; }

    void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {}
    void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {}


    void setPointerCapture(const PointerCaptureRequest&) override {}
    void setPointerCapture(const PointerCaptureRequest&) override {}
@@ -196,8 +194,8 @@ public:
        mInfo.globalScaleFactor = 1.0;
        mInfo.globalScaleFactor = 1.0;
        mInfo.touchableRegion.clear();
        mInfo.touchableRegion.clear();
        mInfo.addTouchableRegion(mFrame);
        mInfo.addTouchableRegion(mFrame);
        mInfo.ownerPid = INJECTOR_PID;
        mInfo.ownerPid = WINDOW_PID;
        mInfo.ownerUid = INJECTOR_UID;
        mInfo.ownerUid = WINDOW_UID;
        mInfo.displayId = ADISPLAY_ID_DEFAULT;
        mInfo.displayId = ADISPLAY_ID_DEFAULT;
    }
    }


@@ -310,14 +308,14 @@ static void benchmarkInjectMotion(benchmark::State& state) {
    for (auto _ : state) {
    for (auto _ : state) {
        MotionEvent event = generateMotionEvent();
        MotionEvent event = generateMotionEvent();
        // Send ACTION_DOWN
        // Send ACTION_DOWN
        dispatcher.injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
        dispatcher.injectInputEvent(&event, {} /*targetUid*/, InputEventInjectionSync::NONE,
                                    InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
                                    INJECT_EVENT_TIMEOUT,
                                    POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
                                    POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);


        // Send ACTION_UP
        // Send ACTION_UP
        event.setAction(AMOTION_EVENT_ACTION_UP);
        event.setAction(AMOTION_EVENT_ACTION_UP);
        dispatcher.injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
        dispatcher.injectInputEvent(&event, {} /*targetUid*/, InputEventInjectionSync::NONE,
                                    InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
                                    INJECT_EVENT_TIMEOUT,
                                    POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
                                    POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);


        window->consumeEvent();
        window->consumeEvent();
+2 −3
Original line number Original line Diff line number Diff line
@@ -20,10 +20,9 @@


namespace android::inputdispatcher {
namespace android::inputdispatcher {


InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid)
InjectionState::InjectionState(const std::optional<int32_t>& targetUid)
      : refCount(1),
      : refCount(1),
        injectorPid(injectorPid),
        targetUid(targetUid),
        injectorUid(injectorUid),
        injectionResult(android::os::InputEventInjectionResult::PENDING),
        injectionResult(android::os::InputEventInjectionResult::PENDING),
        injectionIsAsync(false),
        injectionIsAsync(false),
        pendingForegroundDispatches(0) {}
        pendingForegroundDispatches(0) {}
+2 −3
Original line number Original line Diff line number Diff line
@@ -27,13 +27,12 @@ namespace inputdispatcher {
struct InjectionState {
struct InjectionState {
    mutable int32_t refCount;
    mutable int32_t refCount;


    int32_t injectorPid;
    std::optional<int32_t> targetUid;
    int32_t injectorUid;
    android::os::InputEventInjectionResult injectionResult; // initially PENDING
    android::os::InputEventInjectionResult injectionResult; // initially PENDING
    bool injectionIsAsync;               // set to true if injection is not waiting for the result
    bool injectionIsAsync;               // set to true if injection is not waiting for the result
    int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
    int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress


    InjectionState(int32_t injectorPid, int32_t injectorUid);
    explicit InjectionState(const std::optional<int32_t>& targetUid);
    void release();
    void release();


private:
private:
+87 −81
Original line number Original line Diff line number Diff line
@@ -578,6 +578,27 @@ bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, int32_t pid, int3
    return false;
    return false;
}
}


// Checks targeted injection using the window's owner's uid.
// Returns an empty string if an entry can be sent to the given window, or an error message if the
// entry is a targeted injection whose uid target doesn't match the window owner.
std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
                                                   const EventEntry& entry) {
    if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
        // The event was not injected, or the injected event does not target a window.
        return {};
    }
    const int32_t uid = *entry.injectionState->targetUid;
    if (window == nullptr) {
        return StringPrintf("No valid window target for injection into uid %d.", uid);
    }
    if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
        return StringPrintf("Injected event targeted at uid %d would be dispatched to window '%s' "
                            "owned by uid %d.",
                            uid, window->getName().c_str(), window->getInfo()->ownerUid);
    }
    return {};
}

} // namespace
} // namespace


// --- InputDispatcher ---
// --- InputDispatcher ---
@@ -1036,6 +1057,8 @@ bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newE


    switch (entry.type) {
    switch (entry.type) {
        case EventEntry::Type::KEY: {
        case EventEntry::Type::KEY: {
            LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
                                "Unexpected untrusted event.");
            // Optimize app switch latency.
            // Optimize app switch latency.
            // If the application takes too long to catch up then we drop all events preceding
            // If the application takes too long to catch up then we drop all events preceding
            // the app switch key.
            // the app switch key.
@@ -1073,6 +1096,8 @@ bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newE
        }
        }


        case EventEntry::Type::MOTION: {
        case EventEntry::Type::MOTION: {
            LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
                                "Unexpected untrusted event.");
            if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
            if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
                mNextUnblockedEvent = mInboundQueue.back();
                mNextUnblockedEvent = mInboundQueue.back();
                needWake = true;
                needWake = true;
@@ -1718,8 +1743,7 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<
    }
    }


    setInjectionResult(*entry, injectionResult);
    setInjectionResult(*entry, injectionResult);
    if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
    if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
        ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
        return true;
        return true;
    }
    }
    if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
    if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
@@ -1976,9 +2000,10 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
    // we have a valid, non-null focused window
    // we have a valid, non-null focused window
    resetNoFocusedWindowTimeoutLocked();
    resetNoFocusedWindowTimeoutLocked();


    // Check permissions.
    // Verify targeted injection.
    if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
    if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
        return InputEventInjectionResult::PERMISSION_DENIED;
        ALOGW("Dropping injected event: %s", (*err).c_str());
        return InputEventInjectionResult::TARGET_MISMATCH;
    }
    }


    if (focusedWindowHandle->getInfo()->inputConfig.test(
    if (focusedWindowHandle->getInfo()->inputConfig.test(
@@ -2044,11 +2069,6 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
        nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
        nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
        nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
        nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
    ATRACE_CALL();
    ATRACE_CALL();
    enum InjectionPermission {
        INJECTION_PERMISSION_UNKNOWN,
        INJECTION_PERMISSION_GRANTED,
        INJECTION_PERMISSION_DENIED
    };


    // For security reasons, we defer updating the touch state until we are sure that
    // For security reasons, we defer updating the touch state until we are sure that
    // event injection will be allowed.
    // event injection will be allowed.
@@ -2058,7 +2078,6 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(


    // Update the touch state as needed based on the properties of the touch event.
    // Update the touch state as needed based on the properties of the touch event.
    InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
    InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
    InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
    sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
    sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
    sp<WindowInfoHandle> newTouchedWindowHandle;
    sp<WindowInfoHandle> newTouchedWindowHandle;


@@ -2107,7 +2126,7 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
              "in display %" PRId32,
              "in display %" PRId32,
              displayId);
              displayId);
        // TODO: test multiple simultaneous input streams.
        // TODO: test multiple simultaneous input streams.
        injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
        injectionResult = InputEventInjectionResult::FAILED;
        switchedDevice = false;
        switchedDevice = false;
        wrongDevice = true;
        wrongDevice = true;
        goto Failed;
        goto Failed;
@@ -2140,6 +2159,14 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
            newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
            newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
        }
        }


        // Verify targeted injection.
        if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
            ALOGW("Dropping injected touch event: %s", (*err).c_str());
            injectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
            newTouchedWindowHandle = nullptr;
            goto Failed;
        }

        // Figure out whether splitting will be allowed for this window.
        // Figure out whether splitting will be allowed for this window.
        if (newTouchedWindowHandle != nullptr) {
        if (newTouchedWindowHandle != nullptr) {
            if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
            if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
@@ -2183,6 +2210,11 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
        for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
        for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
            const WindowInfo& info = *windowHandle->getInfo();
            const WindowInfo& info = *windowHandle->getInfo();


            // Skip spy window targets that are not valid for targeted injection.
            if (const auto err = verifyTargetedInjection(windowHandle, entry); err) {
                continue;
            }

            if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
            if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
                ALOGI("Not sending touch event to %s because it is paused",
                ALOGI("Not sending touch event to %s because it is paused",
                      windowHandle->getName().c_str());
                      windowHandle->getName().c_str());
@@ -2276,6 +2308,14 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
            newTouchedWindowHandle =
            newTouchedWindowHandle =
                    findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
                    findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);


            // Verify targeted injection.
            if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
                ALOGW("Dropping injected event: %s", (*err).c_str());
                injectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
                newTouchedWindowHandle = nullptr;
                goto Failed;
            }

            // Drop touch events if requested by input feature
            // Drop touch events if requested by input feature
            if (newTouchedWindowHandle != nullptr &&
            if (newTouchedWindowHandle != nullptr &&
                shouldDropInput(entry, newTouchedWindowHandle)) {
                shouldDropInput(entry, newTouchedWindowHandle)) {
@@ -2367,19 +2407,26 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
        goto Failed;
        goto Failed;
    }
    }


    // Check permission to inject into all touched foreground windows.
    // Ensure that all touched windows are valid for injection.
    if (std::any_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
    if (entry.injectionState != nullptr) {
                    [this, &entry](const TouchedWindow& touchedWindow) {
        std::string errs;
                        return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 &&
        for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
                                !checkInjectionPermission(touchedWindow.windowHandle,
            if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
                                                          entry.injectionState);
                // Allow ACTION_OUTSIDE events generated by targeted injection to be
                    })) {
                // dispatched to any uid, since the coords will be zeroed out later.
        injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
                continue;
        injectionPermission = INJECTION_PERMISSION_DENIED;
            }
            const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
            if (err) errs += "\n  - " + *err;
        }
        if (!errs.empty()) {
            ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
                  "%d:%s",
                  *entry.injectionState->targetUid, errs.c_str());
            injectionResult = InputEventInjectionResult::TARGET_MISMATCH;
            goto Failed;
            goto Failed;
        }
        }
    // Permission granted to inject into all touched foreground windows.
    }
    injectionPermission = INJECTION_PERMISSION_GRANTED;


    // Check whether windows listening for outside touches are owned by the same UID. If it is
    // Check whether windows listening for outside touches are owned by the same UID. If it is
    // set the policy flag that we will not reveal coordinate information to this window.
    // set the policy flag that we will not reveal coordinate information to this window.
@@ -2445,19 +2492,6 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
    tempTouchState.filterNonAsIsTouchWindows();
    tempTouchState.filterNonAsIsTouchWindows();


Failed:
Failed:
    // Check injection permission once and for all.
    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
        if (checkInjectionPermission(nullptr, entry.injectionState)) {
            injectionPermission = INJECTION_PERMISSION_GRANTED;
        } else {
            injectionPermission = INJECTION_PERMISSION_DENIED;
        }
    }

    if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
        return injectionResult;
    }

    // Update final pieces of touch state if the injector had permission.
    // Update final pieces of touch state if the injector had permission.
    if (!wrongDevice) {
    if (!wrongDevice) {
        if (switchedDevice) {
        if (switchedDevice) {
@@ -2655,26 +2689,6 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>&
    }
    }
}
}


bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
                                               const InjectionState* injectionState) {
    if (injectionState &&
        (windowHandle == nullptr ||
         windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
        !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
        if (windowHandle != nullptr) {
            ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
                  "owned by uid %d",
                  injectionState->injectorPid, injectionState->injectorUid,
                  windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
        } else {
            ALOGW("Permission denied: injecting event from pid %d uid %d",
                  injectionState->injectorPid, injectionState->injectorUid);
        }
        return false;
    }
    return true;
}

/**
/**
 * Indicate whether one window handle should be considered as obscuring
 * Indicate whether one window handle should be considered as obscuring
 * another window handle. We only check a few preconditions. Actually
 * another window handle. We only check a few preconditions. Actually
@@ -4193,20 +4207,20 @@ void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChan
    }
    }
}
}


InputEventInjectionResult InputDispatcher::injectInputEvent(
InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
        const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
                                                            std::optional<int32_t> targetUid,
        InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
                                                            InputEventInjectionSync syncMode,
                                                            std::chrono::milliseconds timeout,
                                                            uint32_t policyFlags) {
    if (DEBUG_INBOUND_EVENT_DETAILS) {
    if (DEBUG_INBOUND_EVENT_DETAILS) {
        ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
        ALOGD("injectInputEvent - eventType=%d, targetUid=%s, syncMode=%d, timeout=%lld, "
              "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
              "policyFlags=0x%08x",
              event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
              event->getType(), targetUid ? std::to_string(*targetUid).c_str() : "none", syncMode,
              timeout.count(), policyFlags);
    }
    }
    nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
    nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();


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


    // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
    // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
    // that have gone through the InputFilter. If the event passed through the InputFilter, assign
    // that have gone through the InputFilter. If the event passed through the InputFilter, assign
@@ -4347,7 +4361,7 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(
            return InputEventInjectionResult::FAILED;
            return InputEventInjectionResult::FAILED;
    }
    }


    InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
    InjectionState* injectionState = new InjectionState(targetUid);
    if (syncMode == InputEventInjectionSync::NONE) {
    if (syncMode == InputEventInjectionSync::NONE) {
        injectionState->injectionIsAsync = true;
        injectionState->injectionIsAsync = true;
    }
    }
@@ -4419,8 +4433,7 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(
    } // release lock
    } // release lock


    if (DEBUG_INJECTION) {
    if (DEBUG_INJECTION) {
        ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
        ALOGD("injectInputEvent - Finished with result %d.", injectionResult);
              injectionResult, injectorPid, injectorUid);
    }
    }


    return injectionResult;
    return injectionResult;
@@ -4459,19 +4472,12 @@ std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const Inpu
    return result;
    return result;
}
}


bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
    return injectorUid == 0 ||
            mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
}

void InputDispatcher::setInjectionResult(EventEntry& entry,
void InputDispatcher::setInjectionResult(EventEntry& entry,
                                         InputEventInjectionResult injectionResult) {
                                         InputEventInjectionResult injectionResult) {
    InjectionState* injectionState = entry.injectionState;
    InjectionState* injectionState = entry.injectionState;
    if (injectionState) {
    if (injectionState) {
        if (DEBUG_INJECTION) {
        if (DEBUG_INJECTION) {
            ALOGD("Setting input event injection result to %d.  "
            ALOGD("Setting input event injection result to %d.", injectionResult);
                  "injectorPid=%d, injectorUid=%d",
                  injectionResult, injectionState->injectorPid, injectionState->injectorUid);
        }
        }


        if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
        if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
@@ -4480,12 +4486,12 @@ void InputDispatcher::setInjectionResult(EventEntry& entry,
                case InputEventInjectionResult::SUCCEEDED:
                case InputEventInjectionResult::SUCCEEDED:
                    ALOGV("Asynchronous input event injection succeeded.");
                    ALOGV("Asynchronous input event injection succeeded.");
                    break;
                    break;
                case InputEventInjectionResult::TARGET_MISMATCH:
                    ALOGV("Asynchronous input event injection target mismatch.");
                    break;
                case InputEventInjectionResult::FAILED:
                case InputEventInjectionResult::FAILED:
                    ALOGW("Asynchronous input event injection failed.");
                    ALOGW("Asynchronous input event injection failed.");
                    break;
                    break;
                case InputEventInjectionResult::PERMISSION_DENIED:
                    ALOGW("Asynchronous input event injection permission denied.");
                    break;
                case InputEventInjectionResult::TIMED_OUT:
                case InputEventInjectionResult::TIMED_OUT:
                    ALOGW("Asynchronous input event injection timed out.");
                    ALOGW("Asynchronous input event injection timed out.");
                    break;
                    break;
Loading