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

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

Merge "Use std::unique_ptr for DispatchEntry" into main

parents da055715 8c90d78b
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -38,13 +38,4 @@ const std::string Connection::getWindowName() const {
    return "?";
}

std::deque<DispatchEntry*>::iterator Connection::findWaitQueueEntry(uint32_t seq) {
    for (std::deque<DispatchEntry*>::iterator it = waitQueue.begin(); it != waitQueue.end(); it++) {
        if ((*it)->seq == seq) {
            return it;
        }
    }
    return waitQueue.end();
}

} // namespace android::inputdispatcher
+2 −4
Original line number Diff line number Diff line
@@ -53,11 +53,11 @@ public:
    bool responsive = true;

    // Queue of events that need to be published to the connection.
    std::deque<DispatchEntry*> outboundQueue;
    std::deque<std::unique_ptr<DispatchEntry>> outboundQueue;

    // Queue of events that have been published to the connection but that have not
    // yet received a "finished" response from the application.
    std::deque<DispatchEntry*> waitQueue;
    std::deque<std::unique_ptr<DispatchEntry>> waitQueue;

    Connection(const std::shared_ptr<InputChannel>& inputChannel, bool monitor,
               const IdGenerator& idGenerator);
@@ -65,8 +65,6 @@ public:
    inline const std::string getInputChannelName() const { return inputChannel->getName(); }

    const std::string getWindowName() const;

    std::deque<DispatchEntry*>::iterator findWaitQueueEntry(uint32_t seq);
};

} // namespace android::inputdispatcher
+3 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ struct DispatchEntry {
    const uint32_t seq; // unique sequence number, never 0

    std::shared_ptr<EventEntry> eventEntry; // the event to dispatch
    ftl::Flags<InputTarget::Flags> targetFlags;
    const ftl::Flags<InputTarget::Flags> targetFlags;
    ui::Transform transform;
    ui::Transform rawTransform;
    float globalScaleFactor;
@@ -244,6 +244,8 @@ struct DispatchEntry {
    DispatchEntry(std::shared_ptr<EventEntry> eventEntry,
                  ftl::Flags<InputTarget::Flags> targetFlags, const ui::Transform& transform,
                  const ui::Transform& rawTransform, float globalScaleFactor);
    DispatchEntry(const DispatchEntry&) = delete;
    DispatchEntry& operator=(const DispatchEntry&) = delete;

    inline bool hasForegroundTarget() const {
        return targetFlags.test(InputTarget::Flags::FOREGROUND);
+61 −55
Original line number Diff line number Diff line
@@ -271,7 +271,8 @@ std::string dumpRegion(const Region& region) {
    return dump;
}

std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
                      nsecs_t currentTime) {
    constexpr size_t maxEntries = 50; // max events to print
    constexpr size_t skipBegin = maxEntries / 2;
    const size_t skipEnd = queue.size() - maxEntries / 2;
@@ -492,8 +493,8 @@ bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connect
 */
bool isConnectionResponsive(const Connection& connection) {
    const nsecs_t currentTime = now();
    for (const DispatchEntry* entry : connection.waitQueue) {
        if (entry->timeoutTime < currentTime) {
    for (const auto& dispatchEntry : connection.waitQueue) {
        if (dispatchEntry->timeoutTime < currentTime) {
            return false;
        }
    }
@@ -3415,7 +3416,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio
    }

    // Enqueue the dispatch entry.
    connection->outboundQueue.push_back(dispatchEntry.release());
    connection->outboundQueue.emplace_back(std::move(dispatchEntry));
    traceOutboundQueueLength(*connection);
}

@@ -3584,7 +3585,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
    }

    while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
        DispatchEntry* dispatchEntry = connection->outboundQueue.front();
        std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
        dispatchEntry->deliveryTime = currentTime;
        const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
        dispatchEntry->timeoutTime = currentTime + timeout.count();
@@ -3699,14 +3700,12 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
        }

        // Re-enqueue the event on the wait queue.
        connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
                                                    connection->outboundQueue.end(),
                                                    dispatchEntry));
        const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
        connection->waitQueue.emplace_back(std::move(dispatchEntry));
        connection->outboundQueue.erase(connection->outboundQueue.begin());
        traceOutboundQueueLength(*connection);
        connection->waitQueue.push_back(dispatchEntry);
        if (connection->responsive) {
            mAnrTracker.insert(dispatchEntry->timeoutTime,
                               connection->inputChannel->getConnectionToken());
            mAnrTracker.insert(timeoutTime, connection->inputChannel->getConnectionToken());
        }
        traceWaitQueueLength(*connection);
    }
@@ -3805,19 +3804,17 @@ void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
    }
}

void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
    while (!queue.empty()) {
        DispatchEntry* dispatchEntry = queue.front();
        releaseDispatchEntry(std::move(queue.front()));
        queue.pop_front();
        releaseDispatchEntry(dispatchEntry);
    }
}

void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
    if (dispatchEntry->hasForegroundTarget()) {
        decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
    }
    delete dispatchEntry;
}

