Merge "RpcServer: expose server fd" am: e81f29d204 am: fbbcccc723 am: 8eba788850
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1705663
Change-Id: Ia767123dab6208749dceab013ba66059103fbca3
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index dc10d1c..9cc6e7f 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -272,8 +272,26 @@
}
bool RpcServer::hasServer() {
+ LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
std::lock_guard<std::mutex> _l(mLock);
return mServer.ok();
}
+unique_fd RpcServer::releaseServer() {
+ LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
+ std::lock_guard<std::mutex> _l(mLock);
+ return std::move(mServer);
+}
+
+bool RpcServer::setupExternalServer(base::unique_fd serverFd) {
+ LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
+ std::lock_guard<std::mutex> _l(mLock);
+ if (mServer.ok()) {
+ ALOGE("Each RpcServer can only have one server.");
+ return false;
+ }
+ mServer = std::move(serverFd);
+ return true;
+}
+
} // namespace android
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index 771bbe6..8f0c6fd 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -79,6 +79,17 @@
*/
[[nodiscard]] bool hasServer();
+ /**
+ * If hasServer(), return the server FD. Otherwise return invalid FD.
+ */
+ [[nodiscard]] base::unique_fd releaseServer();
+
+ /**
+ * Set up server using an external FD previously set up by releaseServer().
+ * Return false if there's already a server.
+ */
+ bool setupExternalServer(base::unique_fd serverFd);
+
void iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
/**
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 9c263b1..3f94df2 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -50,6 +50,19 @@
EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), "");
}
+TEST(BinderRpc, SetExternalServer) {
+ base::unique_fd sink(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)));
+ int sinkFd = sink.get();
+ auto server = RpcServer::make();
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ ASSERT_FALSE(server->hasServer());
+ ASSERT_TRUE(server->setupExternalServer(std::move(sink)));
+ ASSERT_TRUE(server->hasServer());
+ base::unique_fd retrieved = server->releaseServer();
+ ASSERT_FALSE(server->hasServer());
+ ASSERT_EQ(sinkFd, retrieved.get());
+}
+
using android::binder::Status;
#define EXPECT_OK(status) \