3
* Copyright 2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
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
14
* derived from this software without specific prior written permission.
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
18
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
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,
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
25
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
#include "talk/app/webrtc/webrtcsession.h"
29
#include "talk/app/webrtc/jsepicecandidate.h"
30
#include "talk/app/webrtc/jsepsessiondescription.h"
31
#include "talk/app/webrtc/mediastreamsignaling.h"
32
#include "talk/base/logging.h"
33
#include "talk/base/fakenetwork.h"
34
#include "talk/base/firewallsocketserver.h"
35
#include "talk/base/gunit.h"
36
#include "talk/base/network.h"
37
#include "talk/base/physicalsocketserver.h"
38
#include "talk/base/thread.h"
39
#include "talk/base/virtualsocketserver.h"
40
#include "talk/p2p/base/stunserver.h"
41
#include "talk/p2p/base/teststunserver.h"
42
#include "talk/p2p/client/basicportallocator.h"
43
#include "talk/session/phone/channelmanager.h"
44
#include "talk/session/phone/fakedevicemanager.h"
45
#include "talk/session/phone/fakemediaengine.h"
46
#include "talk/session/phone/mediasession.h"
48
using talk_base::scoped_ptr;
49
using talk_base::SocketAddress;
50
using webrtc::IceCandidateColletion;
51
using webrtc::JsepInterface;
52
using webrtc::JsepSessionDescription;
53
using webrtc::JsepIceCandidate;
54
using webrtc::SessionDescriptionInterface;
56
using webrtc::MediaHints;
58
static const SocketAddress kClientAddr1("11.11.11.11", 0);
59
static const SocketAddress kClientAddr2("22.22.22.22", 0);
60
static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
62
static const char kStream1[] = "stream1";
63
static const char kVideoTrack1[] = "video1";
64
static const char kAudioTrack1[] = "audio1";
66
static const char kStream2[] = "stream2";
67
static const char kVideoTrack2[] = "video2";
68
static const char kAudioTrack2[] = "audio2";
70
// Label of candidates belonging to the first media content.
71
static const char kMediaContentLabel0[] = "0";
72
static const int kMediaContentIndex0 = 0;
74
// Label of candidates belonging to the second media content.
75
static const char kMediaContentLabel1[] = "1";
76
static const int kMediaContentIndex1 = 1;
78
static const int kIceCandidatesTimeout = 3000;
81
class MockCandidateObserver : public webrtc::IceCandidateObserver {
83
MockCandidateObserver()
84
: oncandidatesready_(false) {
87
// Found a new candidate.
88
virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
89
if (candidate->label() == kMediaContentLabel0) {
90
mline_0_candidates_.push_back(candidate->candidate());
91
} else if (candidate->label() == kMediaContentLabel1) {
92
mline_1_candidates_.push_back(candidate->candidate());
96
virtual void OnIceComplete() {
97
EXPECT_FALSE(oncandidatesready_);
98
oncandidatesready_ = true;
101
bool oncandidatesready_;
102
std::vector<cricket::Candidate> mline_0_candidates_;
103
std::vector<cricket::Candidate> mline_1_candidates_;
106
class WebRtcSessionForTest : public webrtc::WebRtcSession {
108
WebRtcSessionForTest(cricket::ChannelManager* cmgr,
109
talk_base::Thread* signaling_thread,
110
talk_base::Thread* worker_thread,
111
cricket::PortAllocator* port_allocator,
112
webrtc::IceCandidateObserver* ice_observer,
113
webrtc::MediaStreamSignaling* mediastream_signaling)
114
: WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
115
mediastream_signaling) {
116
RegisterObserver(ice_observer);
118
virtual ~WebRtcSessionForTest() {}
120
using webrtc::WebRtcSession::CreateOffer;
121
using webrtc::WebRtcSession::CreateAnswer;
122
using webrtc::WebRtcSession::SetLocalDescription;
123
using webrtc::WebRtcSession::SetRemoteDescription;
124
using webrtc::WebRtcSession::ProcessIceMessage;
127
class FakeMediaStreamSignaling : public webrtc::MediaStreamSignaling,
128
public webrtc::RemoteMediaStreamObserver {
130
FakeMediaStreamSignaling() :
131
webrtc::MediaStreamSignaling(talk_base::Thread::Current(), this) {
134
// Overrides GetMediaSessionOptions in MediaStreamSignaling.
135
// Instead of depending on MediaStreams this version of GetMediaSessionOptions
136
// returns the options decided by MediaSessionOptions set in one of the below
137
// UseOptions functions.
138
virtual cricket::MediaSessionOptions GetMediaSessionOptions(
139
const MediaHints& hints) const {
143
void UseOptionsWithStream1() {
144
cricket::MediaSessionOptions options;
145
options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1, kStream1);
146
options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1, kStream1);
150
void UseOptionsWithStream2() {
151
cricket::MediaSessionOptions options;
152
options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2, kStream2);
153
options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2, kStream2);
157
void UseOptionsWithStream1And2() {
158
cricket::MediaSessionOptions options;
159
options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1, kStream1);
160
options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1, kStream1);
161
options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2, kStream2);
162
options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2, kStream2);
166
void UseOptionsReceiveOnly() {
167
cricket::MediaSessionOptions options;
168
options.has_video = true;
172
// Implements RemoteMediaStreamObserver.
173
virtual void OnAddStream(webrtc::MediaStreamInterface* stream) {
175
virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) {
179
cricket::MediaSessionOptions options_;
182
class WebRtcSessionTest : public testing::Test {
184
// TODO Investigate why ChannelManager crashes, if it's created
185
// after stun_server.
187
: media_engine(new cricket::FakeMediaEngine()),
188
device_manager(new cricket::FakeDeviceManager()),
189
channel_manager_(new cricket::ChannelManager(
190
media_engine, device_manager, talk_base::Thread::Current())),
191
desc_factory_(new cricket::MediaSessionDescriptionFactory(
192
channel_manager_.get())),
193
pss_(new talk_base::PhysicalSocketServer),
194
vss_(new talk_base::VirtualSocketServer(pss_.get())),
195
fss_(new talk_base::FirewallSocketServer(vss_.get())),
196
ss_scope_(fss_.get()),
197
stun_server_(talk_base::Thread::Current(), kStunAddr),
198
allocator_(&network_manager_, kStunAddr,
199
SocketAddress(), SocketAddress(), SocketAddress()) {
200
EXPECT_TRUE(channel_manager_->Init());
201
desc_factory_->set_add_legacy_streams(false);
204
void AddInterface(const SocketAddress& addr) {
205
network_manager_.AddInterface(addr);
209
ASSERT_TRUE(session_.get() == NULL);
210
session_.reset(new WebRtcSessionForTest(
211
channel_manager_.get(), talk_base::Thread::Current(),
212
talk_base::Thread::Current(), &allocator_,
214
&mediastream_signaling_));
216
EXPECT_TRUE(session_->Initialize());
217
mediastream_signaling_.UseOptionsReceiveOnly();
219
video_channel_ = media_engine->GetVideoChannel(0);
220
voice_channel_ = media_engine->GetVoiceChannel(0);
223
// Creates a local offer and applies it. Starts ice.
224
// Call mediastream_signaling_.UseOptionsWithStreamX() before this function
225
// to decide which streams to create.
226
void InitiateCall() {
227
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
228
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
229
EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
232
bool ChannelsExist() {
233
return (session_->voice_channel() != NULL &&
234
session_->video_channel() != NULL);
237
void CheckTransportChannels() {
238
EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, "rtp") != NULL);
239
EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, "rtcp") != NULL);
240
EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, "video_rtp") != NULL);
241
EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, "video_rtcp") != NULL);
244
void VerifyCryptoParams(const cricket::SessionDescription* sdp,
246
ASSERT_TRUE(session_.get() != NULL);
247
const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
248
ASSERT_TRUE(content != NULL);
249
const cricket::AudioContentDescription* audio_content =
250
static_cast<const cricket::AudioContentDescription*>(
251
content->description);
252
ASSERT_TRUE(audio_content != NULL);
254
ASSERT_EQ(2U, audio_content->cryptos().size());
255
// key(40) + inline string
256
ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
257
ASSERT_EQ("AES_CM_128_HMAC_SHA1_32",
258
audio_content->cryptos()[0].cipher_suite);
259
ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
260
audio_content->cryptos()[1].cipher_suite);
261
ASSERT_EQ(47U, audio_content->cryptos()[1].key_params.size());
263
ASSERT_EQ(1U, audio_content->cryptos().size());
264
// key(40) + inline string
265
ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
266
ASSERT_EQ("AES_CM_128_HMAC_SHA1_32",
267
audio_content->cryptos()[0].cipher_suite);
270
content = cricket::GetFirstVideoContent(sdp);
271
ASSERT_TRUE(content != NULL);
272
const cricket::VideoContentDescription* video_content =
273
static_cast<const cricket::VideoContentDescription*>(
274
content->description);
275
ASSERT_TRUE(video_content != NULL);
276
ASSERT_EQ(1U, video_content->cryptos().size());
277
ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
278
video_content->cryptos()[0].cipher_suite);
279
ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
282
void VerifyNoCryptoParams(const cricket::SessionDescription* sdp) {
283
const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
284
ASSERT_TRUE(content != NULL);
285
const cricket::AudioContentDescription* audio_content =
286
static_cast<const cricket::AudioContentDescription*>(
287
content->description);
288
ASSERT_TRUE(audio_content != NULL);
289
ASSERT_EQ(0U, audio_content->cryptos().size());
291
content = cricket::GetFirstVideoContent(sdp);
292
ASSERT_TRUE(content != NULL);
293
const cricket::VideoContentDescription* video_content =
294
static_cast<const cricket::VideoContentDescription*>(
295
content->description);
296
ASSERT_TRUE(video_content != NULL);
297
ASSERT_EQ(0U, video_content->cryptos().size());
300
void VerifyAnswerFromNonCryptoOffer() {
301
// Create a SDP without Crypto.
302
desc_factory_->set_secure(cricket::SEC_DISABLED);
303
cricket::MediaSessionOptions options;
304
options.has_video = true;
305
scoped_ptr<JsepSessionDescription> offer(
306
new JsepSessionDescription(desc_factory_->CreateOffer(options, NULL)));
307
ASSERT_TRUE(offer.get() != NULL);
308
VerifyNoCryptoParams(offer->description());
309
const webrtc::SessionDescriptionInterface* answer =
310
session_->CreateAnswer(MediaHints(), offer.get());
311
// Answer should be NULL as no crypto params in offer.
312
ASSERT_TRUE(answer->description() == NULL);
315
void VerifyAnswerFromCryptoOffer() {
316
desc_factory_->set_secure(cricket::SEC_REQUIRED);
317
cricket::MediaSessionOptions options;
318
options.has_video = true;
319
scoped_ptr<JsepSessionDescription> offer(
320
new JsepSessionDescription(desc_factory_->CreateOffer(options, NULL)));
321
ASSERT_TRUE(offer.get() != NULL);
322
VerifyCryptoParams(offer->description(), true);
323
scoped_ptr<SessionDescriptionInterface> answer(
324
session_->CreateAnswer(MediaHints(), offer.get()));
325
ASSERT_TRUE(answer.get() != NULL);
326
VerifyCryptoParams(answer->description(), false);
328
// Creates and offer and an answer and applies it on the offer.
329
// Call mediastream_signaling_.UseOptionsWithStreamX() before this function
330
// to decide which streams to create.
331
void SetRemoteAndLocalSessionDescription() {
332
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
333
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
335
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
336
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
339
cricket::FakeMediaEngine* media_engine;
340
cricket::FakeDeviceManager* device_manager;
341
talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
342
talk_base::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
343
talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
344
talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
345
talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
346
talk_base::SocketServerScope ss_scope_;
347
cricket::TestStunServer stun_server_;
348
talk_base::FakeNetworkManager network_manager_;
349
cricket::BasicPortAllocator allocator_;
350
FakeMediaStreamSignaling mediastream_signaling_;
351
talk_base::scoped_ptr<WebRtcSessionForTest> session_;
352
MockCandidateObserver observer_;
353
cricket::FakeVideoMediaChannel* video_channel_;
354
cricket::FakeVoiceMediaChannel* voice_channel_;
357
TEST_F(WebRtcSessionTest, TestInitialize) {
358
WebRtcSessionTest::Init();
359
EXPECT_TRUE(ChannelsExist());
360
CheckTransportChannels();
363
TEST_F(WebRtcSessionTest, TestSessionCandidates) {
364
AddInterface(kClientAddr1);
365
WebRtcSessionTest::Init();
366
WebRtcSessionTest::InitiateCall();
367
EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
368
EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
369
EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
372
TEST_F(WebRtcSessionTest, TestMultihomeCandidataes) {
373
AddInterface(kClientAddr1);
374
AddInterface(kClientAddr2);
375
WebRtcSessionTest::Init();
376
WebRtcSessionTest::InitiateCall();
377
EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
378
EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
379
EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
382
TEST_F(WebRtcSessionTest, TestStunError) {
383
AddInterface(kClientAddr1);
384
AddInterface(kClientAddr2);
385
fss_->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY, kClientAddr1);
386
WebRtcSessionTest::Init();
387
WebRtcSessionTest::InitiateCall();
388
// Since kClientAddr1 is blocked, not expecting stun candidates for it.
389
EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
390
EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
391
EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
394
// Test creating offers and receive answers and make sure the
395
// media engine creates the expected send and receive streams.
396
TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
397
WebRtcSessionTest::Init();
398
mediastream_signaling_.UseOptionsWithStream1();
399
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
401
mediastream_signaling_.UseOptionsWithStream2();
402
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
404
// SetLocalDescription and SetRemoteDescriptions takes ownership of offer
406
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
407
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
409
ASSERT_EQ(1u, video_channel_->recv_streams().size());
410
EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].name);
412
ASSERT_EQ(1u, voice_channel_->recv_streams().size());
413
EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].name);
415
ASSERT_EQ(1u, video_channel_->send_streams().size());
416
EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].name);
417
ASSERT_EQ(1u, voice_channel_->send_streams().size());
418
EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].name);
420
// Create new offer without send streams.
421
mediastream_signaling_.UseOptionsReceiveOnly();
422
offer = session_->CreateOffer(MediaHints());
424
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
426
mediastream_signaling_.UseOptionsWithStream2();
427
answer = session_->CreateAnswer(MediaHints(), offer);
428
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
430
EXPECT_EQ(0u, video_channel_->send_streams().size());
431
EXPECT_EQ(0u, voice_channel_->send_streams().size());
433
// Make sure the receive streams have not changed.
434
ASSERT_EQ(1u, video_channel_->recv_streams().size());
435
EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].name);
436
ASSERT_EQ(1u, voice_channel_->recv_streams().size());
437
EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].name);
440
// Test receiving offers and creating answers and make sure the
441
// media engine creates the expected send and receive streams.
442
TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
443
WebRtcSessionTest::Init();
444
mediastream_signaling_.UseOptionsWithStream2();
445
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
447
mediastream_signaling_.UseOptionsWithStream1();
448
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
451
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
452
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
454
ASSERT_EQ(1u, video_channel_->recv_streams().size());
455
EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].name);
457
ASSERT_EQ(1u, voice_channel_->recv_streams().size());
458
EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].name);
460
ASSERT_EQ(1u, video_channel_->send_streams().size());
461
EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].name);
462
ASSERT_EQ(1u, voice_channel_->send_streams().size());
463
EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].name);
465
mediastream_signaling_.UseOptionsWithStream1And2();
466
offer = session_->CreateOffer(MediaHints());
468
// Answer by turning off all send streams.
469
mediastream_signaling_.UseOptionsReceiveOnly();
470
answer = session_->CreateAnswer(MediaHints(), offer);
472
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
473
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
475
ASSERT_EQ(2u, video_channel_->recv_streams().size());
476
EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].name);
477
EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].name);
478
ASSERT_EQ(2u, voice_channel_->recv_streams().size());
479
EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].name);
480
EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].name);
482
// Make sure we have no send streams.
483
EXPECT_EQ(0u, video_channel_->send_streams().size());
484
EXPECT_EQ(0u, voice_channel_->send_streams().size());
487
TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
488
WebRtcSessionTest::Init();
489
mediastream_signaling_.UseOptionsReceiveOnly();
490
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
492
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
493
EXPECT_FALSE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
496
TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
497
WebRtcSessionTest::Init();
498
mediastream_signaling_.UseOptionsReceiveOnly();
499
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
500
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
501
EXPECT_FALSE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
504
TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
505
WebRtcSessionTest::Init();
506
mediastream_signaling_.UseOptionsReceiveOnly();
507
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
508
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
509
EXPECT_FALSE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
512
TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
513
WebRtcSessionTest::Init();
514
mediastream_signaling_.UseOptionsReceiveOnly();
515
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
516
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
517
EXPECT_FALSE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
520
TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
521
WebRtcSessionTest::Init();
522
mediastream_signaling_.UseOptionsReceiveOnly();
523
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
524
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
526
EXPECT_FALSE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
529
TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
530
WebRtcSessionTest::Init();
531
mediastream_signaling_.UseOptionsReceiveOnly();
532
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
533
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
535
EXPECT_FALSE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
538
TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
539
WebRtcSessionTest::Init();
541
cricket::Candidate candidate1;
542
candidate1.set_name("fake_candidate1");
543
JsepIceCandidate ice_candidate(talk_base::ToString(0), candidate1);
545
// Fail since we have not set a remote description
546
EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate));
548
SetRemoteAndLocalSessionDescription();
550
EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
552
JsepIceCandidate bad_ice_candidate("bad content name", candidate1);
553
EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
556
// Test that a remote candidate is added to the remote session description and
557
// that it is retained if the remote session description is changed.
558
TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
559
WebRtcSessionTest::Init();
560
cricket::Candidate candidate1;
561
candidate1.set_name("fake_candidate1");
562
JsepIceCandidate ice_candidate1(kMediaContentLabel0, candidate1);
564
SetRemoteAndLocalSessionDescription();
565
EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
567
EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
568
const SessionDescriptionInterface* remote_desc =
569
session_->remote_description();
570
ASSERT_TRUE(remote_desc != NULL);
571
ASSERT_EQ(2u, remote_desc->number_of_mediasections());
572
const IceCandidateColletion* candidates =
573
remote_desc->candidates(kMediaContentIndex0);
574
ASSERT_EQ(1u, candidates->count());
575
EXPECT_EQ(kMediaContentLabel0, candidates->at(0)->label());
577
// Update the RemoteSessionDescription with a new session description and
578
// a candidate and check that the new remote session description contains both
580
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
581
cricket::Candidate candidate2;
582
candidate2.set_name("fake_candidate2");
583
JsepIceCandidate ice_candidate2(kMediaContentLabel0, candidate2);
584
EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
585
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
587
remote_desc = session_->remote_description();
588
ASSERT_TRUE(remote_desc != NULL);
589
ASSERT_EQ(2u, remote_desc->number_of_mediasections());
590
candidates = remote_desc->candidates(kMediaContentIndex0);
591
ASSERT_EQ(2u, candidates->count());
592
EXPECT_EQ(kMediaContentLabel0, candidates->at(0)->label());
593
EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
594
EXPECT_EQ(kMediaContentLabel0, candidates->at(1)->label());
595
EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
597
// Test that the candidate is ignored if we can add the same candidate again.
598
EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
601
// Test that local candidates are added to the local session description and
602
// that they are retained if the local session description is changed.
603
TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
604
AddInterface(kClientAddr1);
605
WebRtcSessionTest::Init();
606
SetRemoteAndLocalSessionDescription();
608
const SessionDescriptionInterface* local_desc = session_->local_description();
609
const IceCandidateColletion* candidates =
610
local_desc->candidates(kMediaContentIndex0);
611
ASSERT_TRUE(candidates != NULL);
612
EXPECT_EQ(0u, candidates->count());
614
EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
615
EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
617
local_desc = session_->local_description();
618
candidates = local_desc->candidates(kMediaContentIndex0);
619
ASSERT_TRUE(candidates != NULL);
620
EXPECT_LT(0u, candidates->count());
621
candidates = local_desc->candidates(1);
622
ASSERT_TRUE(candidates != NULL);
623
EXPECT_LT(0u, candidates->count());
625
// Update the session descriptions.
626
mediastream_signaling_.UseOptionsWithStream1();
627
SetRemoteAndLocalSessionDescription();
629
local_desc = session_->local_description();
630
candidates = local_desc->candidates(kMediaContentIndex0);
631
ASSERT_TRUE(candidates != NULL);
632
EXPECT_LT(0u, candidates->count());
633
candidates = local_desc->candidates(1);
634
ASSERT_TRUE(candidates != NULL);
635
EXPECT_LT(0u, candidates->count());
638
// Test that we can set a remote session description with remote candidates.
639
TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
640
WebRtcSessionTest::Init();
642
cricket::Candidate candidate1;
643
candidate1.set_name("fake_candidate1");
645
JsepIceCandidate ice_candidate(kMediaContentLabel0, candidate1);
646
mediastream_signaling_.UseOptionsReceiveOnly();
647
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
649
EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
650
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
652
const SessionDescriptionInterface* remote_desc =
653
session_->remote_description();
654
ASSERT_TRUE(remote_desc != NULL);
655
ASSERT_EQ(2u, remote_desc->number_of_mediasections());
656
const IceCandidateColletion* candidates =
657
remote_desc->candidates(kMediaContentIndex0);
658
ASSERT_EQ(1u, candidates->count());
659
EXPECT_EQ(kMediaContentLabel0, candidates->at(0)->label());
661
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
663
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
664
EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
665
// TODO: How do I check that the transport have got the
666
// remote candidates?
669
// Test that offers and answers contains ice canidates when Ice candidates have
671
TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
672
AddInterface(kClientAddr1);
673
WebRtcSessionTest::Init();
674
mediastream_signaling_.UseOptionsReceiveOnly();
675
SetRemoteAndLocalSessionDescription();
676
EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
677
// Wait until at least one local candidate has been collected.
678
EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
679
kIceCandidatesTimeout);
680
EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
681
kIceCandidatesTimeout);
683
SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
684
ASSERT_TRUE(offer->candidates(kMediaContentIndex0) != NULL);
685
EXPECT_LT(0u, offer->candidates(kMediaContentIndex0)->count());
686
ASSERT_TRUE(offer->candidates(kMediaContentIndex1) != NULL);
687
EXPECT_LT(0u, offer->candidates(kMediaContentIndex1)->count());
689
SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
691
ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
692
EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
693
ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
694
EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
696
EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
697
EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
701
TEST_F(WebRtcSessionTest, TestDefaultSetSecurePolicy) {
702
WebRtcSessionTest::Init();
703
EXPECT_EQ(cricket::SEC_REQUIRED, session_->secure_policy());
706
TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
707
WebRtcSessionTest::Init();
708
mediastream_signaling_.UseOptionsWithStream1();
709
scoped_ptr<SessionDescriptionInterface> offer(
710
session_->CreateOffer(MediaHints()));
711
VerifyCryptoParams(offer->description(), true);
714
TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
715
WebRtcSessionTest::Init();
716
session_->set_secure_policy(cricket::SEC_DISABLED);
717
mediastream_signaling_.UseOptionsWithStream1();
718
scoped_ptr<SessionDescriptionInterface> offer(
719
session_->CreateOffer(MediaHints()));
720
VerifyNoCryptoParams(offer->description());
723
TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
724
WebRtcSessionTest::Init();
725
VerifyAnswerFromNonCryptoOffer();
728
TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
729
WebRtcSessionTest::Init();
730
VerifyAnswerFromCryptoOffer();