Use std::unique_ptr for DispatchEntry

Bug: 210460522
Test: atest inputflinger_tests
Change-Id: I2e7073493cbd31df0d7073a5f5f44fe64d7be0b3
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 9cd1e09..f037b87 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -271,7 +271,8 @@
     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 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 @@
     }
 
     // Enqueue the dispatch entry.
-    connection->outboundQueue.push_back(dispatchEntry.release());
+    connection->outboundQueue.emplace_back(std::move(dispatchEntry));
     traceOutboundQueueLength(*connection);
 }
 
@@ -3584,7 +3585,7 @@
     }
 
     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 @@
         }
 
         // 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::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) {
@@ -6061,43 +6058,52 @@
                                                      uint32_t seq, bool handled,
                                                      nsecs_t consumeTime) {
     // Handle post-event policy actions.
-    std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
-    if (dispatchEntryIt == connection->waitQueue.end()) {
-        return;
-    }
-    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());
-    }
-    if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
-        mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
-                                           connection->inputChannel->getConnectionToken(),
-                                           dispatchEntry->deliveryTime, consumeTime, finishTime);
-    }
-
     bool restartEvent;
-    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 {
-        restartEvent = false;
-    }
+
+    { // 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;
+        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());
+        }
+        if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
+            mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
+                                               connection->inputChannel->getConnectionToken(),
+                                               dispatchEntry.deliveryTime, consumeTime, finishTime);
+        }
+
+        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 {
+            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) {
@@ -6109,10 +6115,10 @@
         }
         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));
         }
     }
 
@@ -6156,13 +6162,13 @@
      * 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);
 
@@ -6299,7 +6305,7 @@
 }
 
 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) {
@@ -6317,7 +6323,7 @@
         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.
@@ -6484,7 +6490,7 @@
 }
 
 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;
 }