libbinder : Avoid waiting in binder_rpc_fuzzer

Introducing new APIs in RpcServer and RpcSession to check
polling state of file descriptor. Removing fixed wait time
in binder_rpc_fuzzer.

Test: m binder_rpc_fuzzer &&
$ANDROID_HOST_OUT/fuzz/x86_64/binder_rpc_fuzzer/binder_rpc_fuzzer
Bug: 218518615

Change-Id: Ied82cd9c16514761a489731488924274a17053a6
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 0ee5f05..e581d0b 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -560,4 +560,14 @@
     return OK;
 }
 
+bool RpcServer::hasActiveRequests() {
+    RpcMutexLockGuard _l(mLock);
+    for (const auto& [_, session] : mSessions) {
+        if (session->hasActiveRequests()) {
+            return true;
+        }
+    }
+    return !mServer.isInPollingState();
+}
+
 } // namespace android
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index bef2ed6..49843e5 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -952,4 +952,24 @@
     }
 }
 
+bool RpcSession::hasActiveConnection(const std::vector<sp<RpcConnection>>& connections) {
+    for (const auto& connection : connections) {
+        if (connection->exclusiveTid != std::nullopt && !connection->rpcTransport->isWaiting()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool RpcSession::hasActiveRequests() {
+    RpcMutexUniqueLock _l(mMutex);
+    if (hasActiveConnection(mConnections.mIncoming)) {
+        return true;
+    }
+    if (hasActiveConnection(mConnections.mOutgoing)) {
+        return true;
+    }
+    return mConnections.mWaitingThreads != 0;
+}
+
 } // namespace android
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index ca02ab2..2c99334 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -187,6 +187,11 @@
     std::vector<sp<RpcSession>> listSessions();
     size_t numUninitializedSessions();
 
+    /**
+     * Whether any requests are currently being processed.
+     */
+    bool hasActiveRequests();
+
     ~RpcServer();
 
 private:
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index 9630e2f..a25ba98 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -189,6 +189,11 @@
      */
     [[nodiscard]] status_t sendDecStrong(const BpBinder* binder);
 
+    /**
+     * Whether any requests are currently being processed.
+     */
+    bool hasActiveRequests();
+
     ~RpcSession();
 
     /**
@@ -286,6 +291,11 @@
 
     [[nodiscard]] status_t initShutdownTrigger();
 
+    /**
+     * Checks whether any connection is active (Not polling on fd)
+     */
+    bool hasActiveConnection(const std::vector<sp<RpcConnection>>& connections);
+
     enum class ConnectionUse {
         CLIENT,
         CLIENT_ASYNC,
diff --git a/libs/binder/tests/rpc_fuzzer/main.cpp b/libs/binder/tests/rpc_fuzzer/main.cpp
index a8713a2..f68a561 100644
--- a/libs/binder/tests/rpc_fuzzer/main.cpp
+++ b/libs/binder/tests/rpc_fuzzer/main.cpp
@@ -157,8 +157,6 @@
         }
     }
 
-    usleep(10000);
-
     if (hangupBeforeShutdown) {
         connections.clear();
         while (!server->listSessions().empty() || server->numUninitializedSessions()) {
@@ -167,6 +165,10 @@
         }
     }
 
+    while (server->hasActiveRequests()) {
+        usleep(10);
+    }
+
     while (!server->shutdown()) usleep(1);
     serverThread.join();