int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
@@ -6065,43 +6062,52 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
                                                     uint32_t seq, bool handled,
                                                     nsecs_t consumeTime) {
    // Handle post-event policy actions.
    std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
    bool restartEvent;

    { // Start critical section
        auto dispatchEntryIt =
                std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
                             [seq](auto& e) { return e->seq == seq; });
        if (dispatchEntryIt == connection->waitQueue.end()) {
            return;
        }
    DispatchEntry* dispatchEntry = *dispatchEntryIt;
    const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;

        DispatchEntry& dispatchEntry = **dispatchEntryIt;

        const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
        if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
            ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
              ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
                  ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
        }
    if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
        mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
        if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
            mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
                                               connection->inputChannel->getConnectionToken(),
                                           dispatchEntry->deliveryTime, consumeTime, finishTime);
                                               dispatchEntry.deliveryTime, consumeTime, finishTime);
        }

    bool restartEvent;
    if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
        KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
        if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
            KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry.eventEntry));
            restartEvent =
                    afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
    } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
        MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
        restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
                                                           handled);
        } else if (dispatchEntry.eventEntry->type == EventEntry::Type::MOTION) {
            MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry.eventEntry));
            restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry,
                                                               motionEntry, handled);
        } else {
            restartEvent = false;
        }
    } // End critical section: The -LockedInterruptable methods may have released the lock.

    // Dequeue the event and start the next cycle.
    // Because the lock might have been released, it is possible that the
    // contents of the wait queue to have been drained, so we need to double-check
    // a few things.
    dispatchEntryIt = connection->findWaitQueueEntry(seq);
    if (dispatchEntryIt != connection->waitQueue.end()) {
        dispatchEntry = *dispatchEntryIt;
        connection->waitQueue.erase(dispatchEntryIt);
    auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
                                [seq](auto& e) { return e->seq == seq; });
    if (entryIt != connection->waitQueue.end()) {
        std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
        connection->waitQueue.erase(entryIt);

        const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
        mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
        if (!connection->responsive) {
@@ -6113,10 +6119,10 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
        }
        traceWaitQueueLength(*connection);
        if (restartEvent && connection->status == Connection::Status::NORMAL) {
            connection->outboundQueue.push_front(dispatchEntry);
            connection->outboundQueue.emplace_front(std::move(dispatchEntry));
            traceOutboundQueueLength(*connection);
        } else {
            releaseDispatchEntry(dispatchEntry);
            releaseDispatchEntry(std::move(dispatchEntry));
        }
    }

@@ -6160,13 +6166,13 @@ void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection)
     * processes the events linearly. So providing information about the oldest entry seems to be
     * most useful.
     */
    DispatchEntry* oldestEntry = *connection->waitQueue.begin();
    const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
    DispatchEntry& oldestEntry = *connection->waitQueue.front();
    const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
    std::string reason =
            android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
                                        connection->inputChannel->getName().c_str(),
                                        ns2ms(currentWait),
                                        oldestEntry->eventEntry->getDescription().c_str());
                                        oldestEntry.eventEntry->getDescription().c_str());
    sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
    updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);

@@ -6303,7 +6309,7 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec
}

bool InputDispatcher::afterKeyEventLockedInterruptable(
        const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
        const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
        KeyEntry& keyEntry, bool handled) {
    if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
        if (!handled) {
@@ -6321,7 +6327,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable(
        connection->inputState.removeFallbackKey(originalKeyCode);
    }

    if (handled || !dispatchEntry->hasForegroundTarget()) {
    if (handled || !dispatchEntry.hasForegroundTarget()) {
        // If the application handles the original key for which we previously
        // generated a fallback or if the window is not a foreground window,
        // then cancel the associated fallback key, if any.
@@ -6488,7 +6494,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable(
}

bool InputDispatcher::afterMotionEventLockedInterruptable(
        const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
        const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
        MotionEntry& motionEntry, bool handled) {
    return false;
}
+4 −4
Original line number Diff line number Diff line
@@ -598,8 +598,8 @@ private:
    void abortBrokenDispatchCycleLocked(nsecs_t currentTime,
                                        const std::shared_ptr<Connection>& connection, bool notify)
            REQUIRES(mLock);
    void drainDispatchQueue(std::deque<DispatchEntry*>& queue);
    void releaseDispatchEntry(DispatchEntry* dispatchEntry);
    void drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue);
    void releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry);
    int handleReceiveCallback(int events, sp<IBinder> connectionToken);
    // The action sent should only be of type AMOTION_EVENT_*
    void dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
@@ -664,10 +664,10 @@ private:
            REQUIRES(mLock);
    std::map<int32_t /*displayId*/, InputVerifier> mVerifiersByDisplay;
    bool afterKeyEventLockedInterruptable(const std::shared_ptr<Connection>& connection,
                                          DispatchEntry* dispatchEntry, KeyEntry& keyEntry,
                                          DispatchEntry& dispatchEntry, KeyEntry& keyEntry,
                                          bool handled) REQUIRES(mLock);
    bool afterMotionEventLockedInterruptable(const std::shared_ptr<Connection>& connection,
                                             DispatchEntry* dispatchEntry, MotionEntry& motionEntry,
                                             DispatchEntry& dispatchEntry, MotionEntry& motionEntry,
                                             bool handled) REQUIRES(mLock);

    // Find touched state and touched window by token.