diff --git a/client-sdk-rust b/client-sdk-rust index 06371a33..1a477bc4 160000 --- a/client-sdk-rust +++ b/client-sdk-rust @@ -1 +1 @@ -Subproject commit 06371a336d485cf6b51c75a3fee3d208f8f2eedb +Subproject commit 1a477bc422c6890537b3bcdb017f0ac094d49661 diff --git a/include/livekit/room.h b/include/livekit/room.h index 10995731..faffa715 100644 --- a/include/livekit/room.h +++ b/include/livekit/room.h @@ -121,6 +121,16 @@ struct RoomOptions { /// /// If unset, the Rust SDK default is used. std::optional connect_timeout; + + /// @cond + /// Additional LiveKit SDKs layered on top of this one, reported to the server + /// as part of the client info. + /// + /// Comma separated list of `name:version` pairs, e.g. + /// "ros_portal:1.2.3,components-cpp:2.0.0". If unset, no additional SDKs are reported. + /// this is for internal use only. + std::optional other_sdks; + /// @endcond }; /// Represents a LiveKit room session. diff --git a/src/ffi_client.cpp b/src/ffi_client.cpp index 8c0516b0..6c924560 100644 --- a/src/ffi_client.cpp +++ b/src/ffi_client.cpp @@ -61,6 +61,8 @@ const auto optional_to_string = [](const auto& value) -> std::string { return *value ? "true" : "false"; } else if constexpr (std::is_same_v) { return std::to_string(value->count()); + } else if constexpr (std::is_same_v) { + return *value; } else { return std::to_string(*value); } @@ -503,10 +505,10 @@ std::future FfiClient::connectAsync(const std::string& u LK_LOG_DEBUG( "[FfiClient] connectAsync: auto_subscribe={}, adaptive_stream={}, dynacast={}, " - "single_peer_connection={}, join_retries={}, connect_timeout_ms={}", + "single_peer_connection={}, join_retries={}, connect_timeout_ms={}, other_sdks={}", options.auto_subscribe, optional_to_string(options.adaptive_stream), options.dynacast, options.single_peer_connection, optional_to_string(options.join_retries), - optional_to_string(options.connect_timeout)); + optional_to_string(options.connect_timeout), optional_to_string(options.other_sdks)); try { const proto::FfiResponse resp = sendRequest(req); diff --git a/src/room_proto_converter.cpp b/src/room_proto_converter.cpp index a1265aa3..4c5da0ed 100644 --- a/src/room_proto_converter.cpp +++ b/src/room_proto_converter.cpp @@ -469,6 +469,9 @@ proto::RoomOptions toProto(const RoomOptions& in) { if (in.connect_timeout) { out.set_connect_timeout_ms(static_cast(in.connect_timeout->count())); } + if (in.other_sdks) { + out.set_other_sdks(*in.other_sdks); + } return out; } diff --git a/src/tests/unit/test_room.cpp b/src/tests/unit/test_room.cpp index 6ea52d0c..22769930 100644 --- a/src/tests/unit/test_room.cpp +++ b/src/tests/unit/test_room.cpp @@ -192,6 +192,7 @@ TEST_F(RoomTest, RoomOptionsDefaults) { EXPECT_FALSE(options.join_retries.has_value()) << "join_retries should defer to Rust default"; EXPECT_TRUE(options.single_peer_connection) << "single_peer_connection should default to true"; EXPECT_FALSE(options.connect_timeout.has_value()) << "connect_timeout should defer to Rust default"; + EXPECT_FALSE(options.other_sdks.has_value()) << "other_sdks should not report additional SDKs by default"; } TEST_F(RoomTest, RoomOptionsToProtoSerializesDefaults) { @@ -208,6 +209,7 @@ TEST_F(RoomTest, RoomOptionsToProtoSerializesDefaults) { EXPECT_TRUE(proto_options.has_single_peer_connection()); EXPECT_TRUE(proto_options.single_peer_connection()); EXPECT_FALSE(proto_options.has_connect_timeout_ms()); + EXPECT_FALSE(proto_options.has_other_sdks()); } TEST_F(RoomTest, RoomOptionsProtoConverter) { @@ -227,6 +229,7 @@ TEST_F(RoomTest, RoomOptionsProtoConverter) { options.join_retries = 8; options.single_peer_connection = false; options.connect_timeout = std::chrono::milliseconds(750); + options.other_sdks = "ros_portal:1.2.3,another-sdk:2.0.0"; const proto::RoomOptions proto_options = toProto(options); @@ -255,6 +258,8 @@ TEST_F(RoomTest, RoomOptionsProtoConverter) { EXPECT_FALSE(proto_options.single_peer_connection()); EXPECT_TRUE(proto_options.has_connect_timeout_ms()); EXPECT_EQ(proto_options.connect_timeout_ms(), 750U); + EXPECT_TRUE(proto_options.has_other_sdks()); + EXPECT_EQ(proto_options.other_sdks(), "ros_portal:1.2.3,another-sdk:2.0.0"); } TEST(RoomOptionsProtoTest, ConnectRequestSerializesRetryOptions) { @@ -285,6 +290,18 @@ TEST(RoomOptionsProtoTest, ConnectRequestSerializesRetryOptions) { EXPECT_EQ(decoded.connect().options().connect_timeout_ms(), 750U); } +TEST(RoomOptionsProtoTest, EmptyOtherSdksIsStillSerialized) { + // An explicitly empty list stays distinguishable from unset on the wire; Rust + // collapses both to "no additional SDKs". + RoomOptions options; + options.other_sdks = ""; + + const proto::RoomOptions proto_options = toProto(options); + + ASSERT_TRUE(proto_options.has_other_sdks()); + EXPECT_EQ(proto_options.other_sdks(), ""); +} + TEST_F(RoomTest, RtcConfigDefaults) { RtcConfig config;