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

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

Merge changes I15826708,I2738d1a3 into main

* changes:
  InputDispatcher: Establish 1:1 relation between eventId and EventEntry
  Make EventEntry const throughout the Dispatcher pipieline
parents bd9fb126 2a2da1d8
Loading
Loading
Loading
Loading
+7 −28
Original line number Diff line number Diff line
@@ -139,15 +139,15 @@ KeyEntry::KeyEntry(int32_t id, std::shared_ptr<InjectionState> injectionState, n
        source(source),
        displayId(displayId),
        action(action),
        flags(flags),
        keyCode(keyCode),
        scanCode(scanCode),
        metaState(metaState),
        repeatCount(repeatCount),
        downTime(downTime),
        syntheticRepeat(false),
        interceptKeyResult(KeyEntry::InterceptKeyResult::UNKNOWN),
        interceptKeyWakeupTime(0) {
        interceptKeyWakeupTime(0),
        flags(flags),
        repeatCount(repeatCount) {
    EventEntry::injectionState = std::move(injectionState);
}

@@ -276,7 +276,7 @@ std::string SensorEntry::getDescription() const {

volatile int32_t DispatchEntry::sNextSeqAtomic;

DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry,
DispatchEntry::DispatchEntry(std::shared_ptr<const EventEntry> eventEntry,
                             ftl::Flags<InputTarget::Flags> targetFlags,
                             const ui::Transform& transform, const ui::Transform& rawTransform,
                             float globalScaleFactor)
@@ -287,21 +287,15 @@ DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry,
        rawTransform(rawTransform),
        globalScaleFactor(globalScaleFactor),
        deliveryTime(0),
        resolvedAction(0),
        resolvedFlags(0) {
    switch (this->eventEntry->type) {
        case EventEntry::Type::KEY: {
            const KeyEntry& keyEntry = static_cast<KeyEntry&>(*this->eventEntry);
            resolvedEventId = keyEntry.id;
            resolvedAction = keyEntry.action;
            const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*this->eventEntry);
            resolvedFlags = keyEntry.flags;

            break;
        }
        case EventEntry::Type::MOTION: {
            const MotionEntry& motionEntry = static_cast<MotionEntry&>(*this->eventEntry);
            resolvedEventId = motionEntry.id;
            resolvedAction = motionEntry.action;
            const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*this->eventEntry);
            resolvedFlags = motionEntry.flags;
            break;
        }
@@ -321,24 +315,9 @@ uint32_t DispatchEntry::nextSeq() {
}

std::ostream& operator<<(std::ostream& out, const DispatchEntry& entry) {
    out << "DispatchEntry{resolvedAction=";
    switch (entry.eventEntry->type) {
        case EventEntry::Type::KEY: {
            out << KeyEvent::actionToString(entry.resolvedAction);
            break;
        }
        case EventEntry::Type::MOTION: {
            out << MotionEvent::actionToString(entry.resolvedAction);
            break;
        }
        default: {
            out << "<invalid, not a key or a motion>";
            break;
        }
    }
    std::string transform;
    entry.transform.dump(transform, "transform");
    out << ", resolvedFlags=" << entry.resolvedFlags
    out << "DispatchEntry{resolvedFlags=" << entry.resolvedFlags
        << ", targetFlags=" << entry.targetFlags.string() << ", transform=" << transform
        << "} original: " << entry.eventEntry->getDescription();
    return out;
+10 −10
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ struct EventEntry {
    uint32_t policyFlags;
    std::shared_ptr<InjectionState> injectionState;

    bool dispatchInProgress; // initially false, set to true while dispatching
    mutable bool dispatchInProgress; // initially false, set to true while dispatching

    /**
     * Injected keys are events from an external (probably untrusted) application
@@ -72,6 +72,8 @@ struct EventEntry {
    virtual std::string getDescription() const = 0;

    EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
    EventEntry(const EventEntry&) = delete;
    EventEntry& operator=(const EventEntry&) = delete;
    virtual ~EventEntry() = default;
};

@@ -119,11 +121,9 @@ struct KeyEntry : EventEntry {
    uint32_t source;
    int32_t displayId;
    int32_t action;
    int32_t flags;
    int32_t keyCode;
    int32_t scanCode;
    int32_t metaState;
    int32_t repeatCount;
    nsecs_t downTime;

    bool syntheticRepeat; // set to true for synthetic key repeats
@@ -134,8 +134,11 @@ struct KeyEntry : EventEntry {
        CONTINUE,
        TRY_AGAIN_LATER,
    };
    InterceptKeyResult interceptKeyResult; // set based on the interception result
    nsecs_t interceptKeyWakeupTime;        // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
    // These are special fields that may need to be modified while the event is being dispatched.
    mutable InterceptKeyResult interceptKeyResult; // set based on the interception result
    mutable nsecs_t interceptKeyWakeupTime;        // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
    mutable int32_t flags;
    mutable int32_t repeatCount;

    KeyEntry(int32_t id, std::shared_ptr<InjectionState> injectionState, nsecs_t eventTime,
             int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags,
@@ -206,7 +209,7 @@ struct TouchModeEntry : EventEntry {
struct DispatchEntry {
    const uint32_t seq; // unique sequence number, never 0

    std::shared_ptr<EventEntry> eventEntry; // the event to dispatch
    std::shared_ptr<const EventEntry> eventEntry; // the event to dispatch
    const ftl::Flags<InputTarget::Flags> targetFlags;
    ui::Transform transform;
    ui::Transform rawTransform;
@@ -217,12 +220,9 @@ struct DispatchEntry {
    // An ANR will be triggered if a response for this entry is not received by timeoutTime
    nsecs_t timeoutTime;

    // Set to the resolved ID, action and flags when the event is enqueued.
    int32_t resolvedEventId;
    int32_t resolvedAction;
    int32_t resolvedFlags;

    DispatchEntry(std::shared_ptr<EventEntry> eventEntry,
    DispatchEntry(std::shared_ptr<const EventEntry> eventEntry,
                  ftl::Flags<InputTarget::Flags> targetFlags, const ui::Transform& transform,
                  const ui::Transform& rawTransform, float globalScaleFactor);
    DispatchEntry(const DispatchEntry&) = delete;
+154 −139

File changed.

Preview size limit exceeded, changes collapsed.

+27 −25
Original line number Diff line number Diff line
@@ -171,9 +171,9 @@ private:

    sp<Looper> mLooper;

    std::shared_ptr<EventEntry> mPendingEvent GUARDED_BY(mLock);
    std::deque<std::shared_ptr<EventEntry>> mInboundQueue GUARDED_BY(mLock);
    std::deque<std::shared_ptr<EventEntry>> mRecentQueue GUARDED_BY(mLock);
    std::shared_ptr<const EventEntry> mPendingEvent GUARDED_BY(mLock);
    std::deque<std::shared_ptr<const EventEntry>> mInboundQueue GUARDED_BY(mLock);
    std::deque<std::shared_ptr<const EventEntry>> mRecentQueue GUARDED_BY(mLock);

    // A command entry captures state and behavior for an action to be performed in the
    // dispatch loop after the initial processing has taken place.  It is essentially
@@ -223,7 +223,7 @@ private:
            REQUIRES(mLock);

    // Adds an event to a queue of recent events for debugging purposes.
    void addRecentEventLocked(std::shared_ptr<EventEntry> entry) REQUIRES(mLock);
    void addRecentEventLocked(std::shared_ptr<const EventEntry> entry) REQUIRES(mLock);

    // App switch latency optimization.
    bool mAppSwitchSawKeyDown GUARDED_BY(mLock);
@@ -235,7 +235,7 @@ private:

    // Blocked event latency optimization.  Drops old events when the user intends
    // to transfer focus to a new application.
    std::shared_ptr<EventEntry> mNextUnblockedEvent GUARDED_BY(mLock);
    std::shared_ptr<const EventEntry> mNextUnblockedEvent GUARDED_BY(mLock);

    sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked(
            int32_t displayId, float x, float y, bool isStylus = false,
@@ -282,19 +282,19 @@ private:

    // Event injection and synchronization.
    std::condition_variable mInjectionResultAvailable;
    void setInjectionResult(EventEntry& entry,
    void setInjectionResult(const EventEntry& entry,
                            android::os::InputEventInjectionResult injectionResult);
    void transformMotionEntryForInjectionLocked(MotionEntry&,
                                                const ui::Transform& injectedTransform) const
            REQUIRES(mLock);

    std::condition_variable mInjectionSyncFinished;
    void incrementPendingForegroundDispatches(EventEntry& entry);
    void decrementPendingForegroundDispatches(EventEntry& entry);
    void incrementPendingForegroundDispatches(const EventEntry& entry);
    void decrementPendingForegroundDispatches(const EventEntry& entry);

    // Key repeat tracking.
    struct KeyRepeatState {
        std::shared_ptr<KeyEntry> lastKeyEntry; // or null if no repeat
        std::shared_ptr<const KeyEntry> lastKeyEntry; // or null if no repeat
        nsecs_t nextRepeatTime;
    } mKeyRepeatState GUARDED_BY(mLock);

@@ -320,7 +320,7 @@ private:
    // Inbound event processing.
    void drainInboundQueueLocked() REQUIRES(mLock);
    void releasePendingEventLocked() REQUIRES(mLock);
    void releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) REQUIRES(mLock);
    void releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) REQUIRES(mLock);

    // Dispatch state.
    bool mDispatchEnabled GUARDED_BY(mLock);
@@ -431,23 +431,24 @@ private:
                                            const ConfigurationChangedEntry& entry) REQUIRES(mLock);
    bool dispatchDeviceResetLocked(nsecs_t currentTime, const DeviceResetEntry& entry)
            REQUIRES(mLock);
    bool dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
    bool dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
                           DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
    bool dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
    bool dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<const MotionEntry> entry,
                              DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
    void dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry)
    void dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<const FocusEntry> entry)
            REQUIRES(mLock);
    void dispatchPointerCaptureChangedLocked(
            nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
            nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
            DropReason& dropReason) REQUIRES(mLock);
    void dispatchTouchModeChangeLocked(nsecs_t currentTime,
                                       const std::shared_ptr<TouchModeEntry>& entry)
                                       const std::shared_ptr<const TouchModeEntry>& entry)
            REQUIRES(mLock);
    void dispatchEventLocked(nsecs_t currentTime, std::shared_ptr<EventEntry> entry,
    void dispatchEventLocked(nsecs_t currentTime, std::shared_ptr<const EventEntry> entry,
                             const std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
    void dispatchSensorLocked(nsecs_t currentTime, const std::shared_ptr<SensorEntry>& entry,
    void dispatchSensorLocked(nsecs_t currentTime, const std::shared_ptr<const SensorEntry>& entry,
                              DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
    void dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) REQUIRES(mLock);
    void dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<const DragEntry> entry)
            REQUIRES(mLock);
    void logOutboundKeyDetails(const char* prefix, const KeyEntry& entry);
    void logOutboundMotionDetails(const char* prefix, const MotionEntry& entry);

@@ -577,14 +578,15 @@ private:
    // If needed, the methods post commands to run later once the critical bits are done.
    void prepareDispatchCycleLocked(nsecs_t currentTime,
                                    const std::shared_ptr<Connection>& connection,
                                    std::shared_ptr<EventEntry>, const InputTarget& inputTarget)
            REQUIRES(mLock);
                                    std::shared_ptr<const EventEntry>,
                                    const InputTarget& inputTarget) REQUIRES(mLock);
    void enqueueDispatchEntriesLocked(nsecs_t currentTime,
                                      const std::shared_ptr<Connection>& connection,
                                      std::shared_ptr<EventEntry>, const InputTarget& inputTarget)
            REQUIRES(mLock);
                                      std::shared_ptr<const EventEntry>,
                                      const InputTarget& inputTarget) REQUIRES(mLock);
    void enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
                                    std::shared_ptr<EventEntry>, const InputTarget& inputTarget,
                                    std::shared_ptr<const EventEntry>,
                                    const InputTarget& inputTarget,
                                    ftl::Flags<InputTarget::Flags> dispatchMode) REQUIRES(mLock);
    status_t publishMotionEvent(Connection& connection, DispatchEntry& dispatchEntry) const;
    void startDispatchCycleLocked(nsecs_t currentTime,
@@ -646,7 +648,7 @@ private:
                                        const std::shared_ptr<Connection>& connection, uint32_t seq,
                                        bool handled, nsecs_t consumeTime) REQUIRES(mLock);
    void doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
                                                KeyEntry& entry) REQUIRES(mLock);
                                                const KeyEntry& entry) REQUIRES(mLock);
    void onFocusChangedLocked(const FocusResolver::FocusChanges& changes) REQUIRES(mLock);
    void sendFocusChangedCommandLocked(const sp<IBinder>& oldToken, const sp<IBinder>& newToken)
            REQUIRES(mLock);
@@ -661,7 +663,7 @@ private:
            REQUIRES(mLock);
    std::map<int32_t /*displayId*/, InputVerifier> mVerifiersByDisplay;
    // Returns a fallback KeyEntry that should be sent to the connection, if required.
    std::unique_ptr<KeyEntry> afterKeyEventLockedInterruptable(
    std::unique_ptr<const KeyEntry> afterKeyEventLockedInterruptable(
            const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
            const KeyEntry& keyEntry, bool handled) REQUIRES(mLock);

+10 −11
Original line number Diff line number Diff line
@@ -38,8 +38,8 @@ bool InputState::isHovering(DeviceId deviceId, uint32_t source, int32_t displayI
    return false;
}

bool InputState::trackKey(const KeyEntry& entry, int32_t action, int32_t flags) {
    switch (action) {
bool InputState::trackKey(const KeyEntry& entry, int32_t flags) {
    switch (entry.action) {
        case AKEY_EVENT_ACTION_UP: {
            if (entry.flags & AKEY_EVENT_FLAG_FALLBACK) {
                std::erase_if(mFallbackKeys,
@@ -88,7 +88,7 @@ bool InputState::trackKey(const KeyEntry& entry, int32_t action, int32_t flags)
 *  true if the incoming event was correctly tracked,
 *  false if the incoming event should be dropped.
 */
bool InputState::trackMotion(const MotionEntry& entry, int32_t action, int32_t flags) {
bool InputState::trackMotion(const MotionEntry& entry, int32_t flags) {
    // Don't track non-pointer events
    if (!isFromSource(entry.source, AINPUT_SOURCE_CLASS_POINTER)) {
        // This is a focus-dispatched event; we don't track its state.
@@ -104,7 +104,7 @@ bool InputState::trackMotion(const MotionEntry& entry, int32_t action, int32_t f
        }
    }

    int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
    int32_t actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
    switch (actionMasked) {
        case AMOTION_EVENT_ACTION_UP:
        case AMOTION_EVENT_ACTION_CANCEL: {
@@ -281,8 +281,7 @@ size_t InputState::MotionMemento::getPointerCount() const {
    return pointerProperties.size();
}

bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry,
                                            int32_t resolvedAction) const {
bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry) const {
    if (!isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER)) {
        // This is a focus-dispatched event that should not affect the previous stream.
        return false;
@@ -300,7 +299,7 @@ bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry,
    }

    const MotionMemento& lastMemento = mMotionMementos.back();
    const int32_t actionMasked = MotionEvent::getActionMasked(resolvedAction);
    const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);

    // For compatibility, only one input device can be active at a time in the same window.
    if (lastMemento.deviceId == motionEntry.deviceId) {
@@ -369,9 +368,9 @@ bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry,
    return false;
}

std::unique_ptr<EventEntry> InputState::cancelConflictingInputStream(const MotionEntry& motionEntry,
                                                                     int32_t resolvedAction) {
    if (!shouldCancelPreviousStream(motionEntry, resolvedAction)) {
std::unique_ptr<EventEntry> InputState::cancelConflictingInputStream(
        const MotionEntry& motionEntry) {
    if (!shouldCancelPreviousStream(motionEntry)) {
        return {};
    }

@@ -381,7 +380,7 @@ std::unique_ptr<EventEntry> InputState::cancelConflictingInputStream(const Motio
    std::unique_ptr<MotionEntry> cancelEntry =
            createCancelEntryForMemento(memento, motionEntry.eventTime);

    if (!trackMotion(*cancelEntry, cancelEntry->action, cancelEntry->flags)) {
    if (!trackMotion(*cancelEntry, cancelEntry->flags)) {
        LOG(FATAL) << "Generated inconsistent cancel event!";
    }
    return cancelEntry;
Loading