libbinder: Add object offsets to RPC Binder protocol
The list of object offsets is always empty in this CL. That will change
in follow up CLs when file descriptor support is added.
The size of the parcel data is included in the RpcWireTransaction and
RpcWireReply headers and then the object offsets are written after the
parcel data.
There was no space in RpcWireReply, so we must start a new wire protocol
version. I've added some reserved space to RpcWireReply to match
RpcWireTransaction so that it might be easier to make backwards
compatible changes later.
binderRpcTest on host went from 36 seconds to 2 minutes 24 seconds
because of the added parameterization (x4 the tests => x4 the time).
Bug: 185909244
Test: TH
Change-Id: I0121a42f8b60362e6a6d0294a350255b5f9f5673
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index f5de5b1..419df86 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -27,6 +27,7 @@
#include "Debug.h"
#include "RpcWireFormat.h"
+#include "Utils.h"
#include <random>
@@ -493,9 +494,15 @@
}
}
+ // objectTable always empty for now. Will be populated from `data` soon.
+ std::vector<uint32_t> objectTable;
+ Span<const uint32_t> objectTableSpan = {objectTable.data(), objectTable.size()};
+
uint32_t bodySize;
LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(sizeof(RpcWireTransaction), data.dataSize(),
- &bodySize),
+ &bodySize) ||
+ __builtin_add_overflow(objectTableSpan.byteSize(), bodySize,
+ &bodySize),
"Too much data %zu", data.dataSize());
RpcWireHeader command{
.command = RPC_COMMAND_TRANSACT,
@@ -507,6 +514,8 @@
.code = code,
.flags = flags,
.asyncNumber = asyncNumber,
+ // bodySize didn't overflow => this cast is safe
+ .parcelDataSize = static_cast<uint32_t>(data.dataSize()),
};
constexpr size_t kWaitMaxUs = 1000000;
@@ -521,6 +530,7 @@
{&command, sizeof(RpcWireHeader)},
{&transaction, sizeof(RpcWireTransaction)},
{const_cast<uint8_t*>(data.data()), data.dataSize()},
+ objectTableSpan.toIovec(),
};
if (status_t status = rpcSend(connection, session, "transaction", iovs, arraysize(iovs),
[&] {
@@ -585,7 +595,9 @@
return status;
}
- if (command.bodySize < sizeof(RpcWireReply)) {
+ const size_t rpcReplyWireSize = RpcWireReply::wireSize(session->getProtocolVersion().value());
+
+ if (command.bodySize < rpcReplyWireSize) {
ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireReply. Terminating!",
sizeof(RpcWireReply), command.bodySize);
(void)session->shutdownAndWait(false);
@@ -593,11 +605,13 @@
}
RpcWireReply rpcReply;
- CommandData data(command.bodySize - sizeof(RpcWireReply));
+ memset(&rpcReply, 0, sizeof(RpcWireReply)); // zero because of potential short read
+
+ CommandData data(command.bodySize - rpcReplyWireSize);
if (!data.valid()) return NO_MEMORY;
iovec iovs[]{
- {&rpcReply, sizeof(RpcWireReply)},
+ {&rpcReply, rpcReplyWireSize},
{data.data(), data.size()},
};
if (status_t status = rpcRec(connection, session, "reply body", iovs, arraysize(iovs));
@@ -605,11 +619,15 @@
return status;
if (rpcReply.status != OK) return rpcReply.status;
- uint8_t* parcelData = data.data();
- size_t parcelDataSize = data.size();
- data.release();
- reply->rpcSetDataReference(session, parcelData, parcelDataSize, cleanup_reply_data);
+ Span<const uint8_t> parcelSpan = {data.data(), data.size()};
+ if (session->getProtocolVersion().value() >=
+ RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE) {
+ Span<const uint8_t> objectTableBytes = parcelSpan.splitOff(rpcReply.parcelDataSize);
+ LOG_ALWAYS_FATAL_IF(objectTableBytes.size > 0, "Non-empty object table not supported yet.");
+ }
+ data.release();
+ reply->rpcSetDataReference(session, parcelSpan.data, parcelSpan.size, cleanup_reply_data);
return OK;
}
@@ -824,12 +842,22 @@
reply.markForRpc(session);
if (replyStatus == OK) {
+ Span<const uint8_t> parcelSpan = {transaction->data,
+ transactionData.size() -
+ offsetof(RpcWireTransaction, data)};
+ if (session->getProtocolVersion().value() >=
+ RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE) {
+ Span<const uint8_t> objectTableBytes = parcelSpan.splitOff(transaction->parcelDataSize);
+ LOG_ALWAYS_FATAL_IF(objectTableBytes.size > 0,
+ "Non-empty object table not supported yet.");
+ }
+
Parcel data;
// transaction->data is owned by this function. Parcel borrows this data and
// only holds onto it for the duration of this function call. Parcel will be
// deleted before the 'transactionData' object.
- data.rpcSetDataReference(session, transaction->data,
- transactionData.size() - offsetof(RpcWireTransaction, data),
+
+ data.rpcSetDataReference(session, parcelSpan.data, parcelSpan.size,
do_nothing_to_transact_data);
if (target) {
@@ -941,8 +969,16 @@
replyStatus = flushExcessBinderRefs(session, addr, target);
}
+ const size_t rpcReplyWireSize = RpcWireReply::wireSize(session->getProtocolVersion().value());
+
+ // objectTable always empty for now. Will be populated from `reply` soon.
+ std::vector<uint32_t> objectTable;
+ Span<const uint32_t> objectTableSpan = {objectTable.data(), objectTable.size()};
+
uint32_t bodySize;
- LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(sizeof(RpcWireReply), reply.dataSize(), &bodySize),
+ LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(rpcReplyWireSize, reply.dataSize(), &bodySize) ||
+ __builtin_add_overflow(objectTableSpan.byteSize(), bodySize,
+ &bodySize),
"Too much data for reply %zu", reply.dataSize());
RpcWireHeader cmdReply{
.command = RPC_COMMAND_REPLY,
@@ -950,12 +986,17 @@
};
RpcWireReply rpcReply{
.status = replyStatus,
+ // NOTE: Not necessarily written to socket depending on session
+ // version.
+ // NOTE: bodySize didn't overflow => this cast is safe
+ .parcelDataSize = static_cast<uint32_t>(reply.dataSize()),
+ .reserved = {0, 0, 0},
};
-
iovec iovs[]{
{&cmdReply, sizeof(RpcWireHeader)},
- {&rpcReply, sizeof(RpcWireReply)},
+ {&rpcReply, rpcReplyWireSize},
{const_cast<uint8_t*>(reply.data()), reply.dataSize()},
+ objectTableSpan.toIovec(),
};
return rpcSend(connection, session, "reply", iovs, arraysize(iovs), std::nullopt);
}
diff --git a/libs/binder/RpcWireFormat.h b/libs/binder/RpcWireFormat.h
index d9b5ca0..7e2aa79 100644
--- a/libs/binder/RpcWireFormat.h
+++ b/libs/binder/RpcWireFormat.h
@@ -131,7 +131,10 @@
uint64_t asyncNumber;
- uint32_t reserved[4];
+ // The size of the Parcel data directly following RpcWireTransaction.
+ uint32_t parcelDataSize;
+
+ uint32_t reserved[3];
uint8_t data[];
};
@@ -139,8 +142,23 @@
struct RpcWireReply {
int32_t status; // transact return
+
+ // -- Fields below only transmitted starting at protocol version 1 --
+
+ // The size of the Parcel data directly following RpcWireReply.
+ uint32_t parcelDataSize;
+
+ uint32_t reserved[3];
+
+ // Byte size of RpcWireReply in the wire protocol.
+ static size_t wireSize(uint32_t protocolVersion) {
+ if (protocolVersion == 0) {
+ return sizeof(int32_t);
+ }
+ return sizeof(RpcWireReply);
+ }
};
-static_assert(sizeof(RpcWireReply) == 4);
+static_assert(sizeof(RpcWireReply) == 20);
#pragma clang diagnostic pop
diff --git a/libs/binder/Utils.h b/libs/binder/Utils.h
index 150d520..7dcb70e 100644
--- a/libs/binder/Utils.h
+++ b/libs/binder/Utils.h
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-#include <cstdint>
#include <stddef.h>
+#include <cstdint>
+#include <optional>
#include <android-base/result.h>
#include <android-base/unique_fd.h>
@@ -39,4 +40,26 @@
status_t getRandomBytes(uint8_t* data, size_t size);
+// View of contiguous sequence. Similar to std::span.
+template <typename T>
+struct Span {
+ T* data = nullptr;
+ size_t size = 0;
+
+ size_t byteSize() { return size * sizeof(T); }
+
+ iovec toIovec() { return {const_cast<std::remove_const_t<T>*>(data), byteSize()}; }
+
+ // Truncates `this` to a length of `offset` and returns a span with the
+ // remainder.
+ //
+ // Aborts if offset > size.
+ Span<T> splitOff(size_t offset) {
+ LOG_ALWAYS_FATAL_IF(offset > size);
+ Span<T> rest = {data + offset, size - offset};
+ size = offset;
+ return rest;
+ }
+};
+
} // namespace android
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index cb81584..e76b140 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -38,7 +38,13 @@
constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_NEXT = 1;
constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL = 0xF0000000;
-constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = 0;
+constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL;
+
+// Starting with this version:
+//
+// * RpcWireReply is larger (4 bytes -> 20).
+// * RpcWireTransaction and RpcWireReplyV1 include the parcel data size.
+constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE = 1;
/**
* This represents a session (group of connections) between a client
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 4977c63..5161469 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -99,17 +99,19 @@
EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), "");
}
-class BinderRpcSimple : public ::testing::TestWithParam<RpcSecurity> {
+class BinderRpcServerOnly : public ::testing::TestWithParam<std::tuple<RpcSecurity, uint32_t>> {
public:
static std::string PrintTestParam(const ::testing::TestParamInfo<ParamType>& info) {
- return newFactory(info.param)->toCString();
+ return std::string(newFactory(std::get<0>(info.param))->toCString()) + "_serverV" +
+ std::to_string(std::get<1>(info.param));
}
};
-TEST_P(BinderRpcSimple, SetExternalServerTest) {
+TEST_P(BinderRpcServerOnly, SetExternalServerTest) {
base::unique_fd sink(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)));
int sinkFd = sink.get();
- auto server = RpcServer::make(newFactory(GetParam()));
+ auto server = RpcServer::make(newFactory(std::get<0>(GetParam())));
+ server->setProtocolVersion(std::get<1>(GetParam()));
ASSERT_FALSE(server->hasServer());
ASSERT_EQ(OK, server->setupExternalServer(std::move(sink)));
ASSERT_TRUE(server->hasServer());
@@ -480,7 +482,8 @@
return serverFd;
}
-class BinderRpc : public ::testing::TestWithParam<std::tuple<SocketType, RpcSecurity>> {
+class BinderRpc
+ : public ::testing::TestWithParam<std::tuple<SocketType, RpcSecurity, uint32_t, uint32_t>> {
public:
struct Options {
size_t numThreads = 1;
@@ -490,8 +493,9 @@
};
static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [type, security] = info.param;
- return PrintToString(type) + "_" + newFactory(security)->toCString();
+ auto [type, security, clientVersion, serverVersion] = info.param;
+ return PrintToString(type) + "_" + newFactory(security)->toCString() + "_clientV" +
+ std::to_string(clientVersion) + "_serverV" + std::to_string(serverVersion);
}
static inline void writeString(android::base::borrowed_fd fd, std::string_view str) {
@@ -533,16 +537,19 @@
SocketType socketType = std::get<0>(GetParam());
RpcSecurity rpcSecurity = std::get<1>(GetParam());
+ uint32_t clientVersion = std::get<2>(GetParam());
+ uint32_t serverVersion = std::get<3>(GetParam());
unsigned int vsockPort = allocateVsockPort();
std::string addr = allocateSocketAddress();
auto ret = ProcessSession{
- .host = Process([&](android::base::borrowed_fd writeEnd,
+ .host = Process([=](android::base::borrowed_fd writeEnd,
android::base::borrowed_fd readEnd) {
auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
sp<RpcServer> server = RpcServer::make(newFactory(rpcSecurity, certVerifier));
+ server->setProtocolVersion(serverVersion);
server->setMaxThreads(options.numThreads);
unsigned int outPort = 0;
@@ -618,6 +625,7 @@
status_t status;
for (const auto& session : sessions) {
+ CHECK(session->setProtocolVersion(clientVersion));
session->setMaxIncomingThreads(options.numIncomingConnections);
session->setMaxOutgoingThreads(options.numOutgoingConnections);
@@ -1420,9 +1428,20 @@
return ret;
}
+static std::vector<uint32_t> testVersions() {
+ std::vector<uint32_t> versions;
+ for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
+ versions.push_back(i);
+ }
+ versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
+ return versions;
+}
+
INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
::testing::Combine(::testing::ValuesIn(testSocketTypes()),
- ::testing::ValuesIn(RpcSecurityValues())),
+ ::testing::ValuesIn(RpcSecurityValues()),
+ ::testing::ValuesIn(testVersions()),
+ ::testing::ValuesIn(testVersions())),
BinderRpc::PrintParamInfo);
class BinderRpcServerRootObject
@@ -1476,9 +1495,10 @@
bool mValue = false;
};
-TEST_P(BinderRpcSimple, Shutdown) {
+TEST_P(BinderRpcServerOnly, Shutdown) {
auto addr = allocateSocketAddress();
- auto server = RpcServer::make(newFactory(GetParam()));
+ auto server = RpcServer::make(newFactory(std::get<0>(GetParam())));
+ server->setProtocolVersion(std::get<1>(GetParam()));
ASSERT_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
auto joinEnds = std::make_shared<OneOffSignal>();
@@ -1548,12 +1568,17 @@
ASSERT_EQ(OK, rpcBinder->pingBinder());
}
-INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcSimple, ::testing::ValuesIn(RpcSecurityValues()),
- BinderRpcSimple::PrintTestParam);
+INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerOnly,
+ ::testing::Combine(::testing::ValuesIn(RpcSecurityValues()),
+ ::testing::ValuesIn(testVersions())),
+ BinderRpcServerOnly::PrintTestParam);
class RpcTransportTestUtils {
public:
- using Param = std::tuple<SocketType, RpcSecurity, std::optional<RpcCertificateFormat>>;
+ // Only parameterized only server version because `RpcSession` is bypassed
+ // in the client half of the tests.
+ using Param =
+ std::tuple<SocketType, RpcSecurity, std::optional<RpcCertificateFormat>, uint32_t>;
using ConnectToServer = std::function<base::unique_fd()>;
// A server that handles client socket connections.
@@ -1565,8 +1590,9 @@
[[nodiscard]] AssertionResult setUp(
const Param& param,
std::unique_ptr<RpcAuth> auth = std::make_unique<RpcAuthSelfSigned>()) {
- auto [socketType, rpcSecurity, certificateFormat] = param;
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = param;
auto rpcServer = RpcServer::make(newFactory(rpcSecurity));
+ rpcServer->setProtocolVersion(serverVersion);
switch (socketType) {
case SocketType::PRECONNECTED: {
return AssertionFailure() << "Not supported by this test";
@@ -1696,7 +1722,8 @@
explicit Client(ConnectToServer connectToServer) : mConnectToServer(connectToServer) {}
Client(Client&&) = default;
[[nodiscard]] AssertionResult setUp(const Param& param) {
- auto [socketType, rpcSecurity, certificateFormat] = param;
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = param;
+ (void)serverVersion;
mFdTrigger = FdTrigger::make();
mCtx = newFactory(rpcSecurity, mCertVerifier)->newClientCtx();
if (mCtx == nullptr) return AssertionFailure() << "newClientCtx";
@@ -1767,23 +1794,28 @@
using Server = RpcTransportTestUtils::Server;
using Client = RpcTransportTestUtils::Client;
static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [socketType, rpcSecurity, certificateFormat] = info.param;
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = info.param;
auto ret = PrintToString(socketType) + "_" + newFactory(rpcSecurity)->toCString();
if (certificateFormat.has_value()) ret += "_" + PrintToString(*certificateFormat);
+ ret += "_serverV" + std::to_string(serverVersion);
return ret;
}
static std::vector<ParamType> getRpcTranportTestParams() {
std::vector<ParamType> ret;
- for (auto socketType : testSocketTypes(false /* hasPreconnected */)) {
- for (auto rpcSecurity : RpcSecurityValues()) {
- switch (rpcSecurity) {
- case RpcSecurity::RAW: {
- ret.emplace_back(socketType, rpcSecurity, std::nullopt);
- } break;
- case RpcSecurity::TLS: {
- ret.emplace_back(socketType, rpcSecurity, RpcCertificateFormat::PEM);
- ret.emplace_back(socketType, rpcSecurity, RpcCertificateFormat::DER);
- } break;
+ for (auto serverVersion : testVersions()) {
+ for (auto socketType : testSocketTypes(false /* hasPreconnected */)) {
+ for (auto rpcSecurity : RpcSecurityValues()) {
+ switch (rpcSecurity) {
+ case RpcSecurity::RAW: {
+ ret.emplace_back(socketType, rpcSecurity, std::nullopt, serverVersion);
+ } break;
+ case RpcSecurity::TLS: {
+ ret.emplace_back(socketType, rpcSecurity, RpcCertificateFormat::PEM,
+ serverVersion);
+ ret.emplace_back(socketType, rpcSecurity, RpcCertificateFormat::DER,
+ serverVersion);
+ } break;
+ }
}
}
}
@@ -1791,7 +1823,8 @@
}
template <typename A, typename B>
status_t trust(const A& a, const B& b) {
- auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = GetParam();
+ (void)serverVersion;
return RpcTransportTestUtils::trust(rpcSecurity, certificateFormat, a, b);
}
};
@@ -1827,7 +1860,8 @@
}
TEST_P(RpcTransportTest, UntrustedServer) {
- auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = GetParam();
+ (void)serverVersion;
auto untrustedServer = std::make_unique<Server>();
ASSERT_TRUE(untrustedServer->setUp(GetParam()));
@@ -1845,7 +1879,9 @@
client.run(handshakeOk);
}
TEST_P(RpcTransportTest, MaliciousServer) {
- auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = GetParam();
+ (void)serverVersion;
+
auto validServer = std::make_unique<Server>();
ASSERT_TRUE(validServer->setUp(GetParam()));
@@ -1868,7 +1904,9 @@
}
TEST_P(RpcTransportTest, UntrustedClient) {
- auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = GetParam();
+ (void)serverVersion;
+
auto server = std::make_unique<Server>();
ASSERT_TRUE(server->setUp(GetParam()));
@@ -1887,7 +1925,9 @@
}
TEST_P(RpcTransportTest, MaliciousClient) {
- auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+ auto [socketType, rpcSecurity, certificateFormat, serverVersion] = GetParam();
+ (void)serverVersion;
+
auto server = std::make_unique<Server>();
ASSERT_TRUE(server->setUp(GetParam()));
@@ -1973,23 +2013,24 @@
RpcTransportTest::PrintParamInfo);
class RpcTransportTlsKeyTest
- : public testing::TestWithParam<std::tuple<SocketType, RpcCertificateFormat, RpcKeyFormat>> {
+ : public testing::TestWithParam<
+ std::tuple<SocketType, RpcCertificateFormat, RpcKeyFormat, uint32_t>> {
public:
template <typename A, typename B>
status_t trust(const A& a, const B& b) {
- auto [socketType, certificateFormat, keyFormat] = GetParam();
+ auto [socketType, certificateFormat, keyFormat, serverVersion] = GetParam();
+ (void)serverVersion;
return RpcTransportTestUtils::trust(RpcSecurity::TLS, certificateFormat, a, b);
}
static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [socketType, certificateFormat, keyFormat] = info.param;
- auto ret = PrintToString(socketType) + "_certificate_" + PrintToString(certificateFormat) +
- "_key_" + PrintToString(keyFormat);
- return ret;
+ auto [socketType, certificateFormat, keyFormat, serverVersion] = info.param;
+ return PrintToString(socketType) + "_certificate_" + PrintToString(certificateFormat) +
+ "_key_" + PrintToString(keyFormat) + "_serverV" + std::to_string(serverVersion);
};
};
TEST_P(RpcTransportTlsKeyTest, PreSignedCertificate) {
- auto [socketType, certificateFormat, keyFormat] = GetParam();
+ auto [socketType, certificateFormat, keyFormat, serverVersion] = GetParam();
std::vector<uint8_t> pkeyData, certData;
{
@@ -2004,8 +2045,8 @@
auto desPkey = deserializeUnencryptedPrivatekey(pkeyData, keyFormat);
auto desCert = deserializeCertificate(certData, certificateFormat);
auto auth = std::make_unique<RpcAuthPreSigned>(std::move(desPkey), std::move(desCert));
- auto utilsParam =
- std::make_tuple(socketType, RpcSecurity::TLS, std::make_optional(certificateFormat));
+ auto utilsParam = std::make_tuple(socketType, RpcSecurity::TLS,
+ std::make_optional(certificateFormat), serverVersion);
auto server = std::make_unique<RpcTransportTestUtils::Server>();
ASSERT_TRUE(server->setUp(utilsParam, std::move(auth)));
@@ -2024,7 +2065,8 @@
BinderRpc, RpcTransportTlsKeyTest,
testing::Combine(testing::ValuesIn(testSocketTypes(false /* hasPreconnected*/)),
testing::Values(RpcCertificateFormat::PEM, RpcCertificateFormat::DER),
- testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER)),
+ testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
+ testing::ValuesIn(testVersions())),
RpcTransportTlsKeyTest::PrintParamInfo);
} // namespace android
diff --git a/libs/binder/tests/binderRpcWireProtocolTest.cpp b/libs/binder/tests/binderRpcWireProtocolTest.cpp
index 4fcf42d..3dab2c7 100644
--- a/libs/binder/tests/binderRpcWireProtocolTest.cpp
+++ b/libs/binder/tests/binderRpcWireProtocolTest.cpp
@@ -233,11 +233,15 @@
"0100000025000000|03000000|00000000|ffffffff|03000000|00000000|00000000|"
"07000000020000003a0044000000000000000000|f8ffffff020000003a002f00000000000000000008000000";
+TEST(RpcWire, V0) {
+ checkRepr(kCurrentRepr, 0);
+}
+
TEST(RpcWire, CurrentVersion) {
checkRepr(kCurrentRepr, RPC_WIRE_PROTOCOL_VERSION);
}
-static_assert(RPC_WIRE_PROTOCOL_VERSION == 0,
+static_assert(RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL,
"If the binder wire protocol is updated, this test should test additional versions. "
"The binder wire protocol should only be updated on upstream AOSP.");