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

Commit a9a7ee88 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Use shared_ptr for EventEntry

Instead of manual refcounting, use std::shared_ptr for EventEntry. This
will make code less error-prone.

We could probably keep unique pointers in mInboundQueue. The only
problem is "mNextUnblockedEvent".

One idea to work around this issue is to prune the queue using event
id's instead. Another idea is to prune the queue right on the spot when
queueing. That might not be OK because it would happen on the
inputreader thread.

Bug: 142581626
Bug: 167946924
Test: presubmit
Change-Id: I6626017180da2d202e2e3acc7a8200107abde3d7
parent ad3b184c
Loading
Loading
Loading
Loading
+4 −20
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry)

EventEntry::EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags)
      : id(id),
        refCount(1),
        type(type),
        eventTime(eventTime),
        policyFlags(policyFlags),
@@ -70,15 +69,6 @@ EventEntry::~EventEntry() {
    releaseInjectionState();
}

void EventEntry::release() {
    refCount -= 1;
    if (refCount == 0) {
        delete this;
    } else {
        ALOG_ASSERT(refCount > 0);
    }
}

void EventEntry::releaseInjectionState() {
    if (injectionState) {
        injectionState->release();
@@ -235,22 +225,16 @@ std::string MotionEntry::getDescription() const {

volatile int32_t DispatchEntry::sNextSeqAtomic;

DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, ui::Transform transform,
                             float globalScaleFactor)
DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
                             ui::Transform transform, float globalScaleFactor)
      : seq(nextSeq()),
        eventEntry(eventEntry),
        eventEntry(std::move(eventEntry)),
        targetFlags(targetFlags),
        transform(transform),
        globalScaleFactor(globalScaleFactor),
        deliveryTime(0),
        resolvedAction(0),
        resolvedFlags(0) {
    eventEntry->refCount += 1;
}

DispatchEntry::~DispatchEntry() {
    eventEntry->release();
}
        resolvedFlags(0) {}

uint32_t DispatchEntry::nextSeq() {
    // Sequence number 0 is reserved and will never be returned.
+6 −14
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ struct EventEntry {
    }

    int32_t id;
    mutable int32_t refCount;
    Type type;
    nsecs_t eventTime;
    uint32_t policyFlags;
@@ -79,13 +78,12 @@ struct EventEntry {
        return isInjected() || IdGenerator::getSource(id) != IdGenerator::Source::INPUT_READER;
    }

    void release();

    virtual std::string getDescription() const = 0;

protected:
    EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
    virtual ~EventEntry();

protected:
    void releaseInjectionState();
};

@@ -93,7 +91,6 @@ struct ConfigurationChangedEntry : EventEntry {
    explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
    std::string getDescription() const override;

protected:
    virtual ~ConfigurationChangedEntry();
};

@@ -103,7 +100,6 @@ struct DeviceResetEntry : EventEntry {
    DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId);
    std::string getDescription() const override;

protected:
    virtual ~DeviceResetEntry();
};

@@ -116,7 +112,6 @@ struct FocusEntry : EventEntry {
               std::string_view reason);
    std::string getDescription() const override;

protected:
    virtual ~FocusEntry();
};

@@ -149,7 +144,6 @@ struct KeyEntry : EventEntry {
    std::string getDescription() const override;
    void recycle();

protected:
    virtual ~KeyEntry();
};

@@ -182,7 +176,6 @@ struct MotionEntry : EventEntry {
                float xOffset, float yOffset);
    std::string getDescription() const override;

protected:
    virtual ~MotionEntry();
};

@@ -190,7 +183,7 @@ protected:
struct DispatchEntry {
    const uint32_t seq; // unique sequence number, never 0

    EventEntry* eventEntry; // the event to dispatch
    std::shared_ptr<EventEntry> eventEntry; // the event to dispatch
    int32_t targetFlags;
    ui::Transform transform;
    float globalScaleFactor;
@@ -205,9 +198,8 @@ struct DispatchEntry {
    int32_t resolvedAction;
    int32_t resolvedFlags;

    DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, ui::Transform transform,
                  float globalScaleFactor);
    ~DispatchEntry();
    DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
                  ui::Transform transform, float globalScaleFactor);

    inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }

