• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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