| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 using cricket::NS_JINGLE_RTP; | 82 using cricket::NS_JINGLE_RTP; |
| 83 using cricket::MEDIA_TYPE_AUDIO; | 83 using cricket::MEDIA_TYPE_AUDIO; |
| 84 using cricket::MEDIA_TYPE_VIDEO; | 84 using cricket::MEDIA_TYPE_VIDEO; |
| 85 using cricket::MEDIA_TYPE_DATA; | 85 using cricket::MEDIA_TYPE_DATA; |
| 86 using cricket::RtpHeaderExtension; | 86 using cricket::RtpHeaderExtension; |
| 87 using cricket::SEC_DISABLED; | 87 using cricket::SEC_DISABLED; |
| 88 using cricket::SEC_ENABLED; | 88 using cricket::SEC_ENABLED; |
| 89 using cricket::SEC_REQUIRED; | 89 using cricket::SEC_REQUIRED; |
| 90 using rtc::CS_AES_CM_128_HMAC_SHA1_32; | 90 using rtc::CS_AES_CM_128_HMAC_SHA1_32; |
| 91 using rtc::CS_AES_CM_128_HMAC_SHA1_80; | 91 using rtc::CS_AES_CM_128_HMAC_SHA1_80; |
| 92 using rtc::CS_AEAD_AES_128_GCM; |
| 93 using rtc::CS_AEAD_AES_256_GCM; |
| 92 | 94 |
| 93 static const AudioCodec kAudioCodecs1[] = { | 95 static const AudioCodec kAudioCodecs1[] = { |
| 94 AudioCodec(103, "ISAC", 16000, -1, 1, 6), | 96 AudioCodec(103, "ISAC", 16000, -1, 1, 6), |
| 95 AudioCodec(102, "iLBC", 8000, 13300, 1, 5), | 97 AudioCodec(102, "iLBC", 8000, 13300, 1, 5), |
| 96 AudioCodec(0, "PCMU", 8000, 64000, 1, 4), | 98 AudioCodec(0, "PCMU", 8000, 64000, 1, 4), |
| 97 AudioCodec(8, "PCMA", 8000, 64000, 1, 3), | 99 AudioCodec(8, "PCMA", 8000, 64000, 1, 3), |
| 98 AudioCodec(117, "red", 8000, 0, 1, 2), | 100 AudioCodec(117, "red", 8000, 0, 1, 2), |
| 99 AudioCodec(107, "CN", 48000, 0, 1, 1) | 101 AudioCodec(107, "CN", 48000, 0, 1, 1) |
| 100 }; | 102 }; |
| 101 | 103 |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 const cricket::AudioContentDescription* audio_content_desc = | 466 const cricket::AudioContentDescription* audio_content_desc = |
| 465 static_cast<const cricket::AudioContentDescription*>(description); | 467 static_cast<const cricket::AudioContentDescription*>(description); |
| 466 ASSERT(audio_content_desc != NULL); | 468 ASSERT(audio_content_desc != NULL); |
| 467 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) { | 469 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) { |
| 468 if (audio_content_desc->codecs()[i].name == "CN") | 470 if (audio_content_desc->codecs()[i].name == "CN") |
| 469 return false; | 471 return false; |
| 470 } | 472 } |
| 471 return true; | 473 return true; |
| 472 } | 474 } |
| 473 | 475 |
| 476 void TestVideoGcmCipher(bool gcm_offer, bool gcm_answer) { |
| 477 MediaSessionOptions offer_opts; |
| 478 offer_opts.recv_video = true; |
| 479 offer_opts.crypto_options.enable_gcm_crypto_suites = gcm_offer; |
| 480 MediaSessionOptions answer_opts; |
| 481 answer_opts.recv_video = true; |
| 482 answer_opts.crypto_options.enable_gcm_crypto_suites = gcm_answer; |
| 483 f1_.set_secure(SEC_ENABLED); |
| 484 f2_.set_secure(SEC_ENABLED); |
| 485 rtc::scoped_ptr<SessionDescription> offer( |
| 486 f1_.CreateOffer(offer_opts, NULL)); |
| 487 ASSERT_TRUE(offer.get() != NULL); |
| 488 rtc::scoped_ptr<SessionDescription> answer( |
| 489 f2_.CreateAnswer(offer.get(), answer_opts, NULL)); |
| 490 const ContentInfo* ac = answer->GetContentByName("audio"); |
| 491 const ContentInfo* vc = answer->GetContentByName("video"); |
| 492 ASSERT_TRUE(ac != NULL); |
| 493 ASSERT_TRUE(vc != NULL); |
| 494 EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type); |
| 495 EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type); |
| 496 const AudioContentDescription* acd = |
| 497 static_cast<const AudioContentDescription*>(ac->description); |
| 498 const VideoContentDescription* vcd = |
| 499 static_cast<const VideoContentDescription*>(vc->description); |
| 500 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 501 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 502 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 503 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 504 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 505 if (gcm_offer && gcm_answer) { |
| 506 ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); |
| 507 } else { |
| 508 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
| 509 } |
| 510 EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); |
| 511 EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); |
| 512 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
| 513 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
| 514 if (gcm_offer && gcm_answer) { |
| 515 ASSERT_CRYPTO(vcd, 1U, CS_AEAD_AES_256_GCM); |
| 516 } else { |
| 517 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); |
| 518 } |
| 519 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
| 520 } |
| 521 |
| 474 protected: | 522 protected: |
| 475 MediaSessionDescriptionFactory f1_; | 523 MediaSessionDescriptionFactory f1_; |
| 476 MediaSessionDescriptionFactory f2_; | 524 MediaSessionDescriptionFactory f2_; |
| 477 TransportDescriptionFactory tdf1_; | 525 TransportDescriptionFactory tdf1_; |
| 478 TransportDescriptionFactory tdf2_; | 526 TransportDescriptionFactory tdf2_; |
| 479 }; | 527 }; |
| 480 | 528 |
| 481 // Create a typical audio offer, and ensure it matches what we expect. | 529 // Create a typical audio offer, and ensure it matches what we expect. |
| 482 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { | 530 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { |
| 483 f1_.set_secure(SEC_ENABLED); | 531 f1_.set_secure(SEC_ENABLED); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 static_cast<const AudioContentDescription*>(ac->description); | 829 static_cast<const AudioContentDescription*>(ac->description); |
| 782 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 830 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 783 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 831 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 784 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 832 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 785 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 833 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 786 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 834 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 787 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 835 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
| 788 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); | 836 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); |
| 789 } | 837 } |
| 790 | 838 |
| 839 // Create a typical audio answer with GCM ciphers enabled, and ensure it |
| 840 // matches what we expect. |
| 841 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { |
| 842 f1_.set_secure(SEC_ENABLED); |
| 843 f2_.set_secure(SEC_ENABLED); |
| 844 MediaSessionOptions options; |
| 845 options.crypto_options.enable_gcm_crypto_suites = true; |
| 846 rtc::scoped_ptr<SessionDescription> offer( |
| 847 f1_.CreateOffer(options, NULL)); |
| 848 ASSERT_TRUE(offer.get() != NULL); |
| 849 rtc::scoped_ptr<SessionDescription> answer( |
| 850 f2_.CreateAnswer(offer.get(), options, NULL)); |
| 851 const ContentInfo* ac = answer->GetContentByName("audio"); |
| 852 const ContentInfo* vc = answer->GetContentByName("video"); |
| 853 ASSERT_TRUE(ac != NULL); |
| 854 ASSERT_TRUE(vc == NULL); |
| 855 EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type); |
| 856 const AudioContentDescription* acd = |
| 857 static_cast<const AudioContentDescription*>(ac->description); |
| 858 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 859 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 860 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 861 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 862 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 863 ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); |
| 864 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); |
| 865 } |
| 866 |
| 791 // Create a typical video answer, and ensure it matches what we expect. | 867 // Create a typical video answer, and ensure it matches what we expect. |
| 792 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { | 868 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { |
| 793 MediaSessionOptions opts; | 869 MediaSessionOptions opts; |
| 794 opts.recv_video = true; | 870 opts.recv_video = true; |
| 795 f1_.set_secure(SEC_ENABLED); | 871 f1_.set_secure(SEC_ENABLED); |
| 796 f2_.set_secure(SEC_ENABLED); | 872 f2_.set_secure(SEC_ENABLED); |
| 797 rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 873 rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); |
| 798 ASSERT_TRUE(offer.get() != NULL); | 874 ASSERT_TRUE(offer.get() != NULL); |
| 799 rtc::scoped_ptr<SessionDescription> answer( | 875 rtc::scoped_ptr<SessionDescription> answer( |
| 800 f2_.CreateAnswer(offer.get(), opts, NULL)); | 876 f2_.CreateAnswer(offer.get(), opts, NULL)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 815 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 891 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 816 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 892 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
| 817 EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); | 893 EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); |
| 818 EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); | 894 EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); |
| 819 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 895 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
| 820 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux | 896 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
| 821 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 897 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); |
| 822 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); | 898 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
| 823 } | 899 } |
| 824 | 900 |
| 901 // Create a typical video answer with GCM ciphers enabled, and ensure it |
| 902 // matches what we expect. |
| 903 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcm) { |
| 904 TestVideoGcmCipher(true, true); |
| 905 } |
| 906 |
| 907 // Create a typical video answer with GCM ciphers enabled for the offer only, |
| 908 // and ensure it matches what we expect. |
| 909 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmOffer) { |
| 910 TestVideoGcmCipher(true, false); |
| 911 } |
| 912 |
| 913 // Create a typical video answer with GCM ciphers enabled for the answer only, |
| 914 // and ensure it matches what we expect. |
| 915 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmAnswer) { |
| 916 TestVideoGcmCipher(false, true); |
| 917 } |
| 918 |
| 825 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) { | 919 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) { |
| 826 MediaSessionOptions opts; | 920 MediaSessionOptions opts; |
| 827 opts.data_channel_type = cricket::DCT_RTP; | 921 opts.data_channel_type = cricket::DCT_RTP; |
| 828 f1_.set_secure(SEC_ENABLED); | 922 f1_.set_secure(SEC_ENABLED); |
| 829 f2_.set_secure(SEC_ENABLED); | 923 f2_.set_secure(SEC_ENABLED); |
| 830 rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 924 rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); |
| 831 ASSERT_TRUE(offer.get() != NULL); | 925 ASSERT_TRUE(offer.get() != NULL); |
| 832 rtc::scoped_ptr<SessionDescription> answer( | 926 rtc::scoped_ptr<SessionDescription> answer( |
| 833 f2_.CreateAnswer(offer.get(), opts, NULL)); | 927 f2_.CreateAnswer(offer.get(), opts, NULL)); |
| 834 const ContentInfo* ac = answer->GetContentByName("audio"); | 928 const ContentInfo* ac = answer->GetContentByName("audio"); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 848 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 942 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 849 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 943 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
| 850 EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type()); | 944 EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type()); |
| 851 EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs()); | 945 EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs()); |
| 852 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 946 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
| 853 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux | 947 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
| 854 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 948 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); |
| 855 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); | 949 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
| 856 } | 950 } |
| 857 | 951 |
| 952 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerGcm) { |
| 953 MediaSessionOptions opts; |
| 954 opts.data_channel_type = cricket::DCT_RTP; |
| 955 opts.crypto_options.enable_gcm_crypto_suites = true; |
| 956 f1_.set_secure(SEC_ENABLED); |
| 957 f2_.set_secure(SEC_ENABLED); |
| 958 rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); |
| 959 ASSERT_TRUE(offer.get() != NULL); |
| 960 rtc::scoped_ptr<SessionDescription> answer( |
| 961 f2_.CreateAnswer(offer.get(), opts, NULL)); |
| 962 const ContentInfo* ac = answer->GetContentByName("audio"); |
| 963 const ContentInfo* vc = answer->GetContentByName("data"); |
| 964 ASSERT_TRUE(ac != NULL); |
| 965 ASSERT_TRUE(vc != NULL); |
| 966 EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type); |
| 967 EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type); |
| 968 const AudioContentDescription* acd = |
| 969 static_cast<const AudioContentDescription*>(ac->description); |
| 970 const DataContentDescription* vcd = |
| 971 static_cast<const DataContentDescription*>(vc->description); |
| 972 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 973 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 974 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 975 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 976 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 977 ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); |
| 978 EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type()); |
| 979 EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs()); |
| 980 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
| 981 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
| 982 ASSERT_CRYPTO(vcd, 1U, CS_AEAD_AES_256_GCM); |
| 983 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
| 984 } |
| 985 |
| 858 // Verifies that the order of the media contents in the offer is preserved in | 986 // Verifies that the order of the media contents in the offer is preserved in |
| 859 // the answer. | 987 // the answer. |
| 860 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAnswerContentOrder) { | 988 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAnswerContentOrder) { |
| 861 MediaSessionOptions opts; | 989 MediaSessionOptions opts; |
| 862 | 990 |
| 863 // Creates a data only offer. | 991 // Creates a data only offer. |
| 864 opts.recv_audio = false; | 992 opts.recv_audio = false; |
| 865 opts.data_channel_type = cricket::DCT_SCTP; | 993 opts.data_channel_type = cricket::DCT_SCTP; |
| 866 rtc::scoped_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); | 994 rtc::scoped_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); |
| 867 ASSERT_TRUE(offer1.get() != NULL); | 995 ASSERT_TRUE(offer1.get() != NULL); |
| (...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2335 const ContentInfo* audio_content = GetFirstAudioContent(updated_offer.get()); | 2463 const ContentInfo* audio_content = GetFirstAudioContent(updated_offer.get()); |
| 2336 const ContentInfo* video_content = GetFirstVideoContent(updated_offer.get()); | 2464 const ContentInfo* video_content = GetFirstVideoContent(updated_offer.get()); |
| 2337 const ContentInfo* data_content = GetFirstDataContent(updated_offer.get()); | 2465 const ContentInfo* data_content = GetFirstDataContent(updated_offer.get()); |
| 2338 ASSERT_TRUE(audio_content != nullptr); | 2466 ASSERT_TRUE(audio_content != nullptr); |
| 2339 ASSERT_TRUE(video_content != nullptr); | 2467 ASSERT_TRUE(video_content != nullptr); |
| 2340 ASSERT_TRUE(data_content != nullptr); | 2468 ASSERT_TRUE(data_content != nullptr); |
| 2341 EXPECT_EQ("audio_modified", audio_content->name); | 2469 EXPECT_EQ("audio_modified", audio_content->name); |
| 2342 EXPECT_EQ("video_modified", video_content->name); | 2470 EXPECT_EQ("video_modified", video_content->name); |
| 2343 EXPECT_EQ("data_modified", data_content->name); | 2471 EXPECT_EQ("data_modified", data_content->name); |
| 2344 } | 2472 } |
| OLD | NEW |