@@ -252,7 +244,7 @@ struct CommandEntry {
    // parameters for the command (usage varies by command)
    sp<Connection> connection;
    nsecs_t eventTime;
    KeyEntry* keyEntry;
    std::shared_ptr<KeyEntry> keyEntry;
    std::shared_ptr<InputApplicationHandle> inputApplicationHandle;
    std::string reason;
    int32_t userActivityEventType;
+271 −275

File changed.

Preview size limit exceeded, changes collapsed.

+29 −26
Original line number Diff line number Diff line
@@ -158,9 +158,9 @@ private:

    sp<Looper> mLooper;

    EventEntry* mPendingEvent GUARDED_BY(mLock);
    std::deque<EventEntry*> mInboundQueue GUARDED_BY(mLock);
    std::deque<EventEntry*> mRecentQueue GUARDED_BY(mLock);
    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::deque<std::unique_ptr<CommandEntry>> mCommandQueue GUARDED_BY(mLock);

    DropReason mLastDropReason GUARDED_BY(mLock);
@@ -175,7 +175,7 @@ private:
    void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) REQUIRES(mLock);

    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
    bool enqueueInboundEventLocked(EventEntry* entry) REQUIRES(mLock);
    bool enqueueInboundEventLocked(std::unique_ptr<EventEntry> entry) REQUIRES(mLock);

    // Cleans up input state when dropping an inbound event.
    void dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) REQUIRES(mLock);
@@ -185,7 +185,7 @@ private:
                                 std::string_view reason) REQUIRES(mLock);

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

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

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

    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y,
                                                    TouchState* touchState,
@@ -242,21 +242,21 @@ private:
    // Event injection and synchronization.
    std::condition_variable mInjectionResultAvailable;
    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
    void setInjectionResult(EventEntry* entry,
    void setInjectionResult(EventEntry& entry,
                            android::os::InputEventInjectionResult injectionResult);

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

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

    void resetKeyRepeatLocked() REQUIRES(mLock);
    KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime) REQUIRES(mLock);
    std::shared_ptr<KeyEntry> synthesizeKeyRepeatLocked(nsecs_t currentTime) REQUIRES(mLock);

    // Key replacement tracking
    struct KeyReplacement {
@@ -292,7 +292,7 @@ private:
    // Inbound event processing.
    void drainInboundQueueLocked() REQUIRES(mLock);
    void releasePendingEventLocked() REQUIRES(mLock);
    void releaseInboundEventLocked(EventEntry* entry) REQUIRES(mLock);
    void releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) REQUIRES(mLock);

    // Dispatch state.
    bool mDispatchEnabled GUARDED_BY(mLock);
@@ -356,15 +356,17 @@ private:
                                       const std::vector<InputTarget>& targets) REQUIRES(mLock);

    // Dispatch inbound events.
    bool dispatchConfigurationChangedLocked(nsecs_t currentTime, ConfigurationChangedEntry* entry)
    bool dispatchConfigurationChangedLocked(nsecs_t currentTime,
                                            const ConfigurationChangedEntry& entry) REQUIRES(mLock);
    bool dispatchDeviceResetLocked(nsecs_t currentTime, const DeviceResetEntry& entry)
            REQUIRES(mLock);
    bool dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) REQUIRES(mLock);
    bool dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry, DropReason* dropReason,
                           nsecs_t* nextWakeupTime) REQUIRES(mLock);
    bool dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason,
                              nsecs_t* nextWakeupTime) REQUIRES(mLock);
    void dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) REQUIRES(mLock);
    void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
    bool dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
                           DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
    bool dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
                              DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
    void dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry)
            REQUIRES(mLock);
    void dispatchEventLocked(nsecs_t currentTime, std::shared_ptr<EventEntry> entry,
                             const std::vector<InputTarget>& inputTargets) REQUIRES(mLock);

    void logOutboundKeyDetails(const char* prefix, const KeyEntry& entry);
@@ -478,12 +480,12 @@ private:
    // with the mutex held makes it easier to ensure that connection invariants are maintained.
    // If needed, the methods post commands to run later once the critical bits are done.
    void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
                                    EventEntry* eventEntry, const InputTarget& inputTarget)
                                    std::shared_ptr<EventEntry>, const InputTarget& inputTarget)
            REQUIRES(mLock);
    void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
                                      EventEntry* eventEntry, const InputTarget& inputTarget)
                                      std::shared_ptr<EventEntry>, const InputTarget& inputTarget)
            REQUIRES(mLock);
    void enqueueDispatchEntryLocked(const sp<Connection>& connection, EventEntry* eventEntry,
    void enqueueDispatchEntryLocked(const sp<Connection>& connection, std::shared_ptr<EventEntry>,
                                    const InputTarget& inputTarget, int32_t dispatchMode)
            REQUIRES(mLock);
    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection)
@@ -517,7 +519,8 @@ private:
            REQUIRES(mLock);

    // Splitting motion events across windows.
    MotionEntry* splitMotionEvent(const MotionEntry& originalMotionEntry, BitSet32 pointerIds);
    std::unique_ptr<MotionEntry> splitMotionEvent(const MotionEntry& originalMotionEntry,
                                                  BitSet32 pointerIds);

    // Reset and drop everything the dispatcher is doing.
    void resetAndDropEverythingLocked(const char* reason) REQUIRES(mLock);
