1 // Copyright 2019 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/receiver_session.h"
6
7 #include <utility>
8
9 #include "cast/streaming/mock_environment.h"
10 #include "cast/streaming/receiver.h"
11 #include "cast/streaming/testing/simple_message_port.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 #include "platform/base/ip_address.h"
15 #include "platform/test/fake_clock.h"
16 #include "platform/test/fake_task_runner.h"
17 #include "util/chrono_helpers.h"
18 #include "util/json/json_serialization.h"
19
20 using ::testing::_;
21 using ::testing::InSequence;
22 using ::testing::Invoke;
23 using ::testing::NiceMock;
24 using ::testing::Return;
25 using ::testing::StrictMock;
26
27 namespace openscreen {
28 namespace cast {
29
30 namespace {
31
32 constexpr char kValidOfferMessage[] = R"({
33 "type": "OFFER",
34 "seqNum": 1337,
35 "offer": {
36 "castMode": "mirroring",
37 "supportedStreams": [
38 {
39 "index": 31337,
40 "type": "video_source",
41 "codecName": "vp9",
42 "rtpProfile": "cast",
43 "rtpPayloadType": 127,
44 "ssrc": 19088743,
45 "maxFrameRate": "60000/1000",
46 "timeBase": "1/90000",
47 "maxBitRate": 5000000,
48 "profile": "main",
49 "level": "4",
50 "aesKey": "bbf109bf84513b456b13a184453b66ce",
51 "aesIvMask": "edaf9e4536e2b66191f560d9c04b2a69",
52 "resolutions": [
53 {
54 "width": 1280,
55 "height": 720
56 }
57 ]
58 },
59 {
60 "index": 31338,
61 "type": "video_source",
62 "codecName": "vp8",
63 "rtpProfile": "cast",
64 "rtpPayloadType": 127,
65 "ssrc": 19088745,
66 "maxFrameRate": "60000/1000",
67 "timeBase": "1/90000",
68 "maxBitRate": 5000000,
69 "profile": "main",
70 "level": "4",
71 "aesKey": "040d756791711fd3adb939066e6d8690",
72 "aesIvMask": "9ff0f022a959150e70a2d05a6c184aed",
73 "resolutions": [
74 {
75 "width": 1280,
76 "height": 720
77 }
78 ]
79 },
80 {
81 "index": 31339,
82 "type": "video_source",
83 "codecName": "hevc",
84 "codecParameter": "hev1.1.6.L150.B0",
85 "rtpProfile": "cast",
86 "rtpPayloadType": 127,
87 "ssrc": 19088746,
88 "maxFrameRate": "120",
89 "timeBase": "1/90000",
90 "maxBitRate": 5000000,
91 "aesKey": "040d756791711fd3adb939066e6d8690",
92 "aesIvMask": "9ff0f022a959150e70a2d05a6c184aed",
93 "resolutions": [
94 {
95 "width": 1920,
96 "height": 1080
97 }
98 ]
99 },
100 {
101 "index": 1337,
102 "type": "audio_source",
103 "codecName": "opus",
104 "rtpProfile": "cast",
105 "rtpPayloadType": 97,
106 "ssrc": 19088747,
107 "bitRate": 124000,
108 "timeBase": "1/48000",
109 "channels": 2,
110 "aesKey": "51027e4e2347cbcb49d57ef10177aebc",
111 "aesIvMask": "7f12a19be62a36c04ae4116caaeff6d1"
112 }
113 ]
114 }
115 })";
116
117 constexpr char kValidRemotingOfferMessage[] = R"({
118 "type": "OFFER",
119 "seqNum": 419,
120 "offer": {
121 "castMode": "remoting",
122 "supportedStreams": [
123 {
124 "index": 31339,
125 "type": "video_source",
126 "codecName": "REMOTE_VIDEO",
127 "rtpProfile": "cast",
128 "rtpPayloadType": 127,
129 "ssrc": 19088745,
130 "maxFrameRate": "60000/1000",
131 "timeBase": "1/90000",
132 "maxBitRate": 5432101,
133 "aesKey": "040d756791711fd3adb939066e6d8690",
134 "aesIvMask": "9ff0f022a959150e70a2d05a6c184aed",
135 "resolutions": [
136 {
137 "width": 1920,
138 "height":1080
139 }
140 ]
141 },
142 {
143 "index": 31340,
144 "type": "audio_source",
145 "codecName": "REMOTE_AUDIO",
146 "rtpProfile": "cast",
147 "rtpPayloadType": 97,
148 "ssrc": 19088747,
149 "bitRate": 125000,
150 "timeBase": "1/48000",
151 "channels": 2,
152 "aesKey": "51027e4e2347cbcb49d57ef10177aebc",
153 "aesIvMask": "7f12a19be62a36c04ae4116caaeff6d1"
154 }
155 ]
156 }
157 })";
158
159 constexpr char kNoAudioOfferMessage[] = R"({
160 "type": "OFFER",
161 "seqNum": 1337,
162 "offer": {
163 "castMode": "mirroring",
164 "supportedStreams": [
165 {
166 "index": 31338,
167 "type": "video_source",
168 "codecName": "vp8",
169 "rtpProfile": "cast",
170 "rtpPayloadType": 127,
171 "ssrc": 19088745,
172 "maxFrameRate": "60000/1000",
173 "timeBase": "1/90000",
174 "maxBitRate": 5000000,
175 "profile": "main",
176 "level": "4",
177 "aesKey": "040d756791711fd3adb939066e6d8690",
178 "aesIvMask": "9ff0f022a959150e70a2d05a6c184aed",
179 "resolutions": [
180 {
181 "width": 1280,
182 "height": 720
183 }
184 ]
185 }
186 ]
187 }
188 })";
189
190 constexpr char kInvalidCodecOfferMessage[] = R"({
191 "type": "OFFER",
192 "seqNum": 1337,
193 "offer": {
194 "castMode": "mirroring",
195 "supportedStreams": [
196 {
197 "index": 31338,
198 "type": "video_source",
199 "codecName": "vp12",
200 "rtpProfile": "cast",
201 "rtpPayloadType": 127,
202 "ssrc": 19088745,
203 "maxFrameRate": "60000/1000",
204 "timeBase": "1/90000",
205 "maxBitRate": 5000000,
206 "profile": "main",
207 "level": "4",
208 "aesKey": "040d756791711fd3adb939066e6d8690",
209 "aesIvMask": "9ff0f022a959150e70a2d05a6c184aed",
210 "resolutions": [
211 {
212 "width": 1280,
213 "height": 720
214 }
215 ]
216 }
217 ]
218 }
219 })";
220
221 constexpr char kNoVideoOfferMessage[] = R"({
222 "type": "OFFER",
223 "seqNum": 1337,
224 "offer": {
225 "castMode": "mirroring",
226 "supportedStreams": [
227 {
228 "index": 1337,
229 "type": "audio_source",
230 "codecName": "opus",
231 "rtpProfile": "cast",
232 "rtpPayloadType": 97,
233 "ssrc": 19088747,
234 "bitRate": 124000,
235 "timeBase": "1/48000",
236 "channels": 2,
237 "aesKey": "51027e4e2347cbcb49d57ef10177aebc",
238 "aesIvMask": "7f12a19be62a36c04ae4116caaeff6d1"
239 }
240 ]
241 }
242 })";
243
244 constexpr char kNoAudioOrVideoOfferMessage[] = R"({
245 "type": "OFFER",
246 "seqNum": 1337,
247 "offer": {
248 "castMode": "mirroring",
249 "supportedStreams": []
250 }
251 })";
252
253 constexpr char kInvalidJsonOfferMessage[] = R"({
254 "type": "OFFER",
255 "seqNum": 1337,
256 "offer": {
257 "castMode": "mirroring",
258 "supportedStreams": [
259 }
260 })";
261
262 constexpr char kMissingMandatoryFieldOfferMessage[] = R"({
263 "type": "OFFER",
264 "seqNum": 1337
265 })";
266
267 constexpr char kMissingSeqNumOfferMessage[] = R"({
268 "type": "OFFER",
269 "offer": {
270 "castMode": "mirroring",
271 "supportedStreams": []
272 }
273 })";
274
275 constexpr char kValidJsonInvalidFormatOfferMessage[] = R"({
276 "type": "OFFER",
277 "seqNum": 1337,
278 "offer": {
279 "castMode": "mirroring",
280 "supportedStreams": "anything"
281 }
282 })";
283
284 constexpr char kNullJsonOfferMessage[] = R"({
285 "type": "OFFER",
286 "seqNum": 1337
287 })";
288
289 constexpr char kInvalidSequenceNumberMessage[] = R"({
290 "type": "OFFER",
291 "seqNum": "not actually a number"
292 })";
293
294 constexpr char kUnknownTypeMessage[] = R"({
295 "type": "OFFER_VERSION_2",
296 "seqNum": 1337
297 })";
298
299 constexpr char kInvalidTypeMessage[] = R"({
300 "type": 39,
301 "seqNum": 1337
302 })";
303
304 constexpr char kGetCapabilitiesMessage[] = R"({
305 "seqNum": 820263770,
306 "type": "GET_CAPABILITIES"
307 })";
308
309 constexpr char kRpcMessage[] = R"({
310 "rpc" : "CGQQnBiCGQgSAggMGgIIBg==",
311 "seqNum" : 2,
312 "type" : "RPC"
313 })";
314
315 class FakeClient : public ReceiverSession::Client {
316 public:
317 MOCK_METHOD(void,
318 OnNegotiated,
319 (const ReceiverSession*, ReceiverSession::ConfiguredReceivers),
320 (override));
321 MOCK_METHOD(void,
322 OnRemotingNegotiated,
323 (const ReceiverSession*, ReceiverSession::RemotingNegotiation),
324 (override));
325 MOCK_METHOD(void,
326 OnReceiversDestroying,
327 (const ReceiverSession*, ReceiversDestroyingReason),
328 (override));
329 MOCK_METHOD(void, OnError, (const ReceiverSession*, Error error), (override));
330 MOCK_METHOD(bool,
331 SupportsCodecParameter,
332 (const std::string& parameter),
333 (override));
334 };
335
ExpectIsErrorAnswerMessage(const ErrorOr<Json::Value> & message_or_error)336 void ExpectIsErrorAnswerMessage(const ErrorOr<Json::Value>& message_or_error) {
337 EXPECT_TRUE(message_or_error.is_value());
338 const Json::Value message = std::move(message_or_error.value());
339 EXPECT_TRUE(message["answer"].isNull());
340 EXPECT_EQ("error", message["result"].asString());
341 EXPECT_EQ(1337, message["seqNum"].asInt());
342 EXPECT_EQ("ANSWER", message["type"].asString());
343
344 const Json::Value& error = message["error"];
345 EXPECT_TRUE(error.isObject());
346 EXPECT_GT(error["code"].asInt(), 0);
347 }
348
349 } // namespace
350
351 class ReceiverSessionTest : public ::testing::Test {
352 public:
ReceiverSessionTest()353 ReceiverSessionTest() : clock_(Clock::time_point{}), task_runner_(&clock_) {}
354
MakeEnvironment()355 std::unique_ptr<MockEnvironment> MakeEnvironment() {
356 auto environment_ = std::make_unique<NiceMock<MockEnvironment>>(
357 &FakeClock::now, &task_runner_);
358 ON_CALL(*environment_, GetBoundLocalEndpoint())
359 .WillByDefault(Return(IPEndpoint{{127, 0, 0, 1}, 12345}));
360 environment_->set_socket_state_for_testing(
361 Environment::SocketState::kReady);
362 return environment_;
363 }
364
SetUp()365 void SetUp() { SetUpWithPreferences(ReceiverSession::Preferences{}); }
366
367 // Since preferences are constant throughout the life of a session,
368 // changing them requires configuring a new session.
SetUpWithPreferences(ReceiverSession::Preferences preferences)369 void SetUpWithPreferences(ReceiverSession::Preferences preferences) {
370 session_.reset();
371 message_port_ = std::make_unique<SimpleMessagePort>("sender-12345");
372 environment_ = MakeEnvironment();
373 session_ = std::make_unique<ReceiverSession>(&client_, environment_.get(),
374 message_port_.get(),
375 std::move(preferences));
376 }
377
378 protected:
AssertGotAnErrorAnswerResponse()379 void AssertGotAnErrorAnswerResponse() {
380 const auto& messages = message_port_->posted_messages();
381 ASSERT_EQ(1u, messages.size());
382
383 auto message_body = json::Parse(messages[0]);
384 ExpectIsErrorAnswerMessage(message_body);
385 }
386
387 StrictMock<FakeClient> client_;
388 FakeClock clock_;
389 std::unique_ptr<MockEnvironment> environment_;
390 std::unique_ptr<SimpleMessagePort> message_port_;
391 std::unique_ptr<ReceiverSession> session_;
392 FakeTaskRunner task_runner_;
393 };
394
TEST_F(ReceiverSessionTest,CanNegotiateWithDefaultPreferences)395 TEST_F(ReceiverSessionTest, CanNegotiateWithDefaultPreferences) {
396 InSequence s;
397 EXPECT_CALL(client_, OnNegotiated(session_.get(), _))
398 .WillOnce([](const ReceiverSession* session_,
399 ReceiverSession::ConfiguredReceivers cr) {
400 EXPECT_TRUE(cr.audio_receiver);
401 EXPECT_EQ(cr.audio_receiver->config().sender_ssrc, 19088747u);
402 EXPECT_EQ(cr.audio_receiver->config().receiver_ssrc, 19088748u);
403 EXPECT_EQ(cr.audio_receiver->config().channels, 2);
404 EXPECT_EQ(cr.audio_receiver->config().rtp_timebase, 48000);
405
406 // We should have chosen opus
407 EXPECT_EQ(cr.audio_config.codec, AudioCodec::kOpus);
408
409 EXPECT_TRUE(cr.video_receiver);
410 EXPECT_EQ(cr.video_receiver->config().sender_ssrc, 19088745u);
411 EXPECT_EQ(cr.video_receiver->config().receiver_ssrc, 19088746u);
412 EXPECT_EQ(cr.video_receiver->config().channels, 1);
413 EXPECT_EQ(cr.video_receiver->config().rtp_timebase, 90000);
414
415 // We should have chosen vp8
416 EXPECT_EQ(cr.video_config.codec, VideoCodec::kVp8);
417 });
418 EXPECT_CALL(client_,
419 OnReceiversDestroying(session_.get(),
420 ReceiverSession::Client::kEndOfSession));
421
422 message_port_->ReceiveMessage(kValidOfferMessage);
423
424 const auto& messages = message_port_->posted_messages();
425 ASSERT_EQ(1u, messages.size());
426
427 auto message_body = json::Parse(messages[0]);
428 EXPECT_TRUE(message_body.is_value());
429 const Json::Value answer = std::move(message_body.value());
430
431 EXPECT_EQ("ANSWER", answer["type"].asString());
432 EXPECT_EQ(1337, answer["seqNum"].asInt());
433 EXPECT_EQ("ok", answer["result"].asString());
434
435 const Json::Value& answer_body = answer["answer"];
436 EXPECT_TRUE(answer_body.isObject());
437
438 // Spot check the answer body fields. We have more in depth testing
439 // of answer behavior in answer_messages_unittest, but here we can
440 // ensure that the ReceiverSession properly configured the answer.
441 EXPECT_EQ(1337, answer_body["sendIndexes"][0].asInt());
442 EXPECT_EQ(31338, answer_body["sendIndexes"][1].asInt());
443 EXPECT_LT(0, answer_body["udpPort"].asInt());
444 EXPECT_GT(65535, answer_body["udpPort"].asInt());
445
446 // Constraints and display should not be present with no preferences.
447 EXPECT_TRUE(answer_body["constraints"].isNull());
448 EXPECT_TRUE(answer_body["display"].isNull());
449 }
450
TEST_F(ReceiverSessionTest,CanNegotiateWithCustomCodecPreferences)451 TEST_F(ReceiverSessionTest, CanNegotiateWithCustomCodecPreferences) {
452 ReceiverSession session(
453 &client_, environment_.get(), message_port_.get(),
454 ReceiverSession::Preferences{{VideoCodec::kVp9}, {AudioCodec::kOpus}});
455
456 InSequence s;
457 EXPECT_CALL(client_, OnNegotiated(&session, _))
458 .WillOnce([](const ReceiverSession* session_,
459 ReceiverSession::ConfiguredReceivers cr) {
460 EXPECT_TRUE(cr.audio_receiver);
461 EXPECT_EQ(cr.audio_receiver->config().sender_ssrc, 19088747u);
462 EXPECT_EQ(cr.audio_receiver->config().receiver_ssrc, 19088748u);
463 EXPECT_EQ(cr.audio_receiver->config().channels, 2);
464 EXPECT_EQ(cr.audio_receiver->config().rtp_timebase, 48000);
465 EXPECT_EQ(cr.audio_config.codec, AudioCodec::kOpus);
466
467 EXPECT_TRUE(cr.video_receiver);
468 EXPECT_EQ(cr.video_receiver->config().sender_ssrc, 19088743u);
469 EXPECT_EQ(cr.video_receiver->config().receiver_ssrc, 19088744u);
470 EXPECT_EQ(cr.video_receiver->config().channels, 1);
471 EXPECT_EQ(cr.video_receiver->config().rtp_timebase, 90000);
472 EXPECT_EQ(cr.video_config.codec, VideoCodec::kVp9);
473 });
474 EXPECT_CALL(client_, OnReceiversDestroying(
475 &session, ReceiverSession::Client::kEndOfSession));
476 message_port_->ReceiveMessage(kValidOfferMessage);
477 }
478
TEST_F(ReceiverSessionTest,RejectsStreamWithUnsupportedCodecParameter)479 TEST_F(ReceiverSessionTest, RejectsStreamWithUnsupportedCodecParameter) {
480 ReceiverSession::Preferences preferences({VideoCodec::kHevc},
481 {AudioCodec::kOpus});
482 EXPECT_CALL(client_, SupportsCodecParameter(_)).WillRepeatedly(Return(false));
483 ReceiverSession session(&client_, environment_.get(), message_port_.get(),
484 preferences);
485 InSequence s;
486 EXPECT_CALL(client_, OnNegotiated(&session, _))
487 .WillOnce([](const ReceiverSession* session_,
488 ReceiverSession::ConfiguredReceivers cr) {
489 EXPECT_FALSE(cr.video_receiver);
490 });
491 EXPECT_CALL(client_, OnReceiversDestroying(
492 &session, ReceiverSession::Client::kEndOfSession));
493 message_port_->ReceiveMessage(kValidOfferMessage);
494 }
495
TEST_F(ReceiverSessionTest,AcceptsStreamWithNoCodecParameter)496 TEST_F(ReceiverSessionTest, AcceptsStreamWithNoCodecParameter) {
497 ReceiverSession::Preferences preferences(
498 {VideoCodec::kHevc, VideoCodec::kVp9}, {AudioCodec::kOpus});
499 EXPECT_CALL(client_, SupportsCodecParameter(_)).WillRepeatedly(Return(false));
500
501 ReceiverSession session(&client_, environment_.get(), message_port_.get(),
502 std::move(preferences));
503 InSequence s;
504 EXPECT_CALL(client_, OnNegotiated(&session, _))
505 .WillOnce([](const ReceiverSession* session_,
506 ReceiverSession::ConfiguredReceivers cr) {
507 EXPECT_TRUE(cr.video_receiver);
508 EXPECT_EQ(cr.video_config.codec, VideoCodec::kVp9);
509 });
510 EXPECT_CALL(client_, OnReceiversDestroying(
511 &session, ReceiverSession::Client::kEndOfSession));
512 message_port_->ReceiveMessage(kValidOfferMessage);
513 }
514
TEST_F(ReceiverSessionTest,AcceptsStreamWithMatchingParameter)515 TEST_F(ReceiverSessionTest, AcceptsStreamWithMatchingParameter) {
516 ReceiverSession::Preferences preferences({VideoCodec::kHevc},
517 {AudioCodec::kOpus});
518 EXPECT_CALL(client_, SupportsCodecParameter(_))
519 .WillRepeatedly(
520 [](const std::string& param) { return param == "hev1.1.6.L150.B0"; });
521
522 ReceiverSession session(&client_, environment_.get(), message_port_.get(),
523 std::move(preferences));
524 InSequence s;
525 EXPECT_CALL(client_, OnNegotiated(&session, _))
526 .WillOnce([](const ReceiverSession* session_,
527 ReceiverSession::ConfiguredReceivers cr) {
528 EXPECT_TRUE(cr.video_receiver);
529 EXPECT_EQ(cr.video_config.codec, VideoCodec::kHevc);
530 });
531 EXPECT_CALL(client_, OnReceiversDestroying(
532 &session, ReceiverSession::Client::kEndOfSession));
533 message_port_->ReceiveMessage(kValidOfferMessage);
534 }
535
TEST_F(ReceiverSessionTest,CanNegotiateWithLimits)536 TEST_F(ReceiverSessionTest, CanNegotiateWithLimits) {
537 std::vector<ReceiverSession::AudioLimits> audio_limits = {
538 {false, AudioCodec::kOpus, 48001, 2, 32001, 32002, milliseconds(3001)}};
539 std::vector<ReceiverSession::VideoLimits> video_limits = {
540 {true,
541 VideoCodec::kVp9,
542 62208000,
543 {1920, 1080, {144, 1}},
544 300000,
545 90000000,
546 milliseconds(1000)}};
547
548 auto display =
549 std::make_unique<ReceiverSession::Display>(ReceiverSession::Display{
550 {640, 480, {60, 1}}, false /* can scale content */});
551
552 ReceiverSession session(&client_, environment_.get(), message_port_.get(),
553 ReceiverSession::Preferences{{VideoCodec::kVp9},
554 {AudioCodec::kOpus},
555 std::move(audio_limits),
556 std::move(video_limits),
557 std::move(display)});
558
559 InSequence s;
560 EXPECT_CALL(client_, OnNegotiated(&session, _));
561 EXPECT_CALL(client_, OnReceiversDestroying(
562 &session, ReceiverSession::Client::kEndOfSession));
563 message_port_->ReceiveMessage(kValidOfferMessage);
564
565 const auto& messages = message_port_->posted_messages();
566 ASSERT_EQ(1u, messages.size());
567
568 auto message_body = json::Parse(messages[0]);
569 ASSERT_TRUE(message_body.is_value());
570 const Json::Value answer = std::move(message_body.value());
571
572 const Json::Value& answer_body = answer["answer"];
573 ASSERT_TRUE(answer_body.isObject()) << messages[0];
574
575 // Constraints and display should be valid with valid preferences.
576 ASSERT_FALSE(answer_body["constraints"].isNull());
577 ASSERT_FALSE(answer_body["display"].isNull());
578
579 const Json::Value& display_json = answer_body["display"];
580 EXPECT_EQ("60", display_json["dimensions"]["frameRate"].asString());
581 EXPECT_EQ(640, display_json["dimensions"]["width"].asInt());
582 EXPECT_EQ(480, display_json["dimensions"]["height"].asInt());
583 EXPECT_EQ("sender", display_json["scaling"].asString());
584
585 const Json::Value& constraints_json = answer_body["constraints"];
586 ASSERT_TRUE(constraints_json.isObject());
587
588 const Json::Value& audio = constraints_json["audio"];
589 ASSERT_TRUE(audio.isObject());
590 EXPECT_EQ(32002, audio["maxBitRate"].asInt());
591 EXPECT_EQ(2, audio["maxChannels"].asInt());
592 EXPECT_EQ(3001, audio["maxDelay"].asInt());
593 EXPECT_EQ(48001, audio["maxSampleRate"].asInt());
594 EXPECT_EQ(32001, audio["minBitRate"].asInt());
595
596 const Json::Value& video = constraints_json["video"];
597 ASSERT_TRUE(video.isObject());
598 EXPECT_EQ(90000000, video["maxBitRate"].asInt());
599 EXPECT_EQ(1000, video["maxDelay"].asInt());
600 EXPECT_EQ("144", video["maxDimensions"]["frameRate"].asString());
601 EXPECT_EQ(1920, video["maxDimensions"]["width"].asInt());
602 EXPECT_EQ(1080, video["maxDimensions"]["height"].asInt());
603 EXPECT_EQ(300000, video["minBitRate"].asInt());
604 }
605
TEST_F(ReceiverSessionTest,HandlesNoValidAudioStream)606 TEST_F(ReceiverSessionTest, HandlesNoValidAudioStream) {
607 InSequence s;
608 EXPECT_CALL(client_, OnNegotiated(session_.get(), _));
609 EXPECT_CALL(client_,
610 OnReceiversDestroying(session_.get(),
611 ReceiverSession::Client::kEndOfSession));
612
613 message_port_->ReceiveMessage(kNoAudioOfferMessage);
614 const auto& messages = message_port_->posted_messages();
615 EXPECT_EQ(1u, messages.size());
616
617 auto message_body = json::Parse(messages[0]);
618 EXPECT_TRUE(message_body.is_value());
619 const Json::Value& answer_body = message_body.value()["answer"];
620 EXPECT_TRUE(answer_body.isObject());
621
622 // Should still select video stream.
623 EXPECT_EQ(1u, answer_body["sendIndexes"].size());
624 EXPECT_EQ(31338, answer_body["sendIndexes"][0].asInt());
625 EXPECT_EQ(1u, answer_body["ssrcs"].size());
626 EXPECT_EQ(19088746, answer_body["ssrcs"][0].asInt());
627 }
628
TEST_F(ReceiverSessionTest,HandlesInvalidCodec)629 TEST_F(ReceiverSessionTest, HandlesInvalidCodec) {
630 // We didn't select any streams, but didn't have any errors either.
631 message_port_->ReceiveMessage(kInvalidCodecOfferMessage);
632 const auto& messages = message_port_->posted_messages();
633 EXPECT_EQ(1u, messages.size());
634
635 auto message_body = json::Parse(messages[0]);
636 EXPECT_TRUE(message_body.is_value());
637
638 // We should have failed to produce a valid answer message due to not
639 // selecting any stream.
640 EXPECT_EQ("error", message_body.value()["result"].asString());
641 }
642
TEST_F(ReceiverSessionTest,HandlesNoValidVideoStream)643 TEST_F(ReceiverSessionTest, HandlesNoValidVideoStream) {
644 InSequence s;
645 EXPECT_CALL(client_, OnNegotiated(session_.get(), _));
646 EXPECT_CALL(client_,
647 OnReceiversDestroying(session_.get(),
648 ReceiverSession::Client::kEndOfSession));
649
650 message_port_->ReceiveMessage(kNoVideoOfferMessage);
651 const auto& messages = message_port_->posted_messages();
652 EXPECT_EQ(1u, messages.size());
653
654 auto message_body = json::Parse(messages[0]);
655 EXPECT_TRUE(message_body.is_value());
656 const Json::Value& answer_body = message_body.value()["answer"];
657 EXPECT_TRUE(answer_body.isObject());
658
659 // Should still select audio stream.
660 EXPECT_EQ(1u, answer_body["sendIndexes"].size());
661 EXPECT_EQ(1337, answer_body["sendIndexes"][0].asInt());
662 EXPECT_EQ(1u, answer_body["ssrcs"].size());
663 EXPECT_EQ(19088748, answer_body["ssrcs"][0].asInt());
664 }
665
TEST_F(ReceiverSessionTest,HandlesNoValidStreams)666 TEST_F(ReceiverSessionTest, HandlesNoValidStreams) {
667 // We shouldn't call OnNegotiated if we failed to negotiate any streams.
668 message_port_->ReceiveMessage(kNoAudioOrVideoOfferMessage);
669 AssertGotAnErrorAnswerResponse();
670 }
671
TEST_F(ReceiverSessionTest,HandlesMalformedOffer)672 TEST_F(ReceiverSessionTest, HandlesMalformedOffer) {
673 // Note that unlike when we simply don't select any streams, when the offer
674 // is not valid JSON we actually have no way of knowing it's an offer at all,
675 // so we call OnError and do not reply with an Answer.
676 EXPECT_CALL(client_, OnError(session_.get(), _));
677 message_port_->ReceiveMessage(kInvalidJsonOfferMessage);
678 }
679
TEST_F(ReceiverSessionTest,HandlesMissingSeqNumInOffer)680 TEST_F(ReceiverSessionTest, HandlesMissingSeqNumInOffer) {
681 // If the OFFER is missing a sequence number it gets rejected before being
682 // parsed as an OFFER, since the sender expects all messages to come back
683 // with a sequence number.
684 message_port_->ReceiveMessage(kMissingSeqNumOfferMessage);
685 }
686
TEST_F(ReceiverSessionTest,HandlesOfferMissingMandatoryFields)687 TEST_F(ReceiverSessionTest, HandlesOfferMissingMandatoryFields) {
688 // If the OFFER is missing mandatory fields, we notify the client as well as
689 // reply with an error-case Answer.
690 EXPECT_CALL(client_, OnError(session_.get(), _));
691
692 message_port_->ReceiveMessage(kMissingMandatoryFieldOfferMessage);
693 AssertGotAnErrorAnswerResponse();
694 }
695
TEST_F(ReceiverSessionTest,HandlesImproperlyFormattedOffer)696 TEST_F(ReceiverSessionTest, HandlesImproperlyFormattedOffer) {
697 EXPECT_CALL(client_, OnError(session_.get(), _));
698 message_port_->ReceiveMessage(kValidJsonInvalidFormatOfferMessage);
699 AssertGotAnErrorAnswerResponse();
700 }
701
TEST_F(ReceiverSessionTest,HandlesNullOffer)702 TEST_F(ReceiverSessionTest, HandlesNullOffer) {
703 EXPECT_CALL(client_, OnError(session_.get(), _));
704 message_port_->ReceiveMessage(kNullJsonOfferMessage);
705 AssertGotAnErrorAnswerResponse();
706 }
707
TEST_F(ReceiverSessionTest,HandlesInvalidSequenceNumber)708 TEST_F(ReceiverSessionTest, HandlesInvalidSequenceNumber) {
709 // We should just discard messages with an invalid sequence number.
710 message_port_->ReceiveMessage(kInvalidSequenceNumberMessage);
711 }
712
TEST_F(ReceiverSessionTest,HandlesUnknownTypeMessage)713 TEST_F(ReceiverSessionTest, HandlesUnknownTypeMessage) {
714 // We should just discard messages with an unknown message type.
715 message_port_->ReceiveMessage(kUnknownTypeMessage);
716 }
717
TEST_F(ReceiverSessionTest,HandlesInvalidTypeMessage)718 TEST_F(ReceiverSessionTest, HandlesInvalidTypeMessage) {
719 // We should just discard messages with an invalid message type.
720 message_port_->ReceiveMessage(kInvalidTypeMessage);
721 }
722
TEST_F(ReceiverSessionTest,DoesNotCrashOnMessagePortError)723 TEST_F(ReceiverSessionTest, DoesNotCrashOnMessagePortError) {
724 message_port_->ReceiveError(Error(Error::Code::kUnknownError));
725 }
726
TEST_F(ReceiverSessionTest,NotifiesReceiverDestruction)727 TEST_F(ReceiverSessionTest, NotifiesReceiverDestruction) {
728 InSequence s;
729 EXPECT_CALL(client_, OnNegotiated(session_.get(), _));
730 EXPECT_CALL(client_,
731 OnReceiversDestroying(session_.get(),
732 ReceiverSession::Client::kRenegotiated));
733 EXPECT_CALL(client_, OnNegotiated(session_.get(), _));
734 EXPECT_CALL(client_,
735 OnReceiversDestroying(session_.get(),
736 ReceiverSession::Client::kEndOfSession));
737
738 message_port_->ReceiveMessage(kNoAudioOfferMessage);
739 message_port_->ReceiveMessage(kValidOfferMessage);
740 }
741
TEST_F(ReceiverSessionTest,HandlesInvalidAnswer)742 TEST_F(ReceiverSessionTest, HandlesInvalidAnswer) {
743 // Simulate an unbound local endpoint.
744 EXPECT_CALL(*environment_, GetBoundLocalEndpoint)
745 .WillOnce(Return(IPEndpoint{}));
746
747 message_port_->ReceiveMessage(kValidOfferMessage);
748 const auto& messages = message_port_->posted_messages();
749 ASSERT_EQ(1u, messages.size());
750
751 auto message_body = json::Parse(messages[0]);
752 EXPECT_TRUE(message_body.is_value());
753 const Json::Value answer = std::move(message_body.value());
754
755 EXPECT_EQ("ANSWER", answer["type"].asString());
756 EXPECT_EQ("error", answer["result"].asString());
757 }
758
TEST_F(ReceiverSessionTest,DelaysAnswerUntilEnvironmentIsReady)759 TEST_F(ReceiverSessionTest, DelaysAnswerUntilEnvironmentIsReady) {
760 environment_->set_socket_state_for_testing(
761 Environment::SocketState::kStarting);
762
763 // We should not have sent an answer yet--the UDP socket is not ready.
764 message_port_->ReceiveMessage(kValidOfferMessage);
765 ASSERT_TRUE(message_port_->posted_messages().empty());
766
767 // Simulate the environment calling back into us with the socket being ready.
768 // state() will not be called again--we just need to get the bind event.
769 EXPECT_CALL(*environment_, GetBoundLocalEndpoint())
770 .WillOnce(Return(IPEndpoint{{10, 0, 0, 2}, 4567}));
771 EXPECT_CALL(client_, OnNegotiated(session_.get(), _));
772 EXPECT_CALL(client_,
773 OnReceiversDestroying(session_.get(),
774 ReceiverSession::Client::kEndOfSession));
775 session_->OnSocketReady();
776 const auto& messages = message_port_->posted_messages();
777 ASSERT_EQ(1u, messages.size());
778
779 // We should have set the UDP port based on the ready socket value.
780 auto message_body = json::Parse(messages[0]);
781 EXPECT_TRUE(message_body.is_value());
782 const Json::Value& answer_body = message_body.value()["answer"];
783 EXPECT_TRUE(answer_body.isObject());
784 EXPECT_EQ(4567, answer_body["udpPort"].asInt());
785 }
786
TEST_F(ReceiverSessionTest,ReturnsErrorAnswerIfEnvironmentIsAlreadyInvalidated)787 TEST_F(ReceiverSessionTest,
788 ReturnsErrorAnswerIfEnvironmentIsAlreadyInvalidated) {
789 environment_->set_socket_state_for_testing(
790 Environment::SocketState::kInvalid);
791
792 // If the environment is already in a bad state, we can respond immediately.
793 message_port_->ReceiveMessage(kValidOfferMessage);
794 const auto& messages = message_port_->posted_messages();
795 ASSERT_EQ(1u, messages.size());
796
797 auto message_body = json::Parse(messages[0]);
798 EXPECT_TRUE(message_body.is_value());
799 EXPECT_EQ("ANSWER", message_body.value()["type"].asString());
800 EXPECT_EQ("error", message_body.value()["result"].asString());
801 }
802
TEST_F(ReceiverSessionTest,ReturnsErrorAnswerIfEnvironmentIsInvalidated)803 TEST_F(ReceiverSessionTest, ReturnsErrorAnswerIfEnvironmentIsInvalidated) {
804 environment_->set_socket_state_for_testing(
805 Environment::SocketState::kStarting);
806
807 // We should not have sent an answer yet--the environment is not ready.
808 message_port_->ReceiveMessage(kValidOfferMessage);
809 ASSERT_TRUE(message_port_->posted_messages().empty());
810
811 // Simulate the environment calling back into us with invalidation.
812 EXPECT_CALL(client_, OnError(_, _)).Times(1);
813 session_->OnSocketInvalid(Error::Code::kSocketBindFailure);
814 const auto& messages = message_port_->posted_messages();
815 ASSERT_EQ(1u, messages.size());
816
817 // We should have an error answer.
818 auto message_body = json::Parse(messages[0]);
819 EXPECT_TRUE(message_body.is_value());
820 EXPECT_EQ("ANSWER", message_body.value()["type"].asString());
821 EXPECT_EQ("error", message_body.value()["result"].asString());
822 }
823
TEST_F(ReceiverSessionTest,ReturnsErrorCapabilitiesIfRemotingDisabled)824 TEST_F(ReceiverSessionTest, ReturnsErrorCapabilitiesIfRemotingDisabled) {
825 message_port_->ReceiveMessage(kGetCapabilitiesMessage);
826 const auto& messages = message_port_->posted_messages();
827 ASSERT_EQ(1u, messages.size());
828
829 // We should have an error response.
830 auto message_body = json::Parse(messages[0]);
831 EXPECT_TRUE(message_body.is_value());
832 EXPECT_EQ("CAPABILITIES_RESPONSE", message_body.value()["type"].asString());
833 EXPECT_EQ("error", message_body.value()["result"].asString());
834 }
835
TEST_F(ReceiverSessionTest,ReturnsCapabilitiesWithRemotingDefaults)836 TEST_F(ReceiverSessionTest, ReturnsCapabilitiesWithRemotingDefaults) {
837 ReceiverSession::Preferences preferences;
838 preferences.remoting =
839 std::make_unique<ReceiverSession::RemotingPreferences>();
840
841 SetUpWithPreferences(std::move(preferences));
842 message_port_->ReceiveMessage(kGetCapabilitiesMessage);
843 const auto& messages = message_port_->posted_messages();
844 ASSERT_EQ(1u, messages.size());
845
846 // We should have an error response.
847 auto message_body = json::Parse(messages[0]);
848 EXPECT_TRUE(message_body.is_value());
849 EXPECT_EQ("CAPABILITIES_RESPONSE", message_body.value()["type"].asString());
850 EXPECT_EQ("ok", message_body.value()["result"].asString());
851 const ReceiverCapability response =
852 ReceiverCapability::Parse(message_body.value()["capabilities"]).value();
853
854 EXPECT_THAT(
855 response.media_capabilities,
856 testing::ElementsAre(MediaCapability::kOpus, MediaCapability::kAac,
857 MediaCapability::kVp8, MediaCapability::kH264));
858 }
859
TEST_F(ReceiverSessionTest,ReturnsCapabilitiesWithRemotingPreferences)860 TEST_F(ReceiverSessionTest, ReturnsCapabilitiesWithRemotingPreferences) {
861 ReceiverSession::Preferences preferences;
862 preferences.video_codecs = {VideoCodec::kH264};
863 preferences.remoting =
864 std::make_unique<ReceiverSession::RemotingPreferences>();
865 preferences.remoting->supports_chrome_audio_codecs = true;
866 preferences.remoting->supports_4k = true;
867
868 SetUpWithPreferences(std::move(preferences));
869 message_port_->ReceiveMessage(kGetCapabilitiesMessage);
870 const auto& messages = message_port_->posted_messages();
871 ASSERT_EQ(1u, messages.size());
872
873 // We should have an error response.
874 auto message_body = json::Parse(messages[0]);
875 EXPECT_TRUE(message_body.is_value());
876 EXPECT_EQ("CAPABILITIES_RESPONSE", message_body.value()["type"].asString());
877 EXPECT_EQ("ok", message_body.value()["result"].asString());
878 const ReceiverCapability response =
879 ReceiverCapability::Parse(message_body.value()["capabilities"]).value();
880
881 EXPECT_THAT(
882 response.media_capabilities,
883 testing::ElementsAre(MediaCapability::kOpus, MediaCapability::kAac,
884 MediaCapability::kH264, MediaCapability::kAudio,
885 MediaCapability::k4k));
886 }
887
TEST_F(ReceiverSessionTest,CanNegotiateRemoting)888 TEST_F(ReceiverSessionTest, CanNegotiateRemoting) {
889 ReceiverSession::Preferences preferences;
890 preferences.remoting =
891 std::make_unique<ReceiverSession::RemotingPreferences>();
892 preferences.remoting->supports_chrome_audio_codecs = true;
893 preferences.remoting->supports_4k = true;
894 SetUpWithPreferences(std::move(preferences));
895
896 InSequence s;
897 EXPECT_CALL(client_, OnRemotingNegotiated(session_.get(), _))
898 .WillOnce([](const ReceiverSession* session_,
899 ReceiverSession::RemotingNegotiation negotiation) {
900 const auto& cr = negotiation.receivers;
901 EXPECT_TRUE(cr.audio_receiver);
902 EXPECT_EQ(cr.audio_receiver->config().sender_ssrc, 19088747u);
903 EXPECT_EQ(cr.audio_receiver->config().receiver_ssrc, 19088748u);
904 EXPECT_EQ(cr.audio_receiver->config().channels, 2);
905 EXPECT_EQ(cr.audio_receiver->config().rtp_timebase, 48000);
906 EXPECT_EQ(cr.audio_config.codec, AudioCodec::kNotSpecified);
907
908 EXPECT_TRUE(cr.video_receiver);
909 EXPECT_EQ(cr.video_receiver->config().sender_ssrc, 19088745u);
910 EXPECT_EQ(cr.video_receiver->config().receiver_ssrc, 19088746u);
911 EXPECT_EQ(cr.video_receiver->config().channels, 1);
912 EXPECT_EQ(cr.video_receiver->config().rtp_timebase, 90000);
913 EXPECT_EQ(cr.video_config.codec, VideoCodec::kNotSpecified);
914 });
915 EXPECT_CALL(client_,
916 OnReceiversDestroying(session_.get(),
917 ReceiverSession::Client::kEndOfSession));
918
919 message_port_->ReceiveMessage(kValidRemotingOfferMessage);
920 }
921
TEST_F(ReceiverSessionTest,HandlesRpcMessage)922 TEST_F(ReceiverSessionTest, HandlesRpcMessage) {
923 ReceiverSession::Preferences preferences;
924 preferences.remoting =
925 std::make_unique<ReceiverSession::RemotingPreferences>();
926 preferences.remoting->supports_chrome_audio_codecs = true;
927 preferences.remoting->supports_4k = true;
928 SetUpWithPreferences(std::move(preferences));
929
930 message_port_->ReceiveMessage(kRpcMessage);
931 const auto& messages = message_port_->posted_messages();
932 // Nothing should happen yet, the session doesn't have a messenger.
933 ASSERT_EQ(0u, messages.size());
934
935 // We don't need to fully test that the subscription model on the RpcMessenger
936 // works, but we do want to test that the ReceiverSession has properly wired
937 // the RpcMessenger up to the backing SessionMessenger and can properly
938 // handle received RPC messages.
939 InSequence s;
940 bool received_initialize_message = false;
941 EXPECT_CALL(client_, OnRemotingNegotiated(session_.get(), _))
942 .WillOnce([this, &received_initialize_message](
943 const ReceiverSession* session_,
944 ReceiverSession::RemotingNegotiation negotiation) mutable {
945 negotiation.messenger->RegisterMessageReceiverCallback(
946 100, [&received_initialize_message](
947 std::unique_ptr<RpcMessage> message) mutable {
948 ASSERT_EQ(100, message->handle());
949 ASSERT_EQ(RpcMessage::RPC_DS_INITIALIZE_CALLBACK,
950 message->proc());
951 ASSERT_EQ(0, message->integer_value());
952 received_initialize_message = true;
953 });
954
955 message_port_->ReceiveMessage(kRpcMessage);
956 });
957 EXPECT_CALL(client_,
958 OnReceiversDestroying(session_.get(),
959 ReceiverSession::Client::kEndOfSession));
960
961 message_port_->ReceiveMessage(kValidRemotingOfferMessage);
962 ASSERT_TRUE(received_initialize_message);
963 }
964
TEST_F(ReceiverSessionTest,VideoLimitsIsSupersetOf)965 TEST_F(ReceiverSessionTest, VideoLimitsIsSupersetOf) {
966 ReceiverSession::VideoLimits first{};
967 ReceiverSession::VideoLimits second = first;
968
969 EXPECT_TRUE(first.IsSupersetOf(second));
970 EXPECT_TRUE(second.IsSupersetOf(first));
971
972 first.max_pixels_per_second += 1;
973 EXPECT_TRUE(first.IsSupersetOf(second));
974 EXPECT_FALSE(second.IsSupersetOf(first));
975 first.max_pixels_per_second = second.max_pixels_per_second;
976
977 first.max_dimensions = {1921, 1090, {kDefaultFrameRate, 1}};
978 EXPECT_TRUE(first.IsSupersetOf(second));
979 EXPECT_FALSE(second.IsSupersetOf(first));
980
981 second.max_dimensions = {1921, 1090, {kDefaultFrameRate + 1, 1}};
982 EXPECT_FALSE(first.IsSupersetOf(second));
983 EXPECT_TRUE(second.IsSupersetOf(first));
984
985 second.max_dimensions = {2000, 1000, {kDefaultFrameRate, 1}};
986 EXPECT_FALSE(first.IsSupersetOf(second));
987 EXPECT_FALSE(second.IsSupersetOf(first));
988 second.max_dimensions = first.max_dimensions;
989
990 first.min_bit_rate += 1;
991 EXPECT_FALSE(first.IsSupersetOf(second));
992 EXPECT_TRUE(second.IsSupersetOf(first));
993 first.min_bit_rate = second.min_bit_rate;
994
995 first.max_bit_rate += 1;
996 EXPECT_TRUE(first.IsSupersetOf(second));
997 EXPECT_FALSE(second.IsSupersetOf(first));
998 first.max_bit_rate = second.max_bit_rate;
999
1000 EXPECT_TRUE(first.IsSupersetOf(second));
1001 EXPECT_TRUE(second.IsSupersetOf(first));
1002
1003 first.applies_to_all_codecs = true;
1004 EXPECT_FALSE(first.IsSupersetOf(second));
1005 EXPECT_FALSE(second.IsSupersetOf(first));
1006 second.applies_to_all_codecs = true;
1007 EXPECT_TRUE(first.IsSupersetOf(second));
1008 EXPECT_TRUE(second.IsSupersetOf(first));
1009 first.codec = VideoCodec::kVp8;
1010 second.codec = VideoCodec::kVp9;
1011 EXPECT_TRUE(first.IsSupersetOf(second));
1012 EXPECT_TRUE(second.IsSupersetOf(first));
1013 first.applies_to_all_codecs = false;
1014 second.applies_to_all_codecs = false;
1015 EXPECT_FALSE(first.IsSupersetOf(second));
1016 EXPECT_FALSE(second.IsSupersetOf(first));
1017 }
1018
TEST_F(ReceiverSessionTest,AudioLimitsIsSupersetOf)1019 TEST_F(ReceiverSessionTest, AudioLimitsIsSupersetOf) {
1020 ReceiverSession::AudioLimits first{};
1021 ReceiverSession::AudioLimits second = first;
1022
1023 EXPECT_TRUE(first.IsSupersetOf(second));
1024 EXPECT_TRUE(second.IsSupersetOf(first));
1025
1026 first.max_sample_rate += 1;
1027 EXPECT_TRUE(first.IsSupersetOf(second));
1028 EXPECT_FALSE(second.IsSupersetOf(first));
1029 first.max_sample_rate = second.max_sample_rate;
1030
1031 first.max_channels += 1;
1032 EXPECT_TRUE(first.IsSupersetOf(second));
1033 EXPECT_FALSE(second.IsSupersetOf(first));
1034 first.max_channels = second.max_channels;
1035
1036 first.min_bit_rate += 1;
1037 EXPECT_FALSE(first.IsSupersetOf(second));
1038 EXPECT_TRUE(second.IsSupersetOf(first));
1039 first.min_bit_rate = second.min_bit_rate;
1040
1041 first.max_bit_rate += 1;
1042 EXPECT_TRUE(first.IsSupersetOf(second));
1043 EXPECT_FALSE(second.IsSupersetOf(first));
1044 first.max_bit_rate = second.max_bit_rate;
1045
1046 EXPECT_TRUE(first.IsSupersetOf(second));
1047 EXPECT_TRUE(second.IsSupersetOf(first));
1048
1049 first.applies_to_all_codecs = true;
1050 EXPECT_FALSE(first.IsSupersetOf(second));
1051 EXPECT_FALSE(second.IsSupersetOf(first));
1052 second.applies_to_all_codecs = true;
1053 EXPECT_TRUE(first.IsSupersetOf(second));
1054 EXPECT_TRUE(second.IsSupersetOf(first));
1055 first.codec = AudioCodec::kOpus;
1056 second.codec = AudioCodec::kAac;
1057 EXPECT_TRUE(first.IsSupersetOf(second));
1058 EXPECT_TRUE(second.IsSupersetOf(first));
1059 first.applies_to_all_codecs = false;
1060 second.applies_to_all_codecs = false;
1061 EXPECT_FALSE(first.IsSupersetOf(second));
1062 EXPECT_FALSE(second.IsSupersetOf(first));
1063 }
1064
TEST_F(ReceiverSessionTest,DisplayIsSupersetOf)1065 TEST_F(ReceiverSessionTest, DisplayIsSupersetOf) {
1066 ReceiverSession::Display first;
1067 ReceiverSession::Display second = first;
1068
1069 EXPECT_TRUE(first.IsSupersetOf(second));
1070 EXPECT_TRUE(second.IsSupersetOf(first));
1071
1072 first.dimensions = {1921, 1090, {kDefaultFrameRate, 1}};
1073 EXPECT_TRUE(first.IsSupersetOf(second));
1074 EXPECT_FALSE(second.IsSupersetOf(first));
1075
1076 second.dimensions = {1921, 1090, {kDefaultFrameRate + 1, 1}};
1077 EXPECT_FALSE(first.IsSupersetOf(second));
1078 EXPECT_TRUE(second.IsSupersetOf(first));
1079
1080 second.dimensions = {2000, 1000, {kDefaultFrameRate, 1}};
1081 EXPECT_FALSE(first.IsSupersetOf(second));
1082 EXPECT_FALSE(second.IsSupersetOf(first));
1083 second.dimensions = first.dimensions;
1084
1085 first.can_scale_content = true;
1086 EXPECT_TRUE(first.IsSupersetOf(second));
1087 EXPECT_FALSE(second.IsSupersetOf(first));
1088 }
1089
TEST_F(ReceiverSessionTest,RemotingPreferencesIsSupersetOf)1090 TEST_F(ReceiverSessionTest, RemotingPreferencesIsSupersetOf) {
1091 ReceiverSession::RemotingPreferences first;
1092 ReceiverSession::RemotingPreferences second = first;
1093
1094 EXPECT_TRUE(first.IsSupersetOf(second));
1095 EXPECT_TRUE(second.IsSupersetOf(first));
1096
1097 first.supports_chrome_audio_codecs = true;
1098 EXPECT_TRUE(first.IsSupersetOf(second));
1099 EXPECT_FALSE(second.IsSupersetOf(first));
1100
1101 second.supports_4k = true;
1102 EXPECT_FALSE(first.IsSupersetOf(second));
1103 EXPECT_FALSE(second.IsSupersetOf(first));
1104
1105 second.supports_chrome_audio_codecs = true;
1106 EXPECT_FALSE(first.IsSupersetOf(second));
1107 EXPECT_TRUE(second.IsSupersetOf(first));
1108 }
1109
TEST_F(ReceiverSessionTest,PreferencesIsSupersetOf)1110 TEST_F(ReceiverSessionTest, PreferencesIsSupersetOf) {
1111 ReceiverSession::Preferences first;
1112 ReceiverSession::Preferences second(first);
1113
1114 EXPECT_TRUE(first.IsSupersetOf(second));
1115 EXPECT_TRUE(second.IsSupersetOf(first));
1116
1117 // Modified |display_description|.
1118 first.display_description = std::make_unique<ReceiverSession::Display>();
1119 first.display_description->dimensions = {1920, 1080, {kDefaultFrameRate, 1}};
1120 EXPECT_FALSE(first.IsSupersetOf(second));
1121 EXPECT_FALSE(second.IsSupersetOf(first));
1122 second = first;
1123
1124 first.display_description->dimensions = {192, 1080, {kDefaultFrameRate, 1}};
1125 EXPECT_FALSE(first.IsSupersetOf(second));
1126 EXPECT_TRUE(second.IsSupersetOf(first));
1127 second = first;
1128
1129 // Modified |remoting|.
1130 first.remoting = std::make_unique<ReceiverSession::RemotingPreferences>();
1131 EXPECT_TRUE(first.IsSupersetOf(second));
1132 EXPECT_FALSE(second.IsSupersetOf(first));
1133 second = first;
1134
1135 second.remoting->supports_4k = true;
1136 EXPECT_FALSE(first.IsSupersetOf(second));
1137 EXPECT_TRUE(second.IsSupersetOf(first));
1138 second = first;
1139
1140 // Modified |video_codecs|.
1141 first.video_codecs = {VideoCodec::kVp8, VideoCodec::kVp9};
1142 second.video_codecs = {};
1143 EXPECT_TRUE(first.IsSupersetOf(second));
1144 EXPECT_FALSE(second.IsSupersetOf(first));
1145 second.video_codecs = {VideoCodec::kHevc};
1146 EXPECT_FALSE(first.IsSupersetOf(second));
1147 EXPECT_FALSE(second.IsSupersetOf(first));
1148 first.video_codecs.emplace_back(VideoCodec::kHevc);
1149 EXPECT_TRUE(first.IsSupersetOf(second));
1150 EXPECT_FALSE(second.IsSupersetOf(first));
1151 first = second;
1152
1153 // Modified |audio_codecs|.
1154 first.audio_codecs = {AudioCodec::kOpus};
1155 second.audio_codecs = {};
1156 EXPECT_TRUE(first.IsSupersetOf(second));
1157 EXPECT_FALSE(second.IsSupersetOf(first));
1158 second.audio_codecs = {AudioCodec::kAac};
1159 EXPECT_FALSE(first.IsSupersetOf(second));
1160 EXPECT_FALSE(second.IsSupersetOf(first));
1161 first.audio_codecs.emplace_back(AudioCodec::kAac);
1162 EXPECT_TRUE(first.IsSupersetOf(second));
1163 EXPECT_FALSE(second.IsSupersetOf(first));
1164 first = second;
1165
1166 // Modified |video_limits|.
1167 first.video_limits.push_back({true, VideoCodec::kVp8});
1168 EXPECT_TRUE(first.IsSupersetOf(second));
1169 EXPECT_TRUE(second.IsSupersetOf(first));
1170 first.video_limits.front().min_bit_rate = -1;
1171 EXPECT_TRUE(first.IsSupersetOf(second));
1172 EXPECT_FALSE(second.IsSupersetOf(first));
1173 second.video_limits.push_back({true, VideoCodec::kVp9});
1174 second.video_limits.front().min_bit_rate = -1;
1175 EXPECT_TRUE(first.IsSupersetOf(second));
1176 EXPECT_TRUE(second.IsSupersetOf(first));
1177 first.video_limits.front().applies_to_all_codecs = false;
1178 first.video_limits.push_back({false, VideoCodec::kHevc, 123});
1179 second.video_limits.front().applies_to_all_codecs = false;
1180 EXPECT_FALSE(first.IsSupersetOf(second));
1181 EXPECT_FALSE(second.IsSupersetOf(first));
1182 second.video_limits.front().min_bit_rate = kDefaultVideoMinBitRate;
1183 first.video_limits.front().min_bit_rate = kDefaultVideoMinBitRate;
1184 EXPECT_FALSE(first.IsSupersetOf(second));
1185 EXPECT_TRUE(second.IsSupersetOf(first));
1186 second = first;
1187
1188 // Modified |audio_limits|.
1189 first.audio_limits.push_back({true, AudioCodec::kOpus});
1190 EXPECT_TRUE(first.IsSupersetOf(second));
1191 EXPECT_TRUE(second.IsSupersetOf(first));
1192 first.audio_limits.front().min_bit_rate = -1;
1193 EXPECT_TRUE(first.IsSupersetOf(second));
1194 EXPECT_FALSE(second.IsSupersetOf(first));
1195 second.audio_limits.push_back({true, AudioCodec::kAac});
1196 second.audio_limits.front().min_bit_rate = -1;
1197 EXPECT_TRUE(first.IsSupersetOf(second));
1198 EXPECT_TRUE(second.IsSupersetOf(first));
1199 first.audio_limits.front().applies_to_all_codecs = false;
1200 first.audio_limits.push_back({false, AudioCodec::kOpus, -1});
1201 second.audio_limits.front().applies_to_all_codecs = false;
1202 EXPECT_FALSE(first.IsSupersetOf(second));
1203 EXPECT_FALSE(second.IsSupersetOf(first));
1204 }
1205
1206 } // namespace cast
1207 } // namespace openscreen
1208