| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 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, |
| 11 * this list of conditions and the following disclaimer in the documentation | 11 * this list of conditions and the following disclaimer in the documentation |
| 12 * and/or other materials provided with the distribution. | 12 * and/or other materials provided with the distribution. |
| 13 * 3. The name of the author may not be used to endorse or promote products | 13 * 3. The name of the author may not be used to endorse or promote products |
| 14 * derived from this software without specific prior written permission. | 14 * derived from this software without specific prior written permission. |
| 15 * | 15 * |
| 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
| 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 | 27 |
| 28 #include <string> | 28 #include <string> |
| 29 | 29 |
| 30 #include "talk/app/webrtc/audiotrack.h" | |
| 31 #include "talk/app/webrtc/fakeportallocatorfactory.h" | 30 #include "talk/app/webrtc/fakeportallocatorfactory.h" |
| 32 #include "talk/app/webrtc/jsepsessiondescription.h" | 31 #include "talk/app/webrtc/jsepsessiondescription.h" |
| 33 #include "talk/app/webrtc/mediastream.h" | |
| 34 #include "talk/app/webrtc/mediastreaminterface.h" | 32 #include "talk/app/webrtc/mediastreaminterface.h" |
| 35 #include "talk/app/webrtc/peerconnection.h" | |
| 36 #include "talk/app/webrtc/peerconnectioninterface.h" | 33 #include "talk/app/webrtc/peerconnectioninterface.h" |
| 37 #include "talk/app/webrtc/rtpreceiverinterface.h" | |
| 38 #include "talk/app/webrtc/rtpsenderinterface.h" | |
| 39 #include "talk/app/webrtc/streamcollection.h" | |
| 40 #include "talk/app/webrtc/test/fakeconstraints.h" | 34 #include "talk/app/webrtc/test/fakeconstraints.h" |
| 41 #include "talk/app/webrtc/test/fakedtlsidentitystore.h" | 35 #include "talk/app/webrtc/test/fakedtlsidentitystore.h" |
| 42 #include "talk/app/webrtc/test/mockpeerconnectionobservers.h" | 36 #include "talk/app/webrtc/test/mockpeerconnectionobservers.h" |
| 43 #include "talk/app/webrtc/test/testsdpstrings.h" | 37 #include "talk/app/webrtc/test/testsdpstrings.h" |
| 44 #include "talk/app/webrtc/videosource.h" | 38 #include "talk/app/webrtc/videosource.h" |
| 45 #include "talk/app/webrtc/videotrack.h" | |
| 46 #include "talk/media/base/fakevideocapturer.h" | 39 #include "talk/media/base/fakevideocapturer.h" |
| 47 #include "talk/media/sctp/sctpdataengine.h" | 40 #include "talk/media/sctp/sctpdataengine.h" |
| 48 #include "talk/session/media/mediasession.h" | 41 #include "talk/session/media/mediasession.h" |
| 49 #include "webrtc/base/gunit.h" | 42 #include "webrtc/base/gunit.h" |
| 50 #include "webrtc/base/scoped_ptr.h" | 43 #include "webrtc/base/scoped_ptr.h" |
| 51 #include "webrtc/base/ssladapter.h" | 44 #include "webrtc/base/ssladapter.h" |
| 52 #include "webrtc/base/sslstreamadapter.h" | 45 #include "webrtc/base/sslstreamadapter.h" |
| 53 #include "webrtc/base/stringutils.h" | 46 #include "webrtc/base/stringutils.h" |
| 54 #include "webrtc/base/thread.h" | 47 #include "webrtc/base/thread.h" |
| 55 | 48 |
| 56 static const char kStreamLabel1[] = "local_stream_1"; | 49 static const char kStreamLabel1[] = "local_stream_1"; |
| 57 static const char kStreamLabel2[] = "local_stream_2"; | 50 static const char kStreamLabel2[] = "local_stream_2"; |
| 58 static const char kStreamLabel3[] = "local_stream_3"; | 51 static const char kStreamLabel3[] = "local_stream_3"; |
| 59 static const int kDefaultStunPort = 3478; | 52 static const int kDefaultStunPort = 3478; |
| 60 static const char kStunAddressOnly[] = "stun:address"; | 53 static const char kStunAddressOnly[] = "stun:address"; |
| 61 static const char kStunInvalidPort[] = "stun:address:-1"; | 54 static const char kStunInvalidPort[] = "stun:address:-1"; |
| 62 static const char kStunAddressPortAndMore1[] = "stun:address:port:more"; | 55 static const char kStunAddressPortAndMore1[] = "stun:address:port:more"; |
| 63 static const char kStunAddressPortAndMore2[] = "stun:address:port more"; | 56 static const char kStunAddressPortAndMore2[] = "stun:address:port more"; |
| 64 static const char kTurnIceServerUri[] = "turn:user@turn.example.org"; | 57 static const char kTurnIceServerUri[] = "turn:user@turn.example.org"; |
| 65 static const char kTurnUsername[] = "user"; | 58 static const char kTurnUsername[] = "user"; |
| 66 static const char kTurnPassword[] = "password"; | 59 static const char kTurnPassword[] = "password"; |
| 67 static const char kTurnHostname[] = "turn.example.org"; | 60 static const char kTurnHostname[] = "turn.example.org"; |
| 68 static const uint32_t kTimeout = 10000U; | 61 static const uint32_t kTimeout = 10000U; |
| 69 | 62 |
| 70 static const char kStreams[][8] = {"stream1", "stream2"}; | |
| 71 static const char kAudioTracks[][32] = {"audiotrack0", "audiotrack1"}; | |
| 72 static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"}; | |
| 73 | |
| 74 // Reference SDP with a MediaStream with label "stream1" and audio track with | |
| 75 // id "audio_1" and a video track with id "video_1; | |
| 76 static const char kSdpStringWithStream1[] = | |
| 77 "v=0\r\n" | |
| 78 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 79 "s=-\r\n" | |
| 80 "t=0 0\r\n" | |
| 81 "a=ice-ufrag:e5785931\r\n" | |
| 82 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 83 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 84 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 85 "m=audio 1 RTP/AVPF 103\r\n" | |
| 86 "a=mid:audio\r\n" | |
| 87 "a=rtpmap:103 ISAC/16000\r\n" | |
| 88 "a=ssrc:1 cname:stream1\r\n" | |
| 89 "a=ssrc:1 mslabel:stream1\r\n" | |
| 90 "a=ssrc:1 label:audiotrack0\r\n" | |
| 91 "m=video 1 RTP/AVPF 120\r\n" | |
| 92 "a=mid:video\r\n" | |
| 93 "a=rtpmap:120 VP8/90000\r\n" | |
| 94 "a=ssrc:2 cname:stream1\r\n" | |
| 95 "a=ssrc:2 mslabel:stream1\r\n" | |
| 96 "a=ssrc:2 label:videotrack0\r\n"; | |
| 97 | |
| 98 // Reference SDP with two MediaStreams with label "stream1" and "stream2. Each | |
| 99 // MediaStreams have one audio track and one video track. | |
| 100 // This uses MSID. | |
| 101 static const char kSdpStringWithStream1And2[] = | |
| 102 "v=0\r\n" | |
| 103 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 104 "s=-\r\n" | |
| 105 "t=0 0\r\n" | |
| 106 "a=ice-ufrag:e5785931\r\n" | |
| 107 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 108 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 109 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 110 "a=msid-semantic: WMS stream1 stream2\r\n" | |
| 111 "m=audio 1 RTP/AVPF 103\r\n" | |
| 112 "a=mid:audio\r\n" | |
| 113 "a=rtpmap:103 ISAC/16000\r\n" | |
| 114 "a=ssrc:1 cname:stream1\r\n" | |
| 115 "a=ssrc:1 msid:stream1 audiotrack0\r\n" | |
| 116 "a=ssrc:3 cname:stream2\r\n" | |
| 117 "a=ssrc:3 msid:stream2 audiotrack1\r\n" | |
| 118 "m=video 1 RTP/AVPF 120\r\n" | |
| 119 "a=mid:video\r\n" | |
| 120 "a=rtpmap:120 VP8/0\r\n" | |
| 121 "a=ssrc:2 cname:stream1\r\n" | |
| 122 "a=ssrc:2 msid:stream1 videotrack0\r\n" | |
| 123 "a=ssrc:4 cname:stream2\r\n" | |
| 124 "a=ssrc:4 msid:stream2 videotrack1\r\n"; | |
| 125 | |
| 126 // Reference SDP without MediaStreams. Msid is not supported. | |
| 127 static const char kSdpStringWithoutStreams[] = | |
| 128 "v=0\r\n" | |
| 129 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 130 "s=-\r\n" | |
| 131 "t=0 0\r\n" | |
| 132 "a=ice-ufrag:e5785931\r\n" | |
| 133 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 134 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 135 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 136 "m=audio 1 RTP/AVPF 103\r\n" | |
| 137 "a=mid:audio\r\n" | |
| 138 "a=rtpmap:103 ISAC/16000\r\n" | |
| 139 "m=video 1 RTP/AVPF 120\r\n" | |
| 140 "a=mid:video\r\n" | |
| 141 "a=rtpmap:120 VP8/90000\r\n"; | |
| 142 | |
| 143 // Reference SDP without MediaStreams. Msid is supported. | |
| 144 static const char kSdpStringWithMsidWithoutStreams[] = | |
| 145 "v=0\r\n" | |
| 146 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 147 "s=-\r\n" | |
| 148 "t=0 0\r\n" | |
| 149 "a=ice-ufrag:e5785931\r\n" | |
| 150 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 151 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 152 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 153 "a=msid-semantic: WMS\r\n" | |
| 154 "m=audio 1 RTP/AVPF 103\r\n" | |
| 155 "a=mid:audio\r\n" | |
| 156 "a=rtpmap:103 ISAC/16000\r\n" | |
| 157 "m=video 1 RTP/AVPF 120\r\n" | |
| 158 "a=mid:video\r\n" | |
| 159 "a=rtpmap:120 VP8/90000\r\n"; | |
| 160 | |
| 161 // Reference SDP without MediaStreams and audio only. | |
| 162 static const char kSdpStringWithoutStreamsAudioOnly[] = | |
| 163 "v=0\r\n" | |
| 164 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 165 "s=-\r\n" | |
| 166 "t=0 0\r\n" | |
| 167 "a=ice-ufrag:e5785931\r\n" | |
| 168 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 169 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 170 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 171 "m=audio 1 RTP/AVPF 103\r\n" | |
| 172 "a=mid:audio\r\n" | |
| 173 "a=rtpmap:103 ISAC/16000\r\n"; | |
| 174 | |
| 175 // Reference SENDONLY SDP without MediaStreams. Msid is not supported. | |
| 176 static const char kSdpStringSendOnlyWithoutStreams[] = | |
| 177 "v=0\r\n" | |
| 178 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 179 "s=-\r\n" | |
| 180 "t=0 0\r\n" | |
| 181 "a=ice-ufrag:e5785931\r\n" | |
| 182 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 183 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 184 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 185 "m=audio 1 RTP/AVPF 103\r\n" | |
| 186 "a=mid:audio\r\n" | |
| 187 "a=sendonly\r\n" | |
| 188 "a=rtpmap:103 ISAC/16000\r\n" | |
| 189 "m=video 1 RTP/AVPF 120\r\n" | |
| 190 "a=mid:video\r\n" | |
| 191 "a=sendonly\r\n" | |
| 192 "a=rtpmap:120 VP8/90000\r\n"; | |
| 193 | |
| 194 static const char kSdpStringInit[] = | |
| 195 "v=0\r\n" | |
| 196 "o=- 0 0 IN IP4 127.0.0.1\r\n" | |
| 197 "s=-\r\n" | |
| 198 "t=0 0\r\n" | |
| 199 "a=ice-ufrag:e5785931\r\n" | |
| 200 "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" | |
| 201 "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:" | |
| 202 "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n" | |
| 203 "a=msid-semantic: WMS\r\n"; | |
| 204 | |
| 205 static const char kSdpStringAudio[] = | |
| 206 "m=audio 1 RTP/AVPF 103\r\n" | |
| 207 "a=mid:audio\r\n" | |
| 208 "a=rtpmap:103 ISAC/16000\r\n"; | |
| 209 | |
| 210 static const char kSdpStringVideo[] = | |
| 211 "m=video 1 RTP/AVPF 120\r\n" | |
| 212 "a=mid:video\r\n" | |
| 213 "a=rtpmap:120 VP8/90000\r\n"; | |
| 214 | |
| 215 static const char kSdpStringMs1Audio0[] = | |
| 216 "a=ssrc:1 cname:stream1\r\n" | |
| 217 "a=ssrc:1 msid:stream1 audiotrack0\r\n"; | |
| 218 | |
| 219 static const char kSdpStringMs1Video0[] = | |
| 220 "a=ssrc:2 cname:stream1\r\n" | |
| 221 "a=ssrc:2 msid:stream1 videotrack0\r\n"; | |
| 222 | |
| 223 static const char kSdpStringMs1Audio1[] = | |
| 224 "a=ssrc:3 cname:stream1\r\n" | |
| 225 "a=ssrc:3 msid:stream1 audiotrack1\r\n"; | |
| 226 | |
| 227 static const char kSdpStringMs1Video1[] = | |
| 228 "a=ssrc:4 cname:stream1\r\n" | |
| 229 "a=ssrc:4 msid:stream1 videotrack1\r\n"; | |
| 230 | |
| 231 #define MAYBE_SKIP_TEST(feature) \ | 63 #define MAYBE_SKIP_TEST(feature) \ |
| 232 if (!(feature())) { \ | 64 if (!(feature())) { \ |
| 233 LOG(LS_INFO) << "Feature disabled... skipping"; \ | 65 LOG(LS_INFO) << "Feature disabled... skipping"; \ |
| 234 return; \ | 66 return; \ |
| 235 } | 67 } |
| 236 | 68 |
| 237 using rtc::scoped_ptr; | 69 using rtc::scoped_ptr; |
| 238 using rtc::scoped_refptr; | 70 using rtc::scoped_refptr; |
| 239 using webrtc::AudioSourceInterface; | 71 using webrtc::AudioSourceInterface; |
| 240 using webrtc::AudioTrack; | |
| 241 using webrtc::AudioTrackInterface; | 72 using webrtc::AudioTrackInterface; |
| 242 using webrtc::DataBuffer; | 73 using webrtc::DataBuffer; |
| 243 using webrtc::DataChannelInterface; | 74 using webrtc::DataChannelInterface; |
| 244 using webrtc::FakeConstraints; | 75 using webrtc::FakeConstraints; |
| 245 using webrtc::FakePortAllocatorFactory; | 76 using webrtc::FakePortAllocatorFactory; |
| 246 using webrtc::IceCandidateInterface; | 77 using webrtc::IceCandidateInterface; |
| 247 using webrtc::MediaStream; | |
| 248 using webrtc::MediaStreamInterface; | 78 using webrtc::MediaStreamInterface; |
| 249 using webrtc::MediaStreamTrackInterface; | 79 using webrtc::MediaStreamTrackInterface; |
| 250 using webrtc::MockCreateSessionDescriptionObserver; | 80 using webrtc::MockCreateSessionDescriptionObserver; |
| 251 using webrtc::MockDataChannelObserver; | 81 using webrtc::MockDataChannelObserver; |
| 252 using webrtc::MockSetSessionDescriptionObserver; | 82 using webrtc::MockSetSessionDescriptionObserver; |
| 253 using webrtc::MockStatsObserver; | 83 using webrtc::MockStatsObserver; |
| 254 using webrtc::PeerConnectionInterface; | 84 using webrtc::PeerConnectionInterface; |
| 255 using webrtc::PeerConnectionObserver; | 85 using webrtc::PeerConnectionObserver; |
| 256 using webrtc::PortAllocatorFactoryInterface; | 86 using webrtc::PortAllocatorFactoryInterface; |
| 257 using webrtc::RtpReceiverInterface; | |
| 258 using webrtc::RtpSenderInterface; | |
| 259 using webrtc::SdpParseError; | 87 using webrtc::SdpParseError; |
| 260 using webrtc::SessionDescriptionInterface; | 88 using webrtc::SessionDescriptionInterface; |
| 261 using webrtc::StreamCollection; | |
| 262 using webrtc::StreamCollectionInterface; | |
| 263 using webrtc::VideoSourceInterface; | 89 using webrtc::VideoSourceInterface; |
| 264 using webrtc::VideoTrack; | |
| 265 using webrtc::VideoTrackInterface; | 90 using webrtc::VideoTrackInterface; |
| 266 | 91 |
| 267 typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions; | |
| 268 | |
| 269 namespace { | 92 namespace { |
| 270 | 93 |
| 271 // Gets the first ssrc of given content type from the ContentInfo. | 94 // Gets the first ssrc of given content type from the ContentInfo. |
| 272 bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) { | 95 bool GetFirstSsrc(const cricket::ContentInfo* content_info, int* ssrc) { |
| 273 if (!content_info || !ssrc) { | 96 if (!content_info || !ssrc) { |
| 274 return false; | 97 return false; |
| 275 } | 98 } |
| 276 const cricket::MediaContentDescription* media_desc = | 99 const cricket::MediaContentDescription* media_desc = |
| 277 static_cast<const cricket::MediaContentDescription*>( | 100 static_cast<const cricket::MediaContentDescription*>( |
| 278 content_info->description); | 101 content_info->description); |
| 279 if (!media_desc || media_desc->streams().empty()) { | 102 if (!media_desc || media_desc->streams().empty()) { |
| 280 return false; | 103 return false; |
| 281 } | 104 } |
| 282 *ssrc = media_desc->streams().begin()->first_ssrc(); | 105 *ssrc = media_desc->streams().begin()->first_ssrc(); |
| 283 return true; | 106 return true; |
| 284 } | 107 } |
| 285 | 108 |
| 286 void SetSsrcToZero(std::string* sdp) { | 109 void SetSsrcToZero(std::string* sdp) { |
| 287 const char kSdpSsrcAtribute[] = "a=ssrc:"; | 110 const char kSdpSsrcAtribute[] = "a=ssrc:"; |
| 288 const char kSdpSsrcAtributeZero[] = "a=ssrc:0"; | 111 const char kSdpSsrcAtributeZero[] = "a=ssrc:0"; |
| 289 size_t ssrc_pos = 0; | 112 size_t ssrc_pos = 0; |
| 290 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) != | 113 while ((ssrc_pos = sdp->find(kSdpSsrcAtribute, ssrc_pos)) != |
| 291 std::string::npos) { | 114 std::string::npos) { |
| 292 size_t end_ssrc = sdp->find(" ", ssrc_pos); | 115 size_t end_ssrc = sdp->find(" ", ssrc_pos); |
| 293 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero); | 116 sdp->replace(ssrc_pos, end_ssrc - ssrc_pos, kSdpSsrcAtributeZero); |
| 294 ssrc_pos = end_ssrc; | 117 ssrc_pos = end_ssrc; |
| 295 } | 118 } |
| 296 } | 119 } |
| 297 | 120 |
| 298 // Check if |streams| contains the specified track. | |
| 299 bool ContainsTrack(const std::vector<cricket::StreamParams>& streams, | |
| 300 const std::string& stream_label, | |
| 301 const std::string& track_id) { | |
| 302 for (const cricket::StreamParams& params : streams) { | |
| 303 if (params.sync_label == stream_label && params.id == track_id) { | |
| 304 return true; | |
| 305 } | |
| 306 } | |
| 307 return false; | |
| 308 } | |
| 309 | |
| 310 // Check if |senders| contains the specified sender, by id. | |
| 311 bool ContainsSender( | |
| 312 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& senders, | |
| 313 const std::string& id) { | |
| 314 for (const auto& sender : senders) { | |
| 315 if (sender->id() == id) { | |
| 316 return true; | |
| 317 } | |
| 318 } | |
| 319 return false; | |
| 320 } | |
| 321 | |
| 322 // Create a collection of streams. | |
| 323 // CreateStreamCollection(1) creates a collection that | |
| 324 // correspond to kSdpStringWithStream1. | |
| 325 // CreateStreamCollection(2) correspond to kSdpStringWithStream1And2. | |
| 326 rtc::scoped_refptr<StreamCollection> CreateStreamCollection( | |
| 327 int number_of_streams) { | |
| 328 rtc::scoped_refptr<StreamCollection> local_collection( | |
| 329 StreamCollection::Create()); | |
| 330 | |
| 331 for (int i = 0; i < number_of_streams; ++i) { | |
| 332 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream( | |
| 333 webrtc::MediaStream::Create(kStreams[i])); | |
| 334 | |
| 335 // Add a local audio track. | |
| 336 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track( | |
| 337 webrtc::AudioTrack::Create(kAudioTracks[i], nullptr)); | |
| 338 stream->AddTrack(audio_track); | |
| 339 | |
| 340 // Add a local video track. | |
| 341 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track( | |
| 342 webrtc::VideoTrack::Create(kVideoTracks[i], nullptr)); | |
| 343 stream->AddTrack(video_track); | |
| 344 | |
| 345 local_collection->AddStream(stream); | |
| 346 } | |
| 347 return local_collection; | |
| 348 } | |
| 349 | |
| 350 // Check equality of StreamCollections. | |
| 351 bool CompareStreamCollections(StreamCollectionInterface* s1, | |
| 352 StreamCollectionInterface* s2) { | |
| 353 if (s1 == nullptr || s2 == nullptr || s1->count() != s2->count()) { | |
| 354 return false; | |
| 355 } | |
| 356 | |
| 357 for (size_t i = 0; i != s1->count(); ++i) { | |
| 358 if (s1->at(i)->label() != s2->at(i)->label()) { | |
| 359 return false; | |
| 360 } | |
| 361 webrtc::AudioTrackVector audio_tracks1 = s1->at(i)->GetAudioTracks(); | |
| 362 webrtc::AudioTrackVector audio_tracks2 = s2->at(i)->GetAudioTracks(); | |
| 363 webrtc::VideoTrackVector video_tracks1 = s1->at(i)->GetVideoTracks(); | |
| 364 webrtc::VideoTrackVector video_tracks2 = s2->at(i)->GetVideoTracks(); | |
| 365 | |
| 366 if (audio_tracks1.size() != audio_tracks2.size()) { | |
| 367 return false; | |
| 368 } | |
| 369 for (size_t j = 0; j != audio_tracks1.size(); ++j) { | |
| 370 if (audio_tracks1[j]->id() != audio_tracks2[j]->id()) { | |
| 371 return false; | |
| 372 } | |
| 373 } | |
| 374 if (video_tracks1.size() != video_tracks2.size()) { | |
| 375 return false; | |
| 376 } | |
| 377 for (size_t j = 0; j != video_tracks1.size(); ++j) { | |
| 378 if (video_tracks1[j]->id() != video_tracks2[j]->id()) { | |
| 379 return false; | |
| 380 } | |
| 381 } | |
| 382 } | |
| 383 return true; | |
| 384 } | |
| 385 | |
| 386 class MockPeerConnectionObserver : public PeerConnectionObserver { | 121 class MockPeerConnectionObserver : public PeerConnectionObserver { |
| 387 public: | 122 public: |
| 388 MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {} | 123 MockPeerConnectionObserver() |
| 124 : renegotiation_needed_(false), |
| 125 ice_complete_(false) { |
| 126 } |
| 389 ~MockPeerConnectionObserver() { | 127 ~MockPeerConnectionObserver() { |
| 390 } | 128 } |
| 391 void SetPeerConnectionInterface(PeerConnectionInterface* pc) { | 129 void SetPeerConnectionInterface(PeerConnectionInterface* pc) { |
| 392 pc_ = pc; | 130 pc_ = pc; |
| 393 if (pc) { | 131 if (pc) { |
| 394 state_ = pc_->signaling_state(); | 132 state_ = pc_->signaling_state(); |
| 395 } | 133 } |
| 396 } | 134 } |
| 397 virtual void OnSignalingChange( | 135 virtual void OnSignalingChange( |
| 398 PeerConnectionInterface::SignalingState new_state) { | 136 PeerConnectionInterface::SignalingState new_state) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 412 EXPECT_EQ(pc_->signaling_state(), state_); | 150 EXPECT_EQ(pc_->signaling_state(), state_); |
| 413 break; | 151 break; |
| 414 case kIceState: | 152 case kIceState: |
| 415 ADD_FAILURE(); | 153 ADD_FAILURE(); |
| 416 break; | 154 break; |
| 417 default: | 155 default: |
| 418 ADD_FAILURE(); | 156 ADD_FAILURE(); |
| 419 break; | 157 break; |
| 420 } | 158 } |
| 421 } | 159 } |
| 422 | |
| 423 MediaStreamInterface* RemoteStream(const std::string& label) { | |
| 424 return remote_streams_->find(label); | |
| 425 } | |
| 426 StreamCollectionInterface* remote_streams() const { return remote_streams_; } | |
| 427 virtual void OnAddStream(MediaStreamInterface* stream) { | 160 virtual void OnAddStream(MediaStreamInterface* stream) { |
| 428 last_added_stream_ = stream; | 161 last_added_stream_ = stream; |
| 429 remote_streams_->AddStream(stream); | |
| 430 } | 162 } |
| 431 virtual void OnRemoveStream(MediaStreamInterface* stream) { | 163 virtual void OnRemoveStream(MediaStreamInterface* stream) { |
| 432 last_removed_stream_ = stream; | 164 last_removed_stream_ = stream; |
| 433 remote_streams_->RemoveStream(stream); | |
| 434 } | 165 } |
| 435 virtual void OnRenegotiationNeeded() { | 166 virtual void OnRenegotiationNeeded() { |
| 436 renegotiation_needed_ = true; | 167 renegotiation_needed_ = true; |
| 437 } | 168 } |
| 438 virtual void OnDataChannel(DataChannelInterface* data_channel) { | 169 virtual void OnDataChannel(DataChannelInterface* data_channel) { |
| 439 last_datachannel_ = data_channel; | 170 last_datachannel_ = data_channel; |
| 440 } | 171 } |
| 441 | 172 |
| 442 virtual void OnIceConnectionChange( | 173 virtual void OnIceConnectionChange( |
| 443 PeerConnectionInterface::IceConnectionState new_state) { | 174 PeerConnectionInterface::IceConnectionState new_state) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 std::string GetLastRemovedStreamLabel() { | 209 std::string GetLastRemovedStreamLabel() { |
| 479 if (last_removed_stream_.get()) | 210 if (last_removed_stream_.get()) |
| 480 return last_removed_stream_->label(); | 211 return last_removed_stream_->label(); |
| 481 return ""; | 212 return ""; |
| 482 } | 213 } |
| 483 | 214 |
| 484 scoped_refptr<PeerConnectionInterface> pc_; | 215 scoped_refptr<PeerConnectionInterface> pc_; |
| 485 PeerConnectionInterface::SignalingState state_; | 216 PeerConnectionInterface::SignalingState state_; |
| 486 scoped_ptr<IceCandidateInterface> last_candidate_; | 217 scoped_ptr<IceCandidateInterface> last_candidate_; |
| 487 scoped_refptr<DataChannelInterface> last_datachannel_; | 218 scoped_refptr<DataChannelInterface> last_datachannel_; |
| 488 rtc::scoped_refptr<StreamCollection> remote_streams_; | 219 bool renegotiation_needed_; |
| 489 bool renegotiation_needed_ = false; | 220 bool ice_complete_; |
| 490 bool ice_complete_ = false; | |
| 491 | 221 |
| 492 private: | 222 private: |
| 493 scoped_refptr<MediaStreamInterface> last_added_stream_; | 223 scoped_refptr<MediaStreamInterface> last_added_stream_; |
| 494 scoped_refptr<MediaStreamInterface> last_removed_stream_; | 224 scoped_refptr<MediaStreamInterface> last_removed_stream_; |
| 495 }; | 225 }; |
| 496 | 226 |
| 497 } // namespace | 227 } // namespace |
| 498 | |
| 499 class PeerConnectionInterfaceTest : public testing::Test { | 228 class PeerConnectionInterfaceTest : public testing::Test { |
| 500 protected: | 229 protected: |
| 501 virtual void SetUp() { | 230 virtual void SetUp() { |
| 502 pc_factory_ = webrtc::CreatePeerConnectionFactory( | 231 pc_factory_ = webrtc::CreatePeerConnectionFactory( |
| 503 rtc::Thread::Current(), rtc::Thread::Current(), NULL, NULL, | 232 rtc::Thread::Current(), rtc::Thread::Current(), NULL, NULL, |
| 504 NULL); | 233 NULL); |
| 505 ASSERT_TRUE(pc_factory_.get() != NULL); | 234 ASSERT_TRUE(pc_factory_.get() != NULL); |
| 506 } | 235 } |
| 507 | 236 |
| 508 void CreatePeerConnection() { | 237 void CreatePeerConnection() { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 port_allocator_factory_->turn_configs()[0].password); | 320 port_allocator_factory_->turn_configs()[0].password); |
| 592 EXPECT_EQ(kTurnHostname, | 321 EXPECT_EQ(kTurnHostname, |
| 593 port_allocator_factory_->turn_configs()[0].server.hostname()); | 322 port_allocator_factory_->turn_configs()[0].server.hostname()); |
| 594 } | 323 } |
| 595 | 324 |
| 596 void ReleasePeerConnection() { | 325 void ReleasePeerConnection() { |
| 597 pc_ = NULL; | 326 pc_ = NULL; |
| 598 observer_.SetPeerConnectionInterface(NULL); | 327 observer_.SetPeerConnectionInterface(NULL); |
| 599 } | 328 } |
| 600 | 329 |
| 601 void AddVideoStream(const std::string& label) { | 330 void AddStream(const std::string& label) { |
| 602 // Create a local stream. | 331 // Create a local stream. |
| 603 scoped_refptr<MediaStreamInterface> stream( | 332 scoped_refptr<MediaStreamInterface> stream( |
| 604 pc_factory_->CreateLocalMediaStream(label)); | 333 pc_factory_->CreateLocalMediaStream(label)); |
| 605 scoped_refptr<VideoSourceInterface> video_source( | 334 scoped_refptr<VideoSourceInterface> video_source( |
| 606 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); | 335 pc_factory_->CreateVideoSource(new cricket::FakeVideoCapturer(), NULL)); |
| 607 scoped_refptr<VideoTrackInterface> video_track( | 336 scoped_refptr<VideoTrackInterface> video_track( |
| 608 pc_factory_->CreateVideoTrack(label + "v0", video_source)); | 337 pc_factory_->CreateVideoTrack(label + "v0", video_source)); |
| 609 stream->AddTrack(video_track.get()); | 338 stream->AddTrack(video_track.get()); |
| 610 EXPECT_TRUE(pc_->AddStream(stream)); | 339 EXPECT_TRUE(pc_->AddStream(stream)); |
| 611 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); | 340 EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 ASSERT_TRUE(DoCreateOffer(offer.use())); | 453 ASSERT_TRUE(DoCreateOffer(offer.use())); |
| 725 std::string sdp; | 454 std::string sdp; |
| 726 EXPECT_TRUE(offer->ToString(&sdp)); | 455 EXPECT_TRUE(offer->ToString(&sdp)); |
| 727 SessionDescriptionInterface* remote_offer = | 456 SessionDescriptionInterface* remote_offer = |
| 728 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, | 457 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, |
| 729 sdp, NULL); | 458 sdp, NULL); |
| 730 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); | 459 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); |
| 731 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); | 460 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); |
| 732 } | 461 } |
| 733 | 462 |
| 734 void CreateAndSetRemoteOffer(const std::string& sdp) { | |
| 735 SessionDescriptionInterface* remote_offer = | |
| 736 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, | |
| 737 sdp, nullptr); | |
| 738 EXPECT_TRUE(DoSetRemoteDescription(remote_offer)); | |
| 739 EXPECT_EQ(PeerConnectionInterface::kHaveRemoteOffer, observer_.state_); | |
| 740 } | |
| 741 | |
| 742 void CreateAnswerAsLocalDescription() { | 463 void CreateAnswerAsLocalDescription() { |
| 743 scoped_ptr<SessionDescriptionInterface> answer; | 464 scoped_ptr<SessionDescriptionInterface> answer; |
| 744 ASSERT_TRUE(DoCreateAnswer(answer.use())); | 465 ASSERT_TRUE(DoCreateAnswer(answer.use())); |
| 745 | 466 |
| 746 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an | 467 // TODO(perkj): Currently SetLocalDescription fails if any parameters in an |
| 747 // audio codec change, even if the parameter has nothing to do with | 468 // audio codec change, even if the parameter has nothing to do with |
| 748 // receiving. Not all parameters are serialized to SDP. | 469 // receiving. Not all parameters are serialized to SDP. |
| 749 // Since CreatePrAnswerAsLocalDescription serialize/deserialize | 470 // Since CreatePrAnswerAsLocalDescription serialize/deserialize |
| 750 // the SessionDescription, it is necessary to do that here to in order to | 471 // the SessionDescription, it is necessary to do that here to in order to |
| 751 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. | 472 // get ReceiveOfferCreatePrAnswerAndAnswer and RenegotiateAudioOnly to pass. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 webrtc::CreateSessionDescription( | 516 webrtc::CreateSessionDescription( |
| 796 SessionDescriptionInterface::kOffer, | 517 SessionDescriptionInterface::kOffer, |
| 797 sdp, NULL); | 518 sdp, NULL); |
| 798 | 519 |
| 799 EXPECT_TRUE(DoSetLocalDescription(new_offer)); | 520 EXPECT_TRUE(DoSetLocalDescription(new_offer)); |
| 800 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_); | 521 EXPECT_EQ(PeerConnectionInterface::kHaveLocalOffer, observer_.state_); |
| 801 // Wait for the ice_complete message, so that SDP will have candidates. | 522 // Wait for the ice_complete message, so that SDP will have candidates. |
| 802 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); | 523 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); |
| 803 } | 524 } |
| 804 | 525 |
| 805 void CreateAnswerAsRemoteDescription(const std::string& sdp) { | 526 void CreateAnswerAsRemoteDescription(const std::string& offer) { |
| 806 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( | 527 webrtc::JsepSessionDescription* answer = new webrtc::JsepSessionDescription( |
| 807 SessionDescriptionInterface::kAnswer); | 528 SessionDescriptionInterface::kAnswer); |
| 808 EXPECT_TRUE(answer->Initialize(sdp, NULL)); | 529 EXPECT_TRUE(answer->Initialize(offer, NULL)); |
| 809 EXPECT_TRUE(DoSetRemoteDescription(answer)); | 530 EXPECT_TRUE(DoSetRemoteDescription(answer)); |
| 810 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); | 531 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); |
| 811 } | 532 } |
| 812 | 533 |
| 813 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& sdp) { | 534 void CreatePrAnswerAndAnswerAsRemoteDescription(const std::string& offer) { |
| 814 webrtc::JsepSessionDescription* pr_answer = | 535 webrtc::JsepSessionDescription* pr_answer = |
| 815 new webrtc::JsepSessionDescription( | 536 new webrtc::JsepSessionDescription( |
| 816 SessionDescriptionInterface::kPrAnswer); | 537 SessionDescriptionInterface::kPrAnswer); |
| 817 EXPECT_TRUE(pr_answer->Initialize(sdp, NULL)); | 538 EXPECT_TRUE(pr_answer->Initialize(offer, NULL)); |
| 818 EXPECT_TRUE(DoSetRemoteDescription(pr_answer)); | 539 EXPECT_TRUE(DoSetRemoteDescription(pr_answer)); |
| 819 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_); | 540 EXPECT_EQ(PeerConnectionInterface::kHaveRemotePrAnswer, observer_.state_); |
| 820 webrtc::JsepSessionDescription* answer = | 541 webrtc::JsepSessionDescription* answer = |
| 821 new webrtc::JsepSessionDescription( | 542 new webrtc::JsepSessionDescription( |
| 822 SessionDescriptionInterface::kAnswer); | 543 SessionDescriptionInterface::kAnswer); |
| 823 EXPECT_TRUE(answer->Initialize(sdp, NULL)); | 544 EXPECT_TRUE(answer->Initialize(offer, NULL)); |
| 824 EXPECT_TRUE(DoSetRemoteDescription(answer)); | 545 EXPECT_TRUE(DoSetRemoteDescription(answer)); |
| 825 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); | 546 EXPECT_EQ(PeerConnectionInterface::kStable, observer_.state_); |
| 826 } | 547 } |
| 827 | 548 |
| 828 // Help function used for waiting until a the last signaled remote stream has | 549 // Help function used for waiting until a the last signaled remote stream has |
| 829 // the same label as |stream_label|. In a few of the tests in this file we | 550 // the same label as |stream_label|. In a few of the tests in this file we |
| 830 // answer with the same session description as we offer and thus we can | 551 // answer with the same session description as we offer and thus we can |
| 831 // check if OnAddStream have been called with the same stream as we offer to | 552 // check if OnAddStream have been called with the same stream as we offer to |
| 832 // send. | 553 // send. |
| 833 void WaitAndVerifyOnAddStream(const std::string& stream_label) { | 554 void WaitAndVerifyOnAddStream(const std::string& stream_label) { |
| 834 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout); | 555 EXPECT_EQ_WAIT(stream_label, observer_.GetLastAddedStreamLabel(), kTimeout); |
| 835 } | 556 } |
| 836 | 557 |
| 837 // Creates an offer and applies it as a local session description. | 558 // Creates an offer and applies it as a local session description. |
| 838 // Creates an answer with the same SDP an the offer but removes all lines | 559 // Creates an answer with the same SDP an the offer but removes all lines |
| 839 // that start with a:ssrc" | 560 // that start with a:ssrc" |
| 840 void CreateOfferReceiveAnswerWithoutSsrc() { | 561 void CreateOfferReceiveAnswerWithoutSsrc() { |
| 841 CreateOfferAsLocalDescription(); | 562 CreateOfferAsLocalDescription(); |
| 842 std::string sdp; | 563 std::string sdp; |
| 843 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); | 564 EXPECT_TRUE(pc_->local_description()->ToString(&sdp)); |
| 844 SetSsrcToZero(&sdp); | 565 SetSsrcToZero(&sdp); |
| 845 CreateAnswerAsRemoteDescription(sdp); | 566 CreateAnswerAsRemoteDescription(sdp); |
| 846 } | 567 } |
| 847 | 568 |
| 848 // This function creates a MediaStream with label kStreams[0] and | |
| 849 // |number_of_audio_tracks| and |number_of_video_tracks| tracks and the | |
| 850 // corresponding SessionDescriptionInterface. The SessionDescriptionInterface | |
| 851 // is returned in |desc| and the MediaStream is stored in | |
| 852 // |reference_collection_| | |
| 853 void CreateSessionDescriptionAndReference( | |
| 854 size_t number_of_audio_tracks, | |
| 855 size_t number_of_video_tracks, | |
| 856 SessionDescriptionInterface** desc) { | |
| 857 ASSERT_TRUE(desc != nullptr); | |
| 858 ASSERT_LE(number_of_audio_tracks, 2u); | |
| 859 ASSERT_LE(number_of_video_tracks, 2u); | |
| 860 | |
| 861 reference_collection_ = StreamCollection::Create(); | |
| 862 std::string sdp_ms1 = std::string(kSdpStringInit); | |
| 863 | |
| 864 std::string mediastream_label = kStreams[0]; | |
| 865 | |
| 866 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream( | |
| 867 webrtc::MediaStream::Create(mediastream_label)); | |
| 868 reference_collection_->AddStream(stream); | |
| 869 | |
| 870 if (number_of_audio_tracks > 0) { | |
| 871 sdp_ms1 += std::string(kSdpStringAudio); | |
| 872 sdp_ms1 += std::string(kSdpStringMs1Audio0); | |
| 873 AddAudioTrack(kAudioTracks[0], stream); | |
| 874 } | |
| 875 if (number_of_audio_tracks > 1) { | |
| 876 sdp_ms1 += kSdpStringMs1Audio1; | |
| 877 AddAudioTrack(kAudioTracks[1], stream); | |
| 878 } | |
| 879 | |
| 880 if (number_of_video_tracks > 0) { | |
| 881 sdp_ms1 += std::string(kSdpStringVideo); | |
| 882 sdp_ms1 += std::string(kSdpStringMs1Video0); | |
| 883 AddVideoTrack(kVideoTracks[0], stream); | |
| 884 } | |
| 885 if (number_of_video_tracks > 1) { | |
| 886 sdp_ms1 += kSdpStringMs1Video1; | |
| 887 AddVideoTrack(kVideoTracks[1], stream); | |
| 888 } | |
| 889 | |
| 890 *desc = webrtc::CreateSessionDescription( | |
| 891 SessionDescriptionInterface::kOffer, sdp_ms1, nullptr); | |
| 892 } | |
| 893 | |
| 894 void AddAudioTrack(const std::string& track_id, | |
| 895 MediaStreamInterface* stream) { | |
| 896 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track( | |
| 897 webrtc::AudioTrack::Create(track_id, nullptr)); | |
| 898 ASSERT_TRUE(stream->AddTrack(audio_track)); | |
| 899 } | |
| 900 | |
| 901 void AddVideoTrack(const std::string& track_id, | |
| 902 MediaStreamInterface* stream) { | |
| 903 rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track( | |
| 904 webrtc::VideoTrack::Create(track_id, nullptr)); | |
| 905 ASSERT_TRUE(stream->AddTrack(video_track)); | |
| 906 } | |
| 907 | |
| 908 scoped_refptr<FakePortAllocatorFactory> port_allocator_factory_; | 569 scoped_refptr<FakePortAllocatorFactory> port_allocator_factory_; |
| 909 scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; | 570 scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; |
| 910 scoped_refptr<PeerConnectionInterface> pc_; | 571 scoped_refptr<PeerConnectionInterface> pc_; |
| 911 MockPeerConnectionObserver observer_; | 572 MockPeerConnectionObserver observer_; |
| 912 rtc::scoped_refptr<StreamCollection> reference_collection_; | |
| 913 }; | 573 }; |
| 914 | 574 |
| 915 TEST_F(PeerConnectionInterfaceTest, | 575 TEST_F(PeerConnectionInterfaceTest, |
| 916 CreatePeerConnectionWithDifferentConfigurations) { | 576 CreatePeerConnectionWithDifferentConfigurations) { |
| 917 CreatePeerConnectionWithDifferentConfigurations(); | 577 CreatePeerConnectionWithDifferentConfigurations(); |
| 918 } | 578 } |
| 919 | 579 |
| 920 TEST_F(PeerConnectionInterfaceTest, AddStreams) { | 580 TEST_F(PeerConnectionInterfaceTest, AddStreams) { |
| 921 CreatePeerConnection(); | 581 CreatePeerConnection(); |
| 922 AddVideoStream(kStreamLabel1); | 582 AddStream(kStreamLabel1); |
| 923 AddVoiceStream(kStreamLabel2); | 583 AddVoiceStream(kStreamLabel2); |
| 924 ASSERT_EQ(2u, pc_->local_streams()->count()); | 584 ASSERT_EQ(2u, pc_->local_streams()->count()); |
| 925 | 585 |
| 926 // Test we can add multiple local streams to one peerconnection. | 586 // Test we can add multiple local streams to one peerconnection. |
| 927 scoped_refptr<MediaStreamInterface> stream( | 587 scoped_refptr<MediaStreamInterface> stream( |
| 928 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); | 588 pc_factory_->CreateLocalMediaStream(kStreamLabel3)); |
| 929 scoped_refptr<AudioTrackInterface> audio_track( | 589 scoped_refptr<AudioTrackInterface> audio_track( |
| 930 pc_factory_->CreateAudioTrack( | 590 pc_factory_->CreateAudioTrack( |
| 931 kStreamLabel3, static_cast<AudioSourceInterface*>(NULL))); | 591 kStreamLabel3, static_cast<AudioSourceInterface*>(NULL))); |
| 932 stream->AddTrack(audio_track.get()); | 592 stream->AddTrack(audio_track.get()); |
| 933 EXPECT_TRUE(pc_->AddStream(stream)); | 593 EXPECT_TRUE(pc_->AddStream(stream)); |
| 934 EXPECT_EQ(3u, pc_->local_streams()->count()); | 594 EXPECT_EQ(3u, pc_->local_streams()->count()); |
| 935 | 595 |
| 936 // Remove the third stream. | 596 // Remove the third stream. |
| 937 pc_->RemoveStream(pc_->local_streams()->at(2)); | 597 pc_->RemoveStream(pc_->local_streams()->at(2)); |
| 938 EXPECT_EQ(2u, pc_->local_streams()->count()); | 598 EXPECT_EQ(2u, pc_->local_streams()->count()); |
| 939 | 599 |
| 940 // Remove the second stream. | 600 // Remove the second stream. |
| 941 pc_->RemoveStream(pc_->local_streams()->at(1)); | 601 pc_->RemoveStream(pc_->local_streams()->at(1)); |
| 942 EXPECT_EQ(1u, pc_->local_streams()->count()); | 602 EXPECT_EQ(1u, pc_->local_streams()->count()); |
| 943 | 603 |
| 944 // Remove the first stream. | 604 // Remove the first stream. |
| 945 pc_->RemoveStream(pc_->local_streams()->at(0)); | 605 pc_->RemoveStream(pc_->local_streams()->at(0)); |
| 946 EXPECT_EQ(0u, pc_->local_streams()->count()); | 606 EXPECT_EQ(0u, pc_->local_streams()->count()); |
| 947 } | 607 } |
| 948 | 608 |
| 949 // Test that the created offer includes streams we added. | |
| 950 TEST_F(PeerConnectionInterfaceTest, AddedStreamsPresentInOffer) { | |
| 951 CreatePeerConnection(); | |
| 952 AddAudioVideoStream(kStreamLabel1, "audio_track", "video_track"); | |
| 953 scoped_ptr<SessionDescriptionInterface> offer; | |
| 954 ASSERT_TRUE(DoCreateOffer(offer.accept())); | |
| 955 | |
| 956 const cricket::ContentInfo* audio_content = | |
| 957 cricket::GetFirstAudioContent(offer->description()); | |
| 958 const cricket::AudioContentDescription* audio_desc = | |
| 959 static_cast<const cricket::AudioContentDescription*>( | |
| 960 audio_content->description); | |
| 961 EXPECT_TRUE( | |
| 962 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track")); | |
| 963 | |
| 964 const cricket::ContentInfo* video_content = | |
| 965 cricket::GetFirstVideoContent(offer->description()); | |
| 966 const cricket::VideoContentDescription* video_desc = | |
| 967 static_cast<const cricket::VideoContentDescription*>( | |
| 968 video_content->description); | |
| 969 EXPECT_TRUE( | |
| 970 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track")); | |
| 971 | |
| 972 // Add another stream and ensure the offer includes both the old and new | |
| 973 // streams. | |
| 974 AddAudioVideoStream(kStreamLabel2, "audio_track2", "video_track2"); | |
| 975 ASSERT_TRUE(DoCreateOffer(offer.accept())); | |
| 976 | |
| 977 audio_content = cricket::GetFirstAudioContent(offer->description()); | |
| 978 audio_desc = static_cast<const cricket::AudioContentDescription*>( | |
| 979 audio_content->description); | |
| 980 EXPECT_TRUE( | |
| 981 ContainsTrack(audio_desc->streams(), kStreamLabel1, "audio_track")); | |
| 982 EXPECT_TRUE( | |
| 983 ContainsTrack(audio_desc->streams(), kStreamLabel2, "audio_track2")); | |
| 984 | |
| 985 video_content = cricket::GetFirstVideoContent(offer->description()); | |
| 986 video_desc = static_cast<const cricket::VideoContentDescription*>( | |
| 987 video_content->description); | |
| 988 EXPECT_TRUE( | |
| 989 ContainsTrack(video_desc->streams(), kStreamLabel1, "video_track")); | |
| 990 EXPECT_TRUE( | |
| 991 ContainsTrack(video_desc->streams(), kStreamLabel2, "video_track2")); | |
| 992 } | |
| 993 | |
| 994 TEST_F(PeerConnectionInterfaceTest, RemoveStream) { | 609 TEST_F(PeerConnectionInterfaceTest, RemoveStream) { |
| 995 CreatePeerConnection(); | 610 CreatePeerConnection(); |
| 996 AddVideoStream(kStreamLabel1); | 611 AddStream(kStreamLabel1); |
| 997 ASSERT_EQ(1u, pc_->local_streams()->count()); | 612 ASSERT_EQ(1u, pc_->local_streams()->count()); |
| 998 pc_->RemoveStream(pc_->local_streams()->at(0)); | 613 pc_->RemoveStream(pc_->local_streams()->at(0)); |
| 999 EXPECT_EQ(0u, pc_->local_streams()->count()); | 614 EXPECT_EQ(0u, pc_->local_streams()->count()); |
| 1000 } | 615 } |
| 1001 | 616 |
| 1002 TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) { | 617 TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) { |
| 1003 InitiateCall(); | 618 InitiateCall(); |
| 1004 WaitAndVerifyOnAddStream(kStreamLabel1); | 619 WaitAndVerifyOnAddStream(kStreamLabel1); |
| 1005 VerifyRemoteRtpHeaderExtensions(); | 620 VerifyRemoteRtpHeaderExtensions(); |
| 1006 } | 621 } |
| 1007 | 622 |
| 1008 TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) { | 623 TEST_F(PeerConnectionInterfaceTest, CreateOfferReceivePrAnswerAndAnswer) { |
| 1009 CreatePeerConnection(); | 624 CreatePeerConnection(); |
| 1010 AddVideoStream(kStreamLabel1); | 625 AddStream(kStreamLabel1); |
| 1011 CreateOfferAsLocalDescription(); | 626 CreateOfferAsLocalDescription(); |
| 1012 std::string offer; | 627 std::string offer; |
| 1013 EXPECT_TRUE(pc_->local_description()->ToString(&offer)); | 628 EXPECT_TRUE(pc_->local_description()->ToString(&offer)); |
| 1014 CreatePrAnswerAndAnswerAsRemoteDescription(offer); | 629 CreatePrAnswerAndAnswerAsRemoteDescription(offer); |
| 1015 WaitAndVerifyOnAddStream(kStreamLabel1); | 630 WaitAndVerifyOnAddStream(kStreamLabel1); |
| 1016 } | 631 } |
| 1017 | 632 |
| 1018 TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) { | 633 TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreateAnswer) { |
| 1019 CreatePeerConnection(); | 634 CreatePeerConnection(); |
| 1020 AddVideoStream(kStreamLabel1); | 635 AddStream(kStreamLabel1); |
| 1021 | 636 |
| 1022 CreateOfferAsRemoteDescription(); | 637 CreateOfferAsRemoteDescription(); |
| 1023 CreateAnswerAsLocalDescription(); | 638 CreateAnswerAsLocalDescription(); |
| 1024 | 639 |
| 1025 WaitAndVerifyOnAddStream(kStreamLabel1); | 640 WaitAndVerifyOnAddStream(kStreamLabel1); |
| 1026 } | 641 } |
| 1027 | 642 |
| 1028 TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) { | 643 TEST_F(PeerConnectionInterfaceTest, ReceiveOfferCreatePrAnswerAndAnswer) { |
| 1029 CreatePeerConnection(); | 644 CreatePeerConnection(); |
| 1030 AddVideoStream(kStreamLabel1); | 645 AddStream(kStreamLabel1); |
| 1031 | 646 |
| 1032 CreateOfferAsRemoteDescription(); | 647 CreateOfferAsRemoteDescription(); |
| 1033 CreatePrAnswerAsLocalDescription(); | 648 CreatePrAnswerAsLocalDescription(); |
| 1034 CreateAnswerAsLocalDescription(); | 649 CreateAnswerAsLocalDescription(); |
| 1035 | 650 |
| 1036 WaitAndVerifyOnAddStream(kStreamLabel1); | 651 WaitAndVerifyOnAddStream(kStreamLabel1); |
| 1037 } | 652 } |
| 1038 | 653 |
| 1039 TEST_F(PeerConnectionInterfaceTest, Renegotiate) { | 654 TEST_F(PeerConnectionInterfaceTest, Renegotiate) { |
| 1040 InitiateCall(); | 655 InitiateCall(); |
| 1041 ASSERT_EQ(1u, pc_->remote_streams()->count()); | 656 ASSERT_EQ(1u, pc_->remote_streams()->count()); |
| 1042 pc_->RemoveStream(pc_->local_streams()->at(0)); | 657 pc_->RemoveStream(pc_->local_streams()->at(0)); |
| 1043 CreateOfferReceiveAnswer(); | 658 CreateOfferReceiveAnswer(); |
| 1044 EXPECT_EQ(0u, pc_->remote_streams()->count()); | 659 EXPECT_EQ(0u, pc_->remote_streams()->count()); |
| 1045 AddVideoStream(kStreamLabel1); | 660 AddStream(kStreamLabel1); |
| 1046 CreateOfferReceiveAnswer(); | 661 CreateOfferReceiveAnswer(); |
| 1047 } | 662 } |
| 1048 | 663 |
| 1049 // Tests that after negotiating an audio only call, the respondent can perform a | 664 // Tests that after negotiating an audio only call, the respondent can perform a |
| 1050 // renegotiation that removes the audio stream. | 665 // renegotiation that removes the audio stream. |
| 1051 TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) { | 666 TEST_F(PeerConnectionInterfaceTest, RenegotiateAudioOnly) { |
| 1052 CreatePeerConnection(); | 667 CreatePeerConnection(); |
| 1053 AddVoiceStream(kStreamLabel1); | 668 AddVoiceStream(kStreamLabel1); |
| 1054 CreateOfferAsRemoteDescription(); | 669 CreateOfferAsRemoteDescription(); |
| 1055 CreateAnswerAsLocalDescription(); | 670 CreateAnswerAsLocalDescription(); |
| 1056 | 671 |
| 1057 ASSERT_EQ(1u, pc_->remote_streams()->count()); | 672 ASSERT_EQ(1u, pc_->remote_streams()->count()); |
| 1058 pc_->RemoveStream(pc_->local_streams()->at(0)); | 673 pc_->RemoveStream(pc_->local_streams()->at(0)); |
| 1059 CreateOfferReceiveAnswer(); | 674 CreateOfferReceiveAnswer(); |
| 1060 EXPECT_EQ(0u, pc_->remote_streams()->count()); | 675 EXPECT_EQ(0u, pc_->remote_streams()->count()); |
| 1061 } | 676 } |
| 1062 | 677 |
| 1063 // Test that candidates are generated and that we can parse our own candidates. | 678 // Test that candidates are generated and that we can parse our own candidates. |
| 1064 TEST_F(PeerConnectionInterfaceTest, IceCandidates) { | 679 TEST_F(PeerConnectionInterfaceTest, IceCandidates) { |
| 1065 CreatePeerConnection(); | 680 CreatePeerConnection(); |
| 1066 | 681 |
| 1067 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get())); | 682 EXPECT_FALSE(pc_->AddIceCandidate(observer_.last_candidate_.get())); |
| 1068 // SetRemoteDescription takes ownership of offer. | 683 // SetRemoteDescription takes ownership of offer. |
| 1069 SessionDescriptionInterface* offer = NULL; | 684 SessionDescriptionInterface* offer = NULL; |
| 1070 AddVideoStream(kStreamLabel1); | 685 AddStream(kStreamLabel1); |
| 1071 EXPECT_TRUE(DoCreateOffer(&offer)); | 686 EXPECT_TRUE(DoCreateOffer(&offer)); |
| 1072 EXPECT_TRUE(DoSetRemoteDescription(offer)); | 687 EXPECT_TRUE(DoSetRemoteDescription(offer)); |
| 1073 | 688 |
| 1074 // SetLocalDescription takes ownership of answer. | 689 // SetLocalDescription takes ownership of answer. |
| 1075 SessionDescriptionInterface* answer = NULL; | 690 SessionDescriptionInterface* answer = NULL; |
| 1076 EXPECT_TRUE(DoCreateAnswer(&answer)); | 691 EXPECT_TRUE(DoCreateAnswer(&answer)); |
| 1077 EXPECT_TRUE(DoSetLocalDescription(answer)); | 692 EXPECT_TRUE(DoSetLocalDescription(answer)); |
| 1078 | 693 |
| 1079 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout); | 694 EXPECT_TRUE_WAIT(observer_.last_candidate_.get() != NULL, kTimeout); |
| 1080 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); | 695 EXPECT_TRUE_WAIT(observer_.ice_complete_, kTimeout); |
| 1081 | 696 |
| 1082 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get())); | 697 EXPECT_TRUE(pc_->AddIceCandidate(observer_.last_candidate_.get())); |
| 1083 } | 698 } |
| 1084 | 699 |
| 1085 // Test that CreateOffer and CreateAnswer will fail if the track labels are | 700 // Test that the CreateOffer and CreatAnswer will fail if the track labels are |
| 1086 // not unique. | 701 // not unique. |
| 1087 TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { | 702 TEST_F(PeerConnectionInterfaceTest, CreateOfferAnswerWithInvalidStream) { |
| 1088 CreatePeerConnection(); | 703 CreatePeerConnection(); |
| 1089 // Create a regular offer for the CreateAnswer test later. | 704 // Create a regular offer for the CreateAnswer test later. |
| 1090 SessionDescriptionInterface* offer = NULL; | 705 SessionDescriptionInterface* offer = NULL; |
| 1091 EXPECT_TRUE(DoCreateOffer(&offer)); | 706 EXPECT_TRUE(DoCreateOffer(&offer)); |
| 1092 EXPECT_TRUE(offer != NULL); | 707 EXPECT_TRUE(offer != NULL); |
| 1093 delete offer; | 708 delete offer; |
| 1094 offer = NULL; | 709 offer = NULL; |
| 1095 | 710 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 CreatePeerConnection(&constraints); | 940 CreatePeerConnection(&constraints); |
| 1326 | 941 |
| 1327 std::string label = "test"; | 942 std::string label = "test"; |
| 1328 webrtc::DataChannelInit config; | 943 webrtc::DataChannelInit config; |
| 1329 config.reliable = true; | 944 config.reliable = true; |
| 1330 scoped_refptr<DataChannelInterface> channel = | 945 scoped_refptr<DataChannelInterface> channel = |
| 1331 pc_->CreateDataChannel(label, &config); | 946 pc_->CreateDataChannel(label, &config); |
| 1332 EXPECT_TRUE(channel == NULL); | 947 EXPECT_TRUE(channel == NULL); |
| 1333 } | 948 } |
| 1334 | 949 |
| 1335 // Verifies that duplicated label is not allowed for RTP data channel. | |
| 1336 TEST_F(PeerConnectionInterfaceTest, RtpDuplicatedLabelNotAllowed) { | |
| 1337 FakeConstraints constraints; | |
| 1338 constraints.SetAllowRtpDataChannels(); | |
| 1339 CreatePeerConnection(&constraints); | |
| 1340 | |
| 1341 std::string label = "test"; | |
| 1342 scoped_refptr<DataChannelInterface> channel = | |
| 1343 pc_->CreateDataChannel(label, nullptr); | |
| 1344 EXPECT_NE(channel, nullptr); | |
| 1345 | |
| 1346 scoped_refptr<DataChannelInterface> dup_channel = | |
| 1347 pc_->CreateDataChannel(label, nullptr); | |
| 1348 EXPECT_EQ(dup_channel, nullptr); | |
| 1349 } | |
| 1350 | |
| 1351 // This tests that a SCTP data channel is returned using different | 950 // This tests that a SCTP data channel is returned using different |
| 1352 // DataChannelInit configurations. | 951 // DataChannelInit configurations. |
| 1353 TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { | 952 TEST_F(PeerConnectionInterfaceTest, CreateSctpDataChannel) { |
| 1354 FakeConstraints constraints; | 953 FakeConstraints constraints; |
| 1355 constraints.SetAllowDtlsSctpDataChannels(); | 954 constraints.SetAllowDtlsSctpDataChannels(); |
| 1356 CreatePeerConnection(&constraints); | 955 CreatePeerConnection(&constraints); |
| 1357 | 956 |
| 1358 webrtc::DataChannelInit config; | 957 webrtc::DataChannelInit config; |
| 1359 | 958 |
| 1360 scoped_refptr<DataChannelInterface> channel = | 959 scoped_refptr<DataChannelInterface> channel = |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 config.id = cricket::kMaxSctpSid; | 1024 config.id = cricket::kMaxSctpSid; |
| 1426 channel = pc_->CreateDataChannel("max", &config); | 1025 channel = pc_->CreateDataChannel("max", &config); |
| 1427 EXPECT_TRUE(channel != NULL); | 1026 EXPECT_TRUE(channel != NULL); |
| 1428 EXPECT_EQ(config.id, channel->id()); | 1027 EXPECT_EQ(config.id, channel->id()); |
| 1429 | 1028 |
| 1430 config.id = cricket::kMaxSctpSid + 1; | 1029 config.id = cricket::kMaxSctpSid + 1; |
| 1431 channel = pc_->CreateDataChannel("x", &config); | 1030 channel = pc_->CreateDataChannel("x", &config); |
| 1432 EXPECT_TRUE(channel == NULL); | 1031 EXPECT_TRUE(channel == NULL); |
| 1433 } | 1032 } |
| 1434 | 1033 |
| 1435 // Verifies that duplicated label is allowed for SCTP data channel. | |
| 1436 TEST_F(PeerConnectionInterfaceTest, SctpDuplicatedLabelAllowed) { | |
| 1437 FakeConstraints constraints; | |
| 1438 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1439 true); | |
| 1440 CreatePeerConnection(&constraints); | |
| 1441 | |
| 1442 std::string label = "test"; | |
| 1443 scoped_refptr<DataChannelInterface> channel = | |
| 1444 pc_->CreateDataChannel(label, nullptr); | |
| 1445 EXPECT_NE(channel, nullptr); | |
| 1446 | |
| 1447 scoped_refptr<DataChannelInterface> dup_channel = | |
| 1448 pc_->CreateDataChannel(label, nullptr); | |
| 1449 EXPECT_NE(dup_channel, nullptr); | |
| 1450 } | |
| 1451 | |
| 1452 // This test verifies that OnRenegotiationNeeded is fired for every new RTP | 1034 // This test verifies that OnRenegotiationNeeded is fired for every new RTP |
| 1453 // DataChannel. | 1035 // DataChannel. |
| 1454 TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) { | 1036 TEST_F(PeerConnectionInterfaceTest, RenegotiationNeededForNewRtpDataChannel) { |
| 1455 FakeConstraints constraints; | 1037 FakeConstraints constraints; |
| 1456 constraints.SetAllowRtpDataChannels(); | 1038 constraints.SetAllowRtpDataChannels(); |
| 1457 CreatePeerConnection(&constraints); | 1039 CreatePeerConnection(&constraints); |
| 1458 | 1040 |
| 1459 scoped_refptr<DataChannelInterface> dc1 = | 1041 scoped_refptr<DataChannelInterface> dc1 = |
| 1460 pc_->CreateDataChannel("test1", NULL); | 1042 pc_->CreateDataChannel("test1", NULL); |
| 1461 EXPECT_TRUE(observer_.renegotiation_needed_); | 1043 EXPECT_TRUE(observer_.renegotiation_needed_); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 sdp, NULL); | 1227 sdp, NULL); |
| 1646 EXPECT_FALSE(DoSetLocalDescription(local_offer)); | 1228 EXPECT_FALSE(DoSetLocalDescription(local_offer)); |
| 1647 } | 1229 } |
| 1648 | 1230 |
| 1649 // Test that GetStats can still be called after PeerConnection::Close. | 1231 // Test that GetStats can still be called after PeerConnection::Close. |
| 1650 TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) { | 1232 TEST_F(PeerConnectionInterfaceTest, CloseAndGetStats) { |
| 1651 InitiateCall(); | 1233 InitiateCall(); |
| 1652 pc_->Close(); | 1234 pc_->Close(); |
| 1653 DoGetStats(NULL); | 1235 DoGetStats(NULL); |
| 1654 } | 1236 } |
| 1655 | |
| 1656 // NOTE: The series of tests below come from what used to be | |
| 1657 // mediastreamsignaling_unittest.cc, and are mostly aimed at testing that | |
| 1658 // setting a remote or local description has the expected effects. | |
| 1659 | |
| 1660 // This test verifies that the remote MediaStreams corresponding to a received | |
| 1661 // SDP string is created. In this test the two separate MediaStreams are | |
| 1662 // signaled. | |
| 1663 TEST_F(PeerConnectionInterfaceTest, UpdateRemoteStreams) { | |
| 1664 FakeConstraints constraints; | |
| 1665 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1666 true); | |
| 1667 CreatePeerConnection(&constraints); | |
| 1668 CreateAndSetRemoteOffer(kSdpStringWithStream1); | |
| 1669 | |
| 1670 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1)); | |
| 1671 EXPECT_TRUE( | |
| 1672 CompareStreamCollections(observer_.remote_streams(), reference.get())); | |
| 1673 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1674 EXPECT_TRUE(remote_stream->GetVideoTracks()[0]->GetSource() != nullptr); | |
| 1675 | |
| 1676 // Create a session description based on another SDP with another | |
| 1677 // MediaStream. | |
| 1678 CreateAndSetRemoteOffer(kSdpStringWithStream1And2); | |
| 1679 | |
| 1680 rtc::scoped_refptr<StreamCollection> reference2(CreateStreamCollection(2)); | |
| 1681 EXPECT_TRUE( | |
| 1682 CompareStreamCollections(observer_.remote_streams(), reference2.get())); | |
| 1683 } | |
| 1684 | |
| 1685 // This test verifies that when remote tracks are added/removed from SDP, the | |
| 1686 // created remote streams are updated appropriately. | |
| 1687 TEST_F(PeerConnectionInterfaceTest, | |
| 1688 AddRemoveTrackFromExistingRemoteMediaStream) { | |
| 1689 FakeConstraints constraints; | |
| 1690 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1691 true); | |
| 1692 CreatePeerConnection(&constraints); | |
| 1693 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms1; | |
| 1694 CreateSessionDescriptionAndReference(1, 1, desc_ms1.accept()); | |
| 1695 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1.release())); | |
| 1696 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), | |
| 1697 reference_collection_)); | |
| 1698 | |
| 1699 // Add extra audio and video tracks to the same MediaStream. | |
| 1700 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms1_two_tracks; | |
| 1701 CreateSessionDescriptionAndReference(2, 2, desc_ms1_two_tracks.accept()); | |
| 1702 EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release())); | |
| 1703 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), | |
| 1704 reference_collection_)); | |
| 1705 | |
| 1706 // Remove the extra audio and video tracks. | |
| 1707 rtc::scoped_ptr<SessionDescriptionInterface> desc_ms2; | |
| 1708 CreateSessionDescriptionAndReference(1, 1, desc_ms2.accept()); | |
| 1709 EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release())); | |
| 1710 EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), | |
| 1711 reference_collection_)); | |
| 1712 } | |
| 1713 | |
| 1714 // This tests that remote tracks are ended if a local session description is set | |
| 1715 // that rejects the media content type. | |
| 1716 TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) { | |
| 1717 FakeConstraints constraints; | |
| 1718 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1719 true); | |
| 1720 CreatePeerConnection(&constraints); | |
| 1721 // First create and set a remote offer, then reject its video content in our | |
| 1722 // answer. | |
| 1723 CreateAndSetRemoteOffer(kSdpStringWithStream1); | |
| 1724 ASSERT_EQ(1u, observer_.remote_streams()->count()); | |
| 1725 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1726 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size()); | |
| 1727 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size()); | |
| 1728 | |
| 1729 rtc::scoped_refptr<webrtc::VideoTrackInterface> remote_video = | |
| 1730 remote_stream->GetVideoTracks()[0]; | |
| 1731 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_video->state()); | |
| 1732 rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_audio = | |
| 1733 remote_stream->GetAudioTracks()[0]; | |
| 1734 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state()); | |
| 1735 | |
| 1736 rtc::scoped_ptr<SessionDescriptionInterface> local_answer; | |
| 1737 EXPECT_TRUE(DoCreateAnswer(local_answer.accept())); | |
| 1738 cricket::ContentInfo* video_info = | |
| 1739 local_answer->description()->GetContentByName("video"); | |
| 1740 video_info->rejected = true; | |
| 1741 EXPECT_TRUE(DoSetLocalDescription(local_answer.release())); | |
| 1742 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state()); | |
| 1743 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, remote_audio->state()); | |
| 1744 | |
| 1745 // Now create an offer where we reject both video and audio. | |
| 1746 rtc::scoped_ptr<SessionDescriptionInterface> local_offer; | |
| 1747 EXPECT_TRUE(DoCreateOffer(local_offer.accept())); | |
| 1748 video_info = local_offer->description()->GetContentByName("video"); | |
| 1749 ASSERT_TRUE(video_info != nullptr); | |
| 1750 video_info->rejected = true; | |
| 1751 cricket::ContentInfo* audio_info = | |
| 1752 local_offer->description()->GetContentByName("audio"); | |
| 1753 ASSERT_TRUE(audio_info != nullptr); | |
| 1754 audio_info->rejected = true; | |
| 1755 EXPECT_TRUE(DoSetLocalDescription(local_offer.release())); | |
| 1756 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state()); | |
| 1757 EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_audio->state()); | |
| 1758 } | |
| 1759 | |
| 1760 // This tests that we won't crash if the remote track has been removed outside | |
| 1761 // of PeerConnection and then PeerConnection tries to reject the track. | |
| 1762 TEST_F(PeerConnectionInterfaceTest, RemoveTrackThenRejectMediaContent) { | |
| 1763 FakeConstraints constraints; | |
| 1764 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1765 true); | |
| 1766 CreatePeerConnection(&constraints); | |
| 1767 CreateAndSetRemoteOffer(kSdpStringWithStream1); | |
| 1768 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1769 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]); | |
| 1770 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]); | |
| 1771 | |
| 1772 rtc::scoped_ptr<SessionDescriptionInterface> local_answer( | |
| 1773 webrtc::CreateSessionDescription(SessionDescriptionInterface::kAnswer, | |
| 1774 kSdpStringWithStream1, nullptr)); | |
| 1775 cricket::ContentInfo* video_info = | |
| 1776 local_answer->description()->GetContentByName("video"); | |
| 1777 video_info->rejected = true; | |
| 1778 cricket::ContentInfo* audio_info = | |
| 1779 local_answer->description()->GetContentByName("audio"); | |
| 1780 audio_info->rejected = true; | |
| 1781 EXPECT_TRUE(DoSetLocalDescription(local_answer.release())); | |
| 1782 | |
| 1783 // No crash is a pass. | |
| 1784 } | |
| 1785 | |
| 1786 // This tests that a default MediaStream is created if a remote session | |
| 1787 // description doesn't contain any streams and no MSID support. | |
| 1788 // It also tests that the default stream is updated if a video m-line is added | |
| 1789 // in a subsequent session description. | |
| 1790 TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) { | |
| 1791 FakeConstraints constraints; | |
| 1792 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1793 true); | |
| 1794 CreatePeerConnection(&constraints); | |
| 1795 CreateAndSetRemoteOffer(kSdpStringWithoutStreamsAudioOnly); | |
| 1796 | |
| 1797 ASSERT_EQ(1u, observer_.remote_streams()->count()); | |
| 1798 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1799 | |
| 1800 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size()); | |
| 1801 EXPECT_EQ(0u, remote_stream->GetVideoTracks().size()); | |
| 1802 EXPECT_EQ("default", remote_stream->label()); | |
| 1803 | |
| 1804 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); | |
| 1805 ASSERT_EQ(1u, observer_.remote_streams()->count()); | |
| 1806 ASSERT_EQ(1u, remote_stream->GetAudioTracks().size()); | |
| 1807 EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id()); | |
| 1808 ASSERT_EQ(1u, remote_stream->GetVideoTracks().size()); | |
| 1809 EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id()); | |
| 1810 } | |
| 1811 | |
| 1812 // This tests that a default MediaStream is created if a remote session | |
| 1813 // description doesn't contain any streams and media direction is send only. | |
| 1814 TEST_F(PeerConnectionInterfaceTest, | |
| 1815 SendOnlySdpWithoutMsidCreatesDefaultStream) { | |
| 1816 FakeConstraints constraints; | |
| 1817 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1818 true); | |
| 1819 CreatePeerConnection(&constraints); | |
| 1820 CreateAndSetRemoteOffer(kSdpStringSendOnlyWithoutStreams); | |
| 1821 | |
| 1822 ASSERT_EQ(1u, observer_.remote_streams()->count()); | |
| 1823 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1824 | |
| 1825 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size()); | |
| 1826 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size()); | |
| 1827 EXPECT_EQ("default", remote_stream->label()); | |
| 1828 } | |
| 1829 | |
| 1830 // This tests that it won't crash when PeerConnection tries to remove | |
| 1831 // a remote track that as already been removed from the MediaStream. | |
| 1832 TEST_F(PeerConnectionInterfaceTest, RemoveAlreadyGoneRemoteStream) { | |
| 1833 FakeConstraints constraints; | |
| 1834 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1835 true); | |
| 1836 CreatePeerConnection(&constraints); | |
| 1837 CreateAndSetRemoteOffer(kSdpStringWithStream1); | |
| 1838 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1839 remote_stream->RemoveTrack(remote_stream->GetAudioTracks()[0]); | |
| 1840 remote_stream->RemoveTrack(remote_stream->GetVideoTracks()[0]); | |
| 1841 | |
| 1842 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); | |
| 1843 | |
| 1844 // No crash is a pass. | |
| 1845 } | |
| 1846 | |
| 1847 // This tests that a default MediaStream is created if the remote session | |
| 1848 // description doesn't contain any streams and don't contain an indication if | |
| 1849 // MSID is supported. | |
| 1850 TEST_F(PeerConnectionInterfaceTest, | |
| 1851 SdpWithoutMsidAndStreamsCreatesDefaultStream) { | |
| 1852 FakeConstraints constraints; | |
| 1853 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1854 true); | |
| 1855 CreatePeerConnection(&constraints); | |
| 1856 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); | |
| 1857 | |
| 1858 ASSERT_EQ(1u, observer_.remote_streams()->count()); | |
| 1859 MediaStreamInterface* remote_stream = observer_.remote_streams()->at(0); | |
| 1860 EXPECT_EQ(1u, remote_stream->GetAudioTracks().size()); | |
| 1861 EXPECT_EQ(1u, remote_stream->GetVideoTracks().size()); | |
| 1862 } | |
| 1863 | |
| 1864 // This tests that a default MediaStream is not created if the remote session | |
| 1865 // description doesn't contain any streams but does support MSID. | |
| 1866 TEST_F(PeerConnectionInterfaceTest, SdpWithMsidDontCreatesDefaultStream) { | |
| 1867 FakeConstraints constraints; | |
| 1868 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1869 true); | |
| 1870 CreatePeerConnection(&constraints); | |
| 1871 CreateAndSetRemoteOffer(kSdpStringWithMsidWithoutStreams); | |
| 1872 EXPECT_EQ(0u, observer_.remote_streams()->count()); | |
| 1873 } | |
| 1874 | |
| 1875 // This tests that a default MediaStream is not created if a remote session | |
| 1876 // description is updated to not have any MediaStreams. | |
| 1877 TEST_F(PeerConnectionInterfaceTest, VerifyDefaultStreamIsNotCreated) { | |
| 1878 FakeConstraints constraints; | |
| 1879 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1880 true); | |
| 1881 CreatePeerConnection(&constraints); | |
| 1882 CreateAndSetRemoteOffer(kSdpStringWithStream1); | |
| 1883 rtc::scoped_refptr<StreamCollection> reference(CreateStreamCollection(1)); | |
| 1884 EXPECT_TRUE( | |
| 1885 CompareStreamCollections(observer_.remote_streams(), reference.get())); | |
| 1886 | |
| 1887 CreateAndSetRemoteOffer(kSdpStringWithoutStreams); | |
| 1888 EXPECT_EQ(0u, observer_.remote_streams()->count()); | |
| 1889 } | |
| 1890 | |
| 1891 // This tests that an RtpSender is created when the local description is set | |
| 1892 // after adding a local stream. | |
| 1893 // TODO(deadbeef): This test and the one below it need to be updated when | |
| 1894 // an RtpSender's lifetime isn't determined by when a local description is set. | |
| 1895 TEST_F(PeerConnectionInterfaceTest, LocalDescriptionChanged) { | |
| 1896 FakeConstraints constraints; | |
| 1897 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1898 true); | |
| 1899 CreatePeerConnection(&constraints); | |
| 1900 // Create an offer just to ensure we have an identity before we manually | |
| 1901 // call SetLocalDescription. | |
| 1902 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; | |
| 1903 ASSERT_TRUE(DoCreateOffer(throwaway.accept())); | |
| 1904 | |
| 1905 rtc::scoped_ptr<SessionDescriptionInterface> desc_1; | |
| 1906 CreateSessionDescriptionAndReference(2, 2, desc_1.accept()); | |
| 1907 | |
| 1908 pc_->AddStream(reference_collection_->at(0)); | |
| 1909 EXPECT_TRUE(DoSetLocalDescription(desc_1.release())); | |
| 1910 auto senders = pc_->GetSenders(); | |
| 1911 EXPECT_EQ(4u, senders.size()); | |
| 1912 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 1913 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 1914 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1])); | |
| 1915 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1])); | |
| 1916 | |
| 1917 // Remove an audio and video track. | |
| 1918 rtc::scoped_ptr<SessionDescriptionInterface> desc_2; | |
| 1919 CreateSessionDescriptionAndReference(1, 1, desc_2.accept()); | |
| 1920 EXPECT_TRUE(DoSetLocalDescription(desc_2.release())); | |
| 1921 senders = pc_->GetSenders(); | |
| 1922 EXPECT_EQ(2u, senders.size()); | |
| 1923 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 1924 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 1925 EXPECT_FALSE(ContainsSender(senders, kAudioTracks[1])); | |
| 1926 EXPECT_FALSE(ContainsSender(senders, kVideoTracks[1])); | |
| 1927 } | |
| 1928 | |
| 1929 // This tests that an RtpSender is created when the local description is set | |
| 1930 // before adding a local stream. | |
| 1931 TEST_F(PeerConnectionInterfaceTest, | |
| 1932 AddLocalStreamAfterLocalDescriptionChanged) { | |
| 1933 FakeConstraints constraints; | |
| 1934 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1935 true); | |
| 1936 CreatePeerConnection(&constraints); | |
| 1937 // Create an offer just to ensure we have an identity before we manually | |
| 1938 // call SetLocalDescription. | |
| 1939 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; | |
| 1940 ASSERT_TRUE(DoCreateOffer(throwaway.accept())); | |
| 1941 | |
| 1942 rtc::scoped_ptr<SessionDescriptionInterface> desc_1; | |
| 1943 CreateSessionDescriptionAndReference(2, 2, desc_1.accept()); | |
| 1944 | |
| 1945 EXPECT_TRUE(DoSetLocalDescription(desc_1.release())); | |
| 1946 auto senders = pc_->GetSenders(); | |
| 1947 EXPECT_EQ(0u, senders.size()); | |
| 1948 | |
| 1949 pc_->AddStream(reference_collection_->at(0)); | |
| 1950 senders = pc_->GetSenders(); | |
| 1951 EXPECT_EQ(4u, senders.size()); | |
| 1952 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 1953 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 1954 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[1])); | |
| 1955 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[1])); | |
| 1956 } | |
| 1957 | |
| 1958 // This tests that the expected behavior occurs if the SSRC on a local track is | |
| 1959 // changed when SetLocalDescription is called. | |
| 1960 TEST_F(PeerConnectionInterfaceTest, | |
| 1961 ChangeSsrcOnTrackInLocalSessionDescription) { | |
| 1962 FakeConstraints constraints; | |
| 1963 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 1964 true); | |
| 1965 CreatePeerConnection(&constraints); | |
| 1966 // Create an offer just to ensure we have an identity before we manually | |
| 1967 // call SetLocalDescription. | |
| 1968 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; | |
| 1969 ASSERT_TRUE(DoCreateOffer(throwaway.accept())); | |
| 1970 | |
| 1971 rtc::scoped_ptr<SessionDescriptionInterface> desc; | |
| 1972 CreateSessionDescriptionAndReference(1, 1, desc.accept()); | |
| 1973 std::string sdp; | |
| 1974 desc->ToString(&sdp); | |
| 1975 | |
| 1976 pc_->AddStream(reference_collection_->at(0)); | |
| 1977 EXPECT_TRUE(DoSetLocalDescription(desc.release())); | |
| 1978 auto senders = pc_->GetSenders(); | |
| 1979 EXPECT_EQ(2u, senders.size()); | |
| 1980 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 1981 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 1982 | |
| 1983 // Change the ssrc of the audio and video track. | |
| 1984 std::string ssrc_org = "a=ssrc:1"; | |
| 1985 std::string ssrc_to = "a=ssrc:97"; | |
| 1986 rtc::replace_substrs(ssrc_org.c_str(), ssrc_org.length(), ssrc_to.c_str(), | |
| 1987 ssrc_to.length(), &sdp); | |
| 1988 ssrc_org = "a=ssrc:2"; | |
| 1989 ssrc_to = "a=ssrc:98"; | |
| 1990 rtc::replace_substrs(ssrc_org.c_str(), ssrc_org.length(), ssrc_to.c_str(), | |
| 1991 ssrc_to.length(), &sdp); | |
| 1992 rtc::scoped_ptr<SessionDescriptionInterface> updated_desc( | |
| 1993 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp, | |
| 1994 nullptr)); | |
| 1995 | |
| 1996 EXPECT_TRUE(DoSetLocalDescription(updated_desc.release())); | |
| 1997 senders = pc_->GetSenders(); | |
| 1998 EXPECT_EQ(2u, senders.size()); | |
| 1999 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 2000 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 2001 // TODO(deadbeef): Once RtpSenders expose parameters, check that the SSRC | |
| 2002 // changed. | |
| 2003 } | |
| 2004 | |
| 2005 // This tests that the expected behavior occurs if a new session description is | |
| 2006 // set with the same tracks, but on a different MediaStream. | |
| 2007 TEST_F(PeerConnectionInterfaceTest, SignalSameTracksInSeparateMediaStream) { | |
| 2008 FakeConstraints constraints; | |
| 2009 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
| 2010 true); | |
| 2011 CreatePeerConnection(&constraints); | |
| 2012 // Create an offer just to ensure we have an identity before we manually | |
| 2013 // call SetLocalDescription. | |
| 2014 rtc::scoped_ptr<SessionDescriptionInterface> throwaway; | |
| 2015 ASSERT_TRUE(DoCreateOffer(throwaway.accept())); | |
| 2016 | |
| 2017 rtc::scoped_ptr<SessionDescriptionInterface> desc; | |
| 2018 CreateSessionDescriptionAndReference(1, 1, desc.accept()); | |
| 2019 std::string sdp; | |
| 2020 desc->ToString(&sdp); | |
| 2021 | |
| 2022 pc_->AddStream(reference_collection_->at(0)); | |
| 2023 EXPECT_TRUE(DoSetLocalDescription(desc.release())); | |
| 2024 auto senders = pc_->GetSenders(); | |
| 2025 EXPECT_EQ(2u, senders.size()); | |
| 2026 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 2027 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 2028 | |
| 2029 // Add a new MediaStream but with the same tracks as in the first stream. | |
| 2030 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream_1( | |
| 2031 webrtc::MediaStream::Create(kStreams[1])); | |
| 2032 stream_1->AddTrack(reference_collection_->at(0)->GetVideoTracks()[0]); | |
| 2033 stream_1->AddTrack(reference_collection_->at(0)->GetAudioTracks()[0]); | |
| 2034 pc_->AddStream(stream_1); | |
| 2035 | |
| 2036 // Replace msid in the original SDP. | |
| 2037 rtc::replace_substrs(kStreams[0], strlen(kStreams[0]), kStreams[1], | |
| 2038 strlen(kStreams[1]), &sdp); | |
| 2039 | |
| 2040 rtc::scoped_ptr<SessionDescriptionInterface> updated_desc( | |
| 2041 webrtc::CreateSessionDescription(SessionDescriptionInterface::kOffer, sdp, | |
| 2042 nullptr)); | |
| 2043 | |
| 2044 EXPECT_TRUE(DoSetLocalDescription(updated_desc.release())); | |
| 2045 senders = pc_->GetSenders(); | |
| 2046 EXPECT_EQ(2u, senders.size()); | |
| 2047 EXPECT_TRUE(ContainsSender(senders, kAudioTracks[0])); | |
| 2048 EXPECT_TRUE(ContainsSender(senders, kVideoTracks[0])); | |
| 2049 } | |
| 2050 | |
| 2051 // The following tests verify that session options are created correctly. | |
| 2052 | |
| 2053 TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidAudioOption) { | |
| 2054 RTCOfferAnswerOptions rtc_options; | |
| 2055 rtc_options.offer_to_receive_audio = RTCOfferAnswerOptions::kUndefined - 1; | |
| 2056 | |
| 2057 cricket::MediaSessionOptions options; | |
| 2058 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2059 | |
| 2060 rtc_options.offer_to_receive_audio = | |
| 2061 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1; | |
| 2062 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2063 } | |
| 2064 | |
| 2065 TEST(CreateSessionOptionsTest, GetOptionsForOfferWithInvalidVideoOption) { | |
| 2066 RTCOfferAnswerOptions rtc_options; | |
| 2067 rtc_options.offer_to_receive_video = RTCOfferAnswerOptions::kUndefined - 1; | |
| 2068 | |
| 2069 cricket::MediaSessionOptions options; | |
| 2070 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2071 | |
| 2072 rtc_options.offer_to_receive_video = | |
| 2073 RTCOfferAnswerOptions::kMaxOfferToReceiveMedia + 1; | |
| 2074 EXPECT_FALSE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2075 } | |
| 2076 | |
| 2077 // Test that a MediaSessionOptions is created for an offer if | |
| 2078 // OfferToReceiveAudio and OfferToReceiveVideo options are set but no | |
| 2079 // MediaStreams are sent. | |
| 2080 TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudioVideo) { | |
| 2081 RTCOfferAnswerOptions rtc_options; | |
| 2082 rtc_options.offer_to_receive_audio = 1; | |
| 2083 rtc_options.offer_to_receive_video = 1; | |
| 2084 | |
| 2085 cricket::MediaSessionOptions options; | |
| 2086 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2087 EXPECT_TRUE(options.has_audio()); | |
| 2088 EXPECT_TRUE(options.has_video()); | |
| 2089 EXPECT_TRUE(options.bundle_enabled); | |
| 2090 } | |
| 2091 | |
| 2092 // Test that a correct MediaSessionOptions is created for an offer if | |
| 2093 // OfferToReceiveAudio is set but no MediaStreams are sent. | |
| 2094 TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithAudio) { | |
| 2095 RTCOfferAnswerOptions rtc_options; | |
| 2096 rtc_options.offer_to_receive_audio = 1; | |
| 2097 | |
| 2098 cricket::MediaSessionOptions options; | |
| 2099 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2100 EXPECT_TRUE(options.has_audio()); | |
| 2101 EXPECT_FALSE(options.has_video()); | |
| 2102 EXPECT_TRUE(options.bundle_enabled); | |
| 2103 } | |
| 2104 | |
| 2105 // Test that a correct MediaSessionOptions is created for an offer if | |
| 2106 // the default OfferOptons is used or MediaStreams are sent. | |
| 2107 TEST(CreateSessionOptionsTest, GetDefaultMediaSessionOptionsForOffer) { | |
| 2108 RTCOfferAnswerOptions rtc_options; | |
| 2109 | |
| 2110 cricket::MediaSessionOptions options; | |
| 2111 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2112 EXPECT_FALSE(options.has_audio()); | |
| 2113 EXPECT_FALSE(options.has_video()); | |
| 2114 EXPECT_FALSE(options.bundle_enabled); | |
| 2115 EXPECT_TRUE(options.vad_enabled); | |
| 2116 EXPECT_FALSE(options.transport_options.ice_restart); | |
| 2117 } | |
| 2118 | |
| 2119 // Test that a correct MediaSessionOptions is created for an offer if | |
| 2120 // OfferToReceiveVideo is set but no MediaStreams are sent. | |
| 2121 TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithVideo) { | |
| 2122 RTCOfferAnswerOptions rtc_options; | |
| 2123 rtc_options.offer_to_receive_audio = 0; | |
| 2124 rtc_options.offer_to_receive_video = 1; | |
| 2125 | |
| 2126 cricket::MediaSessionOptions options; | |
| 2127 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2128 EXPECT_FALSE(options.has_audio()); | |
| 2129 EXPECT_TRUE(options.has_video()); | |
| 2130 EXPECT_TRUE(options.bundle_enabled); | |
| 2131 } | |
| 2132 | |
| 2133 // Test that a correct MediaSessionOptions is created for an offer if | |
| 2134 // UseRtpMux is set to false. | |
| 2135 TEST(CreateSessionOptionsTest, | |
| 2136 GetMediaSessionOptionsForOfferWithBundleDisabled) { | |
| 2137 RTCOfferAnswerOptions rtc_options; | |
| 2138 rtc_options.offer_to_receive_audio = 1; | |
| 2139 rtc_options.offer_to_receive_video = 1; | |
| 2140 rtc_options.use_rtp_mux = false; | |
| 2141 | |
| 2142 cricket::MediaSessionOptions options; | |
| 2143 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2144 EXPECT_TRUE(options.has_audio()); | |
| 2145 EXPECT_TRUE(options.has_video()); | |
| 2146 EXPECT_FALSE(options.bundle_enabled); | |
| 2147 } | |
| 2148 | |
| 2149 // Test that a correct MediaSessionOptions is created to restart ice if | |
| 2150 // IceRestart is set. It also tests that subsequent MediaSessionOptions don't | |
| 2151 // have |transport_options.ice_restart| set. | |
| 2152 TEST(CreateSessionOptionsTest, GetMediaSessionOptionsForOfferWithIceRestart) { | |
| 2153 RTCOfferAnswerOptions rtc_options; | |
| 2154 rtc_options.ice_restart = true; | |
| 2155 | |
| 2156 cricket::MediaSessionOptions options; | |
| 2157 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2158 EXPECT_TRUE(options.transport_options.ice_restart); | |
| 2159 | |
| 2160 rtc_options = RTCOfferAnswerOptions(); | |
| 2161 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_options, &options)); | |
| 2162 EXPECT_FALSE(options.transport_options.ice_restart); | |
| 2163 } | |
| 2164 | |
| 2165 // Test that the MediaConstraints in an answer don't affect if audio and video | |
| 2166 // is offered in an offer but that if kOfferToReceiveAudio or | |
| 2167 // kOfferToReceiveVideo constraints are true in an offer, the media type will be | |
| 2168 // included in subsequent answers. | |
| 2169 TEST(CreateSessionOptionsTest, MediaConstraintsInAnswer) { | |
| 2170 FakeConstraints answer_c; | |
| 2171 answer_c.SetMandatoryReceiveAudio(true); | |
| 2172 answer_c.SetMandatoryReceiveVideo(true); | |
| 2173 | |
| 2174 cricket::MediaSessionOptions answer_options; | |
| 2175 EXPECT_TRUE(ParseConstraintsForAnswer(&answer_c, &answer_options)); | |
| 2176 EXPECT_TRUE(answer_options.has_audio()); | |
| 2177 EXPECT_TRUE(answer_options.has_video()); | |
| 2178 | |
| 2179 RTCOfferAnswerOptions rtc_offer_optoins; | |
| 2180 | |
| 2181 cricket::MediaSessionOptions offer_options; | |
| 2182 EXPECT_TRUE(ConvertRtcOptionsForOffer(rtc_offer_optoins, &offer_options)); | |
| 2183 EXPECT_FALSE(offer_options.has_audio()); | |
| 2184 EXPECT_FALSE(offer_options.has_video()); | |
| 2185 | |
| 2186 RTCOfferAnswerOptions updated_rtc_offer_optoins; | |
| 2187 updated_rtc_offer_optoins.offer_to_receive_audio = 1; | |
| 2188 updated_rtc_offer_optoins.offer_to_receive_video = 1; | |
| 2189 | |
| 2190 cricket::MediaSessionOptions updated_offer_options; | |
| 2191 EXPECT_TRUE(ConvertRtcOptionsForOffer(updated_rtc_offer_optoins, | |
| 2192 &updated_offer_options)); | |
| 2193 EXPECT_TRUE(updated_offer_options.has_audio()); | |
| 2194 EXPECT_TRUE(updated_offer_options.has_video()); | |
| 2195 | |
| 2196 // Since an offer has been created with both audio and video, subsequent | |
| 2197 // offers and answers should contain both audio and video. | |
| 2198 // Answers will only contain the media types that exist in the offer | |
| 2199 // regardless of the value of |updated_answer_options.has_audio| and | |
| 2200 // |updated_answer_options.has_video|. | |
| 2201 FakeConstraints updated_answer_c; | |
| 2202 answer_c.SetMandatoryReceiveAudio(false); | |
| 2203 answer_c.SetMandatoryReceiveVideo(false); | |
| 2204 | |
| 2205 cricket::MediaSessionOptions updated_answer_options; | |
| 2206 EXPECT_TRUE( | |
| 2207 ParseConstraintsForAnswer(&updated_answer_c, &updated_answer_options)); | |
| 2208 EXPECT_TRUE(updated_answer_options.has_audio()); | |
| 2209 EXPECT_TRUE(updated_answer_options.has_video()); | |
| 2210 | |
| 2211 RTCOfferAnswerOptions default_rtc_options; | |
| 2212 EXPECT_TRUE( | |
| 2213 ConvertRtcOptionsForOffer(default_rtc_options, &updated_offer_options)); | |
| 2214 // By default, |has_audio| or |has_video| are false if there is no media | |
| 2215 // track. | |
| 2216 EXPECT_FALSE(updated_offer_options.has_audio()); | |
| 2217 EXPECT_FALSE(updated_offer_options.has_video()); | |
| 2218 } | |
| OLD | NEW |