libbinder: RPC binder - incl. protocol version
Bug: 182938972
Test: binderRpcTest
Change-Id: I135fa44b111d92b53161775dea90a42e4cb5bee1
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 1c37651..90ce4d6 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -77,6 +77,25 @@
return mMaxThreads;
}
+bool RpcSession::setProtocolVersion(uint32_t version) {
+ if (version >= RPC_WIRE_PROTOCOL_VERSION_NEXT &&
+ version != RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
+ ALOGE("Cannot start RPC session with version %u which is unknown (current protocol version "
+ "is %u).",
+ version, RPC_WIRE_PROTOCOL_VERSION);
+ return false;
+ }
+
+ std::lock_guard<std::mutex> _l(mMutex);
+ mProtocolVersion = version;
+ return true;
+}
+
+std::optional<uint32_t> RpcSession::getProtocolVersion() {
+ std::lock_guard<std::mutex> _l(mMutex);
+ return mProtocolVersion;
+}
+
bool RpcSession::setupUnixDomainClient(const char* path) {
return setupSocketClient(UnixSocketAddress(path));
}
@@ -424,6 +443,18 @@
if (!setupOneSocketConnection(addr, RpcAddress::zero(), false /*incoming*/)) return false;
+ {
+ ExclusiveConnection connection;
+ status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+ ConnectionUse::CLIENT, &connection);
+ if (status != OK) return false;
+
+ uint32_t version;
+ status = state()->readNewSessionResponse(connection.get(),
+ sp<RpcSession>::fromExisting(this), &version);
+ if (!setProtocolVersion(version)) return false;
+ }
+
// TODO(b/189955605): we should add additional sessions dynamically
// instead of all at once.
// TODO(b/186470974): first risk of blocking
@@ -484,7 +515,10 @@
return false;
}
- RpcConnectionHeader header{.options = 0};
+ RpcConnectionHeader header{
+ .version = mProtocolVersion.value_or(RPC_WIRE_PROTOCOL_VERSION),
+ .options = 0,
+ };
memcpy(&header.sessionId, &id.viewRawEmbedded(), sizeof(RpcWireAddress));
if (incoming) header.options |= RPC_CONNECTION_OPTION_INCOMING;