libutils: Looper add 'repoll'

To help cases where kernel drivers do not
implement poll events correctly.

Bug: 316829336
Test: boot

Change-Id: Ibad16a8e8e061a5be8cede7e8680c3095d6e6f32
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index 576c61d..7700c90 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -532,6 +532,30 @@
     return removeSequenceNumberLocked(it->second);
 }
 
+int Looper::repoll(int fd) {
+    AutoMutex _l(mLock);
+    const auto& it = mSequenceNumberByFd.find(fd);
+    if (it == mSequenceNumberByFd.end()) {
+        return 0;
+    }
+
+    const auto& request_it = mRequests.find(it->second);
+    if (request_it == mRequests.end()) {
+        return 0;
+    }
+    const auto& [seq, request] = *request_it;
+
+    LOG_ALWAYS_FATAL_IF(
+            fd != request.fd,
+            "Looper has inconsistent data structure. When looking up FD %d found FD %d.", fd,
+            request_it->second.fd);
+
+    epoll_event eventItem = createEpollEvent(request.getEpollEvents(), seq);
+    if (epoll_ctl(mEpollFd.get(), EPOLL_CTL_MOD, fd, &eventItem) == -1) return 0;
+
+    return 1;  // success
+}
+
 int Looper::removeSequenceNumberLocked(SequenceNumber seq) {
 #if DEBUG_CALLBACKS
     ALOGD("%p ~ removeFd - seq=%" PRIu64, this, seq);