@@ -564,10 +567,10 @@ private:
            REQUIRES(mLock);
    void doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    bool afterKeyEventLockedInterruptible(const sp<Connection>& connection,
                                          DispatchEntry* dispatchEntry, KeyEntry* keyEntry,
                                          DispatchEntry* dispatchEntry, KeyEntry& keyEntry,
                                          bool handled) REQUIRES(mLock);
    bool afterMotionEventLockedInterruptible(const sp<Connection>& connection,
                                             DispatchEntry* dispatchEntry, MotionEntry* motionEntry,
                                             DispatchEntry* dispatchEntry, MotionEntry& motionEntry,
                                             bool handled) REQUIRES(mLock);
    void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    KeyEvent createKeyEvent(const KeyEntry& entry);
+35 −28
Original line number Diff line number Diff line
@@ -265,17 +265,18 @@ void InputState::MotionMemento::mergePointerStateTo(MotionMemento& other) const
    }
}

std::vector<EventEntry*> InputState::synthesizeCancelationEvents(
std::vector<std::unique_ptr<EventEntry>> InputState::synthesizeCancelationEvents(
        nsecs_t currentTime, const CancelationOptions& options) {
    std::vector<EventEntry*> events;
    std::vector<std::unique_ptr<EventEntry>> events;
    for (KeyMemento& memento : mKeyMementos) {
        if (shouldCancelKey(memento, options)) {
            events.push_back(new KeyEntry(mIdGenerator.nextId(), currentTime, memento.deviceId,
                                          memento.source, memento.displayId, memento.policyFlags,
                                          AKEY_EVENT_ACTION_UP,
                                          memento.flags | AKEY_EVENT_FLAG_CANCELED, memento.keyCode,
                                          memento.scanCode, memento.metaState, 0 /*repeatCount*/,
                                          memento.downTime));
            events.push_back(
                    std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId,
                                               memento.source, memento.displayId,
                                               memento.policyFlags, AKEY_EVENT_ACTION_UP,
                                               memento.flags | AKEY_EVENT_FLAG_CANCELED,
                                               memento.keyCode, memento.scanCode, memento.metaState,
                                               0 /*repeatCount*/, memento.downTime));
        }
    }

@@ -283,22 +284,26 @@ std::vector<EventEntry*> InputState::synthesizeCancelationEvents(
        if (shouldCancelMotion(memento, options)) {
            const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT
                                                    : AMOTION_EVENT_ACTION_CANCEL;
            events.push_back(new MotionEntry(mIdGenerator.nextId(), currentTime, memento.deviceId,
                                             memento.source, memento.displayId, memento.policyFlags,
                                             action, 0 /*actionButton*/, memento.flags, AMETA_NONE,
            events.push_back(
                    std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
                                                  memento.deviceId, memento.source,
                                                  memento.displayId, memento.policyFlags, action,
                                                  0 /*actionButton*/, memento.flags, AMETA_NONE,
                                                  0 /*buttonState*/, MotionClassification::NONE,
                                                  AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                                  memento.yPrecision, memento.xCursorPosition,
                                                  memento.yCursorPosition, memento.downTime,
                                                  memento.pointerCount, memento.pointerProperties,
                                             memento.pointerCoords, 0 /*xOffset*/, 0 /*yOffset*/));
                                                  memento.pointerCoords, 0 /*xOffset*/,
                                                  0 /*yOffset*/));
        }
    }
    return events;
}

std::vector<EventEntry*> InputState::synthesizePointerDownEvents(nsecs_t currentTime) {
    std::vector<EventEntry*> events;
std::vector<std::unique_ptr<EventEntry>> InputState::synthesizePointerDownEvents(
        nsecs_t currentTime) {
    std::vector<std::unique_ptr<EventEntry>> events;
    for (MotionMemento& memento : mMotionMementos) {
        if (!(memento.source & AINPUT_SOURCE_CLASS_POINTER)) {
            continue;
@@ -333,9 +338,11 @@ std::vector<EventEntry*> InputState::synthesizePointerDownEvents(nsecs_t current
                    : AMOTION_EVENT_ACTION_POINTER_DOWN
                            | (i << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

            events.push_back(new MotionEntry(mIdGenerator.nextId(), currentTime, memento.deviceId,
                                             memento.source, memento.displayId, memento.policyFlags,
                                             action, 0 /*actionButton*/, memento.flags, AMETA_NONE,
            events.push_back(
                    std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
                                                  memento.deviceId, memento.source,
                                                  memento.displayId, memento.policyFlags, action,
                                                  0 /*actionButton*/, memento.flags, AMETA_NONE,
                                                  0 /*buttonState*/, MotionClassification::NONE,
                                                  AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                                  memento.yPrecision, memento.xCursorPosition,
Loading