1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cast/streaming/session_messenger.h"
6
7 #include "cast/streaming/testing/message_pipe.h"
8 #include "cast/streaming/testing/simple_message_port.h"
9 #include "gtest/gtest.h"
10 #include "platform/test/fake_clock.h"
11 #include "platform/test/fake_task_runner.h"
12
13 namespace openscreen {
14 namespace cast {
15
16 using ::testing::ElementsAre;
17
18 namespace {
19
20 constexpr char kSenderId[] = "sender-12345";
21 constexpr char kReceiverId[] = "receiver-12345";
22
23 // Generally the messages are inlined below, with the exception of the Offer,
24 // simply because it is massive.
25 Offer kExampleOffer{
26 CastMode::kMirroring,
27 {AudioStream{Stream{0,
28 Stream::Type::kAudioSource,
29 2,
30 RtpPayloadType::kAudioOpus,
31 12344442,
32 std::chrono::milliseconds{2000},
33 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
34 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
35 false,
36 "",
37 48000},
38 AudioCodec::kOpus, 1400}},
39 {VideoStream{Stream{1,
40 Stream::Type::kVideoSource,
41 1,
42 RtpPayloadType::kVideoVp8,
43 12344444,
44 std::chrono::milliseconds{2000},
45 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
46 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
47 false,
48 "",
49 90000},
50 VideoCodec::kVp8,
51 SimpleFraction{30, 1},
52 3000000,
53 "",
54 "",
55 "",
56 {Resolution{640, 480}},
57 ""}}};
58
59 struct SessionMessageStore {
60 public:
GetReplyCallbackopenscreen::cast::__anon6e2d8e9a0111::SessionMessageStore61 SenderSessionMessenger::ReplyCallback GetReplyCallback() {
62 return [this](ReceiverMessage message) {
63 receiver_messages.push_back(std::move(message));
64 };
65 }
66
GetRequestCallbackopenscreen::cast::__anon6e2d8e9a0111::SessionMessageStore67 ReceiverSessionMessenger::RequestCallback GetRequestCallback() {
68 return [this](SenderMessage message) {
69 sender_messages.push_back(std::move(message));
70 };
71 }
72
GetErrorCallbackopenscreen::cast::__anon6e2d8e9a0111::SessionMessageStore73 SessionMessenger::ErrorCallback GetErrorCallback() {
74 return [this](Error error) { errors.push_back(std::move(error)); };
75 }
76
77 std::vector<SenderMessage> sender_messages;
78 std::vector<ReceiverMessage> receiver_messages;
79 std::vector<Error> errors;
80 };
81 } // namespace
82
83 class SessionMessengerTest : public ::testing::Test {
84 public:
SessionMessengerTest()85 SessionMessengerTest()
86 : clock_{Clock::now()},
87 task_runner_(&clock_),
88 message_store_(),
89 pipe_(kSenderId, kReceiverId),
90 receiver_messenger_(pipe_.right(),
91 kReceiverId,
92 message_store_.GetErrorCallback()),
93 sender_messenger_(pipe_.left(),
94 kSenderId,
95 kReceiverId,
96 message_store_.GetErrorCallback(),
97 &task_runner_)
98
99 {}
100
SetUp()101 void SetUp() override {
102 sender_messenger_.SetHandler(ReceiverMessage::Type::kRpc,
103 message_store_.GetReplyCallback());
104 receiver_messenger_.SetHandler(SenderMessage::Type::kOffer,
105 message_store_.GetRequestCallback());
106 receiver_messenger_.SetHandler(SenderMessage::Type::kGetCapabilities,
107 message_store_.GetRequestCallback());
108 receiver_messenger_.SetHandler(SenderMessage::Type::kRpc,
109 message_store_.GetRequestCallback());
110 }
111
112 protected:
113 FakeClock clock_;
114 FakeTaskRunner task_runner_;
115 SessionMessageStore message_store_;
116 MessagePipe pipe_;
117 ReceiverSessionMessenger receiver_messenger_;
118 SenderSessionMessenger sender_messenger_;
119
120 std::vector<Error> receiver_errors_;
121 std::vector<Error> sender_errors_;
122 };
123
TEST_F(SessionMessengerTest,RpcMessaging)124 TEST_F(SessionMessengerTest, RpcMessaging) {
125 static const std::vector<uint8_t> kSenderMessage{1, 2, 3, 4, 5};
126 static const std::vector<uint8_t> kReceiverResponse{6, 7, 8, 9};
127 ASSERT_TRUE(
128 sender_messenger_
129 .SendOutboundMessage(SenderMessage{SenderMessage::Type::kRpc, 123,
130 true /* valid */, kSenderMessage})
131 .ok());
132
133 ASSERT_EQ(1u, message_store_.sender_messages.size());
134 ASSERT_TRUE(message_store_.receiver_messages.empty());
135 EXPECT_EQ(SenderMessage::Type::kRpc, message_store_.sender_messages[0].type);
136 ASSERT_TRUE(message_store_.sender_messages[0].valid);
137 EXPECT_EQ(kSenderMessage, absl::get<std::vector<uint8_t>>(
138 message_store_.sender_messages[0].body));
139
140 message_store_.sender_messages.clear();
141 ASSERT_TRUE(
142 receiver_messenger_
143 .SendMessage(ReceiverMessage{ReceiverMessage::Type::kRpc, 123,
144 true /* valid */, kReceiverResponse})
145 .ok());
146
147 ASSERT_TRUE(message_store_.sender_messages.empty());
148 ASSERT_EQ(1u, message_store_.receiver_messages.size());
149 EXPECT_EQ(ReceiverMessage::Type::kRpc,
150 message_store_.receiver_messages[0].type);
151 EXPECT_TRUE(message_store_.receiver_messages[0].valid);
152 EXPECT_EQ(kReceiverResponse, absl::get<std::vector<uint8_t>>(
153 message_store_.receiver_messages[0].body));
154 }
155
TEST_F(SessionMessengerTest,CapabilitiesMessaging)156 TEST_F(SessionMessengerTest, CapabilitiesMessaging) {
157 ASSERT_TRUE(
158 sender_messenger_
159 .SendRequest(SenderMessage{SenderMessage::Type::kGetCapabilities,
160 1337, true /* valid */},
161 ReceiverMessage::Type::kCapabilitiesResponse,
162 message_store_.GetReplyCallback())
163 .ok());
164
165 ASSERT_EQ(1u, message_store_.sender_messages.size());
166 ASSERT_TRUE(message_store_.receiver_messages.empty());
167 EXPECT_EQ(SenderMessage::Type::kGetCapabilities,
168 message_store_.sender_messages[0].type);
169 EXPECT_TRUE(message_store_.sender_messages[0].valid);
170
171 message_store_.sender_messages.clear();
172 ASSERT_TRUE(receiver_messenger_
173 .SendMessage(ReceiverMessage{
174 ReceiverMessage::Type::kCapabilitiesResponse, 1337,
175 true /* valid */,
176 ReceiverCapability{
177 47, {MediaCapability::kAac, MediaCapability::k4k}}})
178 .ok());
179
180 ASSERT_TRUE(message_store_.sender_messages.empty());
181 ASSERT_EQ(1u, message_store_.receiver_messages.size());
182 EXPECT_EQ(ReceiverMessage::Type::kCapabilitiesResponse,
183 message_store_.receiver_messages[0].type);
184 EXPECT_TRUE(message_store_.receiver_messages[0].valid);
185
186 const auto& capability =
187 absl::get<ReceiverCapability>(message_store_.receiver_messages[0].body);
188 EXPECT_EQ(47, capability.remoting_version);
189 EXPECT_THAT(capability.media_capabilities,
190 ElementsAre(MediaCapability::kAac, MediaCapability::k4k));
191 }
192
TEST_F(SessionMessengerTest,OfferAnswerMessaging)193 TEST_F(SessionMessengerTest, OfferAnswerMessaging) {
194 ASSERT_TRUE(sender_messenger_
195 .SendRequest(SenderMessage{SenderMessage::Type::kOffer, 42,
196 true /* valid */, kExampleOffer},
197 ReceiverMessage::Type::kAnswer,
198 message_store_.GetReplyCallback())
199 .ok());
200
201 ASSERT_EQ(1u, message_store_.sender_messages.size());
202 ASSERT_TRUE(message_store_.receiver_messages.empty());
203 EXPECT_EQ(SenderMessage::Type::kOffer,
204 message_store_.sender_messages[0].type);
205 EXPECT_TRUE(message_store_.sender_messages[0].valid);
206 message_store_.sender_messages.clear();
207
208 EXPECT_TRUE(receiver_messenger_
209 .SendMessage(ReceiverMessage{
210 ReceiverMessage::Type::kAnswer, 41, true /* valid */,
211 Answer{1234, {0, 1}, {12344443, 12344445}}})
212 .ok());
213 // A stale answer (for offer 41) should get ignored:
214 ASSERT_TRUE(message_store_.sender_messages.empty());
215 ASSERT_TRUE(message_store_.receiver_messages.empty());
216
217 ASSERT_TRUE(receiver_messenger_
218 .SendMessage(ReceiverMessage{
219 ReceiverMessage::Type::kAnswer, 42, true /* valid */,
220 Answer{1234, {0, 1}, {12344443, 12344445}}})
221 .ok());
222 EXPECT_TRUE(message_store_.sender_messages.empty());
223 ASSERT_EQ(1u, message_store_.receiver_messages.size());
224 EXPECT_EQ(ReceiverMessage::Type::kAnswer,
225 message_store_.receiver_messages[0].type);
226 EXPECT_TRUE(message_store_.receiver_messages[0].valid);
227
228 const auto& answer =
229 absl::get<Answer>(message_store_.receiver_messages[0].body);
230 EXPECT_EQ(1234, answer.udp_port);
231
232 EXPECT_THAT(answer.send_indexes, ElementsAre(0, 1));
233 EXPECT_THAT(answer.ssrcs, ElementsAre(12344443, 12344445));
234 }
235
TEST_F(SessionMessengerTest,OfferAndReceiverError)236 TEST_F(SessionMessengerTest, OfferAndReceiverError) {
237 ASSERT_TRUE(sender_messenger_
238 .SendRequest(SenderMessage{SenderMessage::Type::kOffer, 42,
239 true /* valid */, kExampleOffer},
240 ReceiverMessage::Type::kAnswer,
241 message_store_.GetReplyCallback())
242 .ok());
243
244 ASSERT_EQ(1u, message_store_.sender_messages.size());
245 ASSERT_TRUE(message_store_.receiver_messages.empty());
246 EXPECT_EQ(SenderMessage::Type::kOffer,
247 message_store_.sender_messages[0].type);
248 EXPECT_TRUE(message_store_.sender_messages[0].valid);
249 message_store_.sender_messages.clear();
250
251 EXPECT_TRUE(receiver_messenger_
252 .SendMessage(ReceiverMessage{
253 ReceiverMessage::Type::kAnswer, 42, false /* valid */,
254 ReceiverError{123, "Something real bad happened"}})
255 .ok());
256
257 EXPECT_TRUE(message_store_.sender_messages.empty());
258 ASSERT_EQ(1u, message_store_.receiver_messages.size());
259 EXPECT_EQ(ReceiverMessage::Type::kAnswer,
260 message_store_.receiver_messages[0].type);
261 EXPECT_FALSE(message_store_.receiver_messages[0].valid);
262
263 const auto& error =
264 absl::get<ReceiverError>(message_store_.receiver_messages[0].body);
265 EXPECT_EQ(123, error.code);
266 EXPECT_EQ("Something real bad happened", error.description);
267 }
268
TEST_F(SessionMessengerTest,UnexpectedMessagesAreIgnored)269 TEST_F(SessionMessengerTest, UnexpectedMessagesAreIgnored) {
270 EXPECT_FALSE(receiver_messenger_
271 .SendMessage(ReceiverMessage{
272 ReceiverMessage::Type::kCapabilitiesResponse, 3123,
273 true /* valid */,
274 ReceiverCapability{2, {MediaCapability::kH264}}})
275 .ok());
276
277 // The message gets dropped and thus won't be in the store.
278 EXPECT_TRUE(message_store_.sender_messages.empty());
279 EXPECT_TRUE(message_store_.receiver_messages.empty());
280 }
281
TEST_F(SessionMessengerTest,UnknownSenderMessageTypesDontGetSent)282 TEST_F(SessionMessengerTest, UnknownSenderMessageTypesDontGetSent) {
283 EXPECT_DEATH(sender_messenger_
284 .SendOutboundMessage(SenderMessage{
285 SenderMessage::Type::kUnknown, 123, true /* valid */})
286 .ok(),
287 ".*Trying to send an unknown message is a developer error.*");
288 }
289
TEST_F(SessionMessengerTest,UnknownReceiverMessageTypesDontGetSent)290 TEST_F(SessionMessengerTest, UnknownReceiverMessageTypesDontGetSent) {
291 ASSERT_TRUE(sender_messenger_
292 .SendRequest(SenderMessage{SenderMessage::Type::kOffer, 42,
293 true /* valid */, kExampleOffer},
294 ReceiverMessage::Type::kAnswer,
295 message_store_.GetReplyCallback())
296 .ok());
297
298 EXPECT_DEATH(receiver_messenger_
299 .SendMessage(ReceiverMessage{ReceiverMessage::Type::kUnknown,
300 3123, true /* valid */})
301 .ok(),
302 ".*Trying to send an unknown message is a developer error.*");
303 }
304
TEST_F(SessionMessengerTest,ReceiverHandlesUnknownMessageType)305 TEST_F(SessionMessengerTest, ReceiverHandlesUnknownMessageType) {
306 pipe_.right()->ReceiveMessage(kCastWebrtcNamespace, R"({
307 "type": "GET_VIRTUAL_REALITY",
308 "seqNum": 31337
309 })");
310 ASSERT_TRUE(message_store_.errors.empty());
311 }
312
TEST_F(SessionMessengerTest,SenderHandlesUnknownMessageType)313 TEST_F(SessionMessengerTest, SenderHandlesUnknownMessageType) {
314 // The behavior on the sender side is a little more interesting: we
315 // test elsewhere that messages with the wrong sequence number are ignored,
316 // here if the type is unknown but the message contains a valid sequence
317 // number we just treat it as a bad response/same as a timeout.
318 ASSERT_TRUE(sender_messenger_
319 .SendRequest(SenderMessage{SenderMessage::Type::kOffer, 42,
320 true /* valid */, kExampleOffer},
321 ReceiverMessage::Type::kAnswer,
322 message_store_.GetReplyCallback())
323 .ok());
324 pipe_.left()->ReceiveMessage(kCastWebrtcNamespace, R"({
325 "type": "ANSWER_VERSION_2",
326 "seqNum": 42
327 })");
328
329 ASSERT_TRUE(message_store_.errors.empty());
330 ASSERT_EQ(1u, message_store_.receiver_messages.size());
331 ASSERT_EQ(ReceiverMessage::Type::kUnknown,
332 message_store_.receiver_messages[0].type);
333 ASSERT_EQ(false, message_store_.receiver_messages[0].valid);
334 }
335
TEST_F(SessionMessengerTest,SenderHandlesMessageMissingSequenceNumber)336 TEST_F(SessionMessengerTest, SenderHandlesMessageMissingSequenceNumber) {
337 ASSERT_TRUE(
338 sender_messenger_
339 .SendRequest(SenderMessage{SenderMessage::Type::kGetCapabilities, 42,
340 true /* valid */},
341 ReceiverMessage::Type::kCapabilitiesResponse,
342 message_store_.GetReplyCallback())
343 .ok());
344 pipe_.left()->ReceiveMessage(kCastWebrtcNamespace, R"({
345 "capabilities": {
346 "keySystems": [],
347 "mediaCaps": ["video"]
348 },
349 "result": "ok",
350 "type": "CAPABILITIES_RESPONSE"
351 })");
352
353 ASSERT_TRUE(message_store_.errors.empty());
354 ASSERT_TRUE(message_store_.receiver_messages.empty());
355 }
356
TEST_F(SessionMessengerTest,ReceiverCannotSendFirst)357 TEST_F(SessionMessengerTest, ReceiverCannotSendFirst) {
358 const Error error = receiver_messenger_.SendMessage(ReceiverMessage{
359 ReceiverMessage::Type::kCapabilitiesResponse, 3123, true /* valid */,
360 ReceiverCapability{2, {MediaCapability::kAudio}}});
361
362 EXPECT_EQ(Error::Code::kInitializationFailure, error.code());
363 }
364
TEST_F(SessionMessengerTest,ErrorMessageLoggedIfTimeout)365 TEST_F(SessionMessengerTest, ErrorMessageLoggedIfTimeout) {
366 ASSERT_TRUE(
367 sender_messenger_
368 .SendRequest(SenderMessage{SenderMessage::Type::kGetCapabilities,
369 3123, true /* valid */},
370 ReceiverMessage::Type::kCapabilitiesResponse,
371 message_store_.GetReplyCallback())
372 .ok());
373
374 ASSERT_EQ(1u, message_store_.sender_messages.size());
375 ASSERT_TRUE(message_store_.receiver_messages.empty());
376
377 clock_.Advance(std::chrono::seconds(10));
378 ASSERT_EQ(1u, message_store_.sender_messages.size());
379 ASSERT_EQ(1u, message_store_.receiver_messages.size());
380 EXPECT_EQ(3123, message_store_.receiver_messages[0].sequence_number);
381 EXPECT_EQ(ReceiverMessage::Type::kCapabilitiesResponse,
382 message_store_.receiver_messages[0].type);
383 EXPECT_FALSE(message_store_.receiver_messages[0].valid);
384 }
385
TEST_F(SessionMessengerTest,ReceiverRejectsMessageFromWrongSender)386 TEST_F(SessionMessengerTest, ReceiverRejectsMessageFromWrongSender) {
387 SimpleMessagePort port(kReceiverId);
388 ReceiverSessionMessenger messenger(&port, kReceiverId,
389 message_store_.GetErrorCallback());
390 messenger.SetHandler(SenderMessage::Type::kGetCapabilities,
391 message_store_.GetRequestCallback());
392
393 // The first message should be accepted since we don't have a set sender_id
394 // yet.
395 port.ReceiveMessage("sender-31337", kCastWebrtcNamespace, R"({
396 "seqNum": 820263769,
397 "type": "GET_CAPABILITIES"
398 })");
399 ASSERT_TRUE(message_store_.errors.empty());
400 ASSERT_EQ(1u, message_store_.sender_messages.size());
401 message_store_.sender_messages.clear();
402
403 // The second message should just be ignored.
404 port.ReceiveMessage("sender-42", kCastWebrtcNamespace, R"({
405 "seqNum": 1234,
406 "type": "GET_CAPABILITIES"
407 })");
408 ASSERT_TRUE(message_store_.errors.empty());
409 ASSERT_TRUE(message_store_.sender_messages.empty());
410
411 // But the third message should be accepted again since it's from the
412 // first sender.
413 port.ReceiveMessage("sender-31337", kCastWebrtcNamespace, R"({
414 "seqNum": 820263769,
415 "type": "GET_CAPABILITIES"
416 })");
417 ASSERT_TRUE(message_store_.errors.empty());
418 ASSERT_EQ(1u, message_store_.sender_messages.size());
419 }
420
TEST_F(SessionMessengerTest,SenderRejectsMessageFromWrongSender)421 TEST_F(SessionMessengerTest, SenderRejectsMessageFromWrongSender) {
422 SimpleMessagePort port(kReceiverId);
423 SenderSessionMessenger messenger(&port, kSenderId, kReceiverId,
424 message_store_.GetErrorCallback(),
425 &task_runner_);
426
427 port.ReceiveMessage("receiver-31337", kCastWebrtcNamespace, R"({
428 "seqNum": 12345,
429 "sessionId": 735189,
430 "type": "RPC",
431 "result": "ok",
432 "rpc": "SGVsbG8gZnJvbSB0aGUgQ2FzdCBSZWNlaXZlciE="
433 })");
434
435 // The message should just be ignored.
436 ASSERT_TRUE(message_store_.errors.empty());
437 ASSERT_TRUE(message_store_.sender_messages.empty());
438 ASSERT_TRUE(message_store_.receiver_messages.empty());
439 }
440
TEST_F(SessionMessengerTest,ReceiverRejectsMessagesWithoutHandler)441 TEST_F(SessionMessengerTest, ReceiverRejectsMessagesWithoutHandler) {
442 SimpleMessagePort port(kReceiverId);
443 ReceiverSessionMessenger messenger(&port, kReceiverId,
444 message_store_.GetErrorCallback());
445 messenger.SetHandler(SenderMessage::Type::kGetCapabilities,
446 message_store_.GetRequestCallback());
447
448 // The first message should be accepted since we don't have a set sender_id
449 // yet.
450 port.ReceiveMessage("sender-31337", kCastWebrtcNamespace, R"({
451 "seqNum": 820263769,
452 "type": "GET_CAPABILITIES"
453 })");
454 ASSERT_TRUE(message_store_.errors.empty());
455 ASSERT_EQ(1u, message_store_.sender_messages.size());
456 message_store_.sender_messages.clear();
457
458 // The second message should be rejected since it doesn't have a handler.
459 port.ReceiveMessage("sender-31337", kCastWebrtcNamespace, R"({
460 "seqNum": 820263770,
461 "type": "RPC"
462 })");
463 ASSERT_TRUE(message_store_.errors.empty());
464 ASSERT_TRUE(message_store_.sender_messages.empty());
465 }
466
TEST_F(SessionMessengerTest,SenderRejectsMessagesWithoutHandler)467 TEST_F(SessionMessengerTest, SenderRejectsMessagesWithoutHandler) {
468 SimpleMessagePort port(kReceiverId);
469 SenderSessionMessenger messenger(&port, kSenderId, kReceiverId,
470 message_store_.GetErrorCallback(),
471 &task_runner_);
472
473 port.ReceiveMessage(kReceiverId, kCastWebrtcNamespace, R"({
474 "seqNum": 12345,
475 "sessionId": 735189,
476 "type": "RPC",
477 "result": "ok",
478 "rpc": "SGVsbG8gZnJvbSB0aGUgQ2FzdCBSZWNlaXZlciE="
479 })");
480
481 // The message should just be ignored.
482 ASSERT_TRUE(message_store_.errors.empty());
483 ASSERT_TRUE(message_store_.sender_messages.empty());
484 ASSERT_TRUE(message_store_.receiver_messages.empty());
485 }
486
TEST_F(SessionMessengerTest,UnknownNamespaceMessagesGetDropped)487 TEST_F(SessionMessengerTest, UnknownNamespaceMessagesGetDropped) {
488 pipe_.right()->ReceiveMessage("urn:x-cast:com.google.cast.virtualreality",
489 R"({
490 "seqNum": 12345,
491 "sessionId": 735190,
492 "type": "RPC",
493 "rpc": "SGVsbG8gZnJvbSB0aGUgQ2FzdCBSZWNlaXZlciE="
494 })");
495
496 pipe_.left()->ReceiveMessage("urn:x-cast:com.google.cast.virtualreality", R"({
497 "seqNum": 12345,
498 "sessionId": 735190,
499 "type": "RPC",
500 "result": "ok",
501 "rpc": "SGVsbG8gZnJvbSB0aGUgQ2FzdCBTZW5kZXIh="
502 })");
503
504 // The message should just be ignored.
505 ASSERT_TRUE(message_store_.errors.empty());
506 ASSERT_TRUE(message_store_.sender_messages.empty());
507 ASSERT_TRUE(message_store_.receiver_messages.empty());
508 }
509
510 } // namespace cast
511 } // namespace openscreen
512