Update stable to r5195.
git-svn-id: http://webrtc.googlecode.com/svn/stable/talk@5196 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/app/webrtc/peerconnectionendtoend_unittest.cc b/app/webrtc/peerconnectionendtoend_unittest.cc
new file mode 100644
index 0000000..da3c03d
--- /dev/null
+++ b/app/webrtc/peerconnectionendtoend_unittest.cc
@@ -0,0 +1,224 @@
+/*
+ * libjingle
+ * Copyright 2013, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/app/webrtc/test/peerconnectiontestwrapper.h"
+#include "talk/base/gunit.h"
+#include "talk/base/logging.h"
+#include "talk/base/ssladapter.h"
+#include "talk/base/sslstreamadapter.h"
+#include "talk/base/stringencode.h"
+#include "talk/base/stringutils.h"
+
+using webrtc::FakeConstraints;
+using webrtc::MediaConstraintsInterface;
+using webrtc::MediaStreamInterface;
+using webrtc::PeerConnectionInterface;
+
+namespace {
+
+const char kExternalGiceUfrag[] = "1234567890123456";
+const char kExternalGicePwd[] = "123456789012345678901234";
+
+void RemoveLinesFromSdp(const std::string& line_start,
+ std::string* sdp) {
+ const char kSdpLineEnd[] = "\r\n";
+ size_t ssrc_pos = 0;
+ while ((ssrc_pos = sdp->find(line_start, ssrc_pos)) !=
+ std::string::npos) {
+ size_t end_ssrc = sdp->find(kSdpLineEnd, ssrc_pos);
+ sdp->erase(ssrc_pos, end_ssrc - ssrc_pos + strlen(kSdpLineEnd));
+ }
+}
+
+// Add |newlines| to the |message| after |line|.
+void InjectAfter(const std::string& line,
+ const std::string& newlines,
+ std::string* message) {
+ const std::string tmp = line + newlines;
+ talk_base::replace_substrs(line.c_str(), line.length(),
+ tmp.c_str(), tmp.length(), message);
+}
+
+void Replace(const std::string& line,
+ const std::string& newlines,
+ std::string* message) {
+ talk_base::replace_substrs(line.c_str(), line.length(),
+ newlines.c_str(), newlines.length(), message);
+}
+
+void UseExternalSdes(std::string* sdp) {
+ // Remove current crypto specification.
+ RemoveLinesFromSdp("a=crypto", sdp);
+ RemoveLinesFromSdp("a=fingerprint", sdp);
+ // Add external crypto.
+ const char kAudioSdes[] =
+ "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
+ "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR\r\n";
+ const char kVideoSdes[] =
+ "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
+ "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj\r\n";
+ const char kDataSdes[] =
+ "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
+ "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj\r\n";
+ InjectAfter("a=mid:audio\r\n", kAudioSdes, sdp);
+ InjectAfter("a=mid:video\r\n", kVideoSdes, sdp);
+ InjectAfter("a=mid:data\r\n", kDataSdes, sdp);
+}
+
+void UseGice(std::string* sdp) {
+ InjectAfter("t=0 0\r\n", "a=ice-options:google-ice\r\n", sdp);
+
+ std::string ufragline = "a=ice-ufrag:";
+ std::string pwdline = "a=ice-pwd:";
+ RemoveLinesFromSdp(ufragline, sdp);
+ RemoveLinesFromSdp(pwdline, sdp);
+ ufragline.append(kExternalGiceUfrag);
+ ufragline.append("\r\n");
+ pwdline.append(kExternalGicePwd);
+ pwdline.append("\r\n");
+ const std::string ufrag_pwd = ufragline + pwdline;
+
+ InjectAfter("a=mid:audio\r\n", ufrag_pwd, sdp);
+ InjectAfter("a=mid:video\r\n", ufrag_pwd, sdp);
+ InjectAfter("a=mid:data\r\n", ufrag_pwd, sdp);
+}
+
+void RemoveBundle(std::string* sdp) {
+ RemoveLinesFromSdp("a=group:BUNDLE", sdp);
+}
+
+} // namespace
+
+class PeerConnectionEndToEndTest
+ : public sigslot::has_slots<>,
+ public testing::Test {
+ public:
+ PeerConnectionEndToEndTest()
+ : caller_(new talk_base::RefCountedObject<PeerConnectionTestWrapper>(
+ "caller")),
+ callee_(new talk_base::RefCountedObject<PeerConnectionTestWrapper>(
+ "callee")) {
+ talk_base::InitializeSSL(NULL);
+ }
+
+ void CreatePcs() {
+ CreatePcs(NULL);
+ }
+
+ void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
+ EXPECT_TRUE(caller_->CreatePc(pc_constraints));
+ EXPECT_TRUE(callee_->CreatePc(pc_constraints));
+ PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
+ }
+
+ void GetAndAddUserMedia() {
+ FakeConstraints audio_constraints;
+ FakeConstraints video_constraints;
+ GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
+ }
+
+ void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
+ bool video, FakeConstraints video_constraints) {
+ caller_->GetAndAddUserMedia(audio, audio_constraints,
+ video, video_constraints);
+ callee_->GetAndAddUserMedia(audio, audio_constraints,
+ video, video_constraints);
+ }
+
+ void Negotiate() {
+ caller_->CreateOffer(NULL);
+ }
+
+ void WaitForCallEstablished() {
+ caller_->WaitForCallEstablished();
+ callee_->WaitForCallEstablished();
+ }
+
+ void SetupLegacySdpConverter() {
+ caller_->SignalOnSdpCreated.connect(
+ this, &PeerConnectionEndToEndTest::ConvertToLegacySdp);
+ callee_->SignalOnSdpCreated.connect(
+ this, &PeerConnectionEndToEndTest::ConvertToLegacySdp);
+ }
+
+ void ConvertToLegacySdp(std::string* sdp) {
+ UseExternalSdes(sdp);
+ UseGice(sdp);
+ RemoveBundle(sdp);
+ LOG(LS_INFO) << "ConvertToLegacySdp: " << *sdp;
+ }
+
+ void SetupGiceConverter() {
+ caller_->SignalOnIceCandidateCreated.connect(
+ this, &PeerConnectionEndToEndTest::AddGiceCredsToCandidate);
+ callee_->SignalOnIceCandidateCreated.connect(
+ this, &PeerConnectionEndToEndTest::AddGiceCredsToCandidate);
+ }
+
+ void AddGiceCredsToCandidate(std::string* sdp) {
+ std::string gice_creds = " username ";
+ gice_creds.append(kExternalGiceUfrag);
+ gice_creds.append(" password ");
+ gice_creds.append(kExternalGicePwd);
+ gice_creds.append("\r\n");
+ Replace("\r\n", gice_creds, sdp);
+ LOG(LS_INFO) << "AddGiceCredsToCandidate: " << *sdp;
+ }
+
+ ~PeerConnectionEndToEndTest() {
+ talk_base::CleanupSSL();
+ }
+
+ protected:
+ talk_base::scoped_refptr<PeerConnectionTestWrapper> caller_;
+ talk_base::scoped_refptr<PeerConnectionTestWrapper> callee_;
+};
+
+// Disable for TSan v2, see
+// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
+#if !defined(THREAD_SANITIZER)
+
+TEST_F(PeerConnectionEndToEndTest, Call) {
+ CreatePcs();
+ GetAndAddUserMedia();
+ Negotiate();
+ WaitForCallEstablished();
+}
+
+TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
+ FakeConstraints pc_constraints;
+ pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
+ false);
+ CreatePcs(&pc_constraints);
+ SetupLegacySdpConverter();
+ SetupGiceConverter();
+ GetAndAddUserMedia();
+ Negotiate();
+ WaitForCallEstablished();
+}
+
+#endif // if !defined(THREAD_SANITIZER)
diff --git a/app/webrtc/statscollector.cc b/app/webrtc/statscollector.cc
index db7cac4..57277b6 100644
--- a/app/webrtc/statscollector.cc
+++ b/app/webrtc/statscollector.cc
@@ -100,6 +100,8 @@
const char StatsReport::kStatsValueNameIssuerId[] = "googIssuerId";
const char StatsReport::kStatsValueNameJitterReceived[] = "googJitterReceived";
const char StatsReport::kStatsValueNameLocalAddress[] = "googLocalAddress";
+const char StatsReport::kStatsValueNameLocalCandidateType[] =
+ "googLocalCandidateType";
const char StatsReport::kStatsValueNameLocalCertificateId[] =
"googLocalCertificateId";
const char StatsReport::kStatsValueNameNacksReceived[] = "googNacksReceived";
@@ -109,6 +111,8 @@
const char StatsReport::kStatsValueNamePacketsLost[] = "packetsLost";
const char StatsReport::kStatsValueNameReadable[] = "googReadable";
const char StatsReport::kStatsValueNameRemoteAddress[] = "googRemoteAddress";
+const char StatsReport::kStatsValueNameRemoteCandidateType[] =
+ "googRemoteCandidateType";
const char StatsReport::kStatsValueNameRemoteCertificateId[] =
"googRemoteCertificateId";
const char StatsReport::kStatsValueNameRetransmitBitrate[] =
@@ -678,6 +682,10 @@
report.AddValue(StatsReport::kStatsValueNameRtt, info.rtt);
report.AddValue(StatsReport::kStatsValueNameTransportType,
info.local_candidate.protocol());
+ report.AddValue(StatsReport::kStatsValueNameLocalCandidateType,
+ info.local_candidate.type());
+ report.AddValue(StatsReport::kStatsValueNameRemoteCandidateType,
+ info.remote_candidate.type());
reports_[report.id] = report;
}
}
diff --git a/app/webrtc/statstypes.h b/app/webrtc/statstypes.h
index e76aa86..11a8146 100644
--- a/app/webrtc/statstypes.h
+++ b/app/webrtc/statstypes.h
@@ -177,6 +177,8 @@
static const char kStatsValueNameIssuerId[];
static const char kStatsValueNameLocalCertificateId[];
static const char kStatsValueNameRemoteCertificateId[];
+ static const char kStatsValueNameLocalCandidateType[];
+ static const char kStatsValueNameRemoteCandidateType[];
};
typedef std::vector<StatsReport> StatsReports;
diff --git a/app/webrtc/test/peerconnectiontestwrapper.cc b/app/webrtc/test/peerconnectiontestwrapper.cc
new file mode 100644
index 0000000..c22ecaf
--- /dev/null
+++ b/app/webrtc/test/peerconnectiontestwrapper.cc
@@ -0,0 +1,278 @@
+/*
+ * libjingle
+ * Copyright 2013, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/app/webrtc/fakeportallocatorfactory.h"
+#include "talk/app/webrtc/test/fakeperiodicvideocapturer.h"
+#include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
+#include "talk/app/webrtc/test/peerconnectiontestwrapper.h"
+#include "talk/app/webrtc/videosourceinterface.h"
+#include "talk/base/gunit.h"
+
+static const char kStreamLabelBase[] = "stream_label";
+static const char kVideoTrackLabelBase[] = "video_track";
+static const char kAudioTrackLabelBase[] = "audio_track";
+static const int kMaxWait = 5000;
+static const int kTestAudioFrameCount = 3;
+static const int kTestVideoFrameCount = 3;
+
+using webrtc::FakeConstraints;
+using webrtc::FakeVideoTrackRenderer;
+using webrtc::IceCandidateInterface;
+using webrtc::MediaConstraintsInterface;
+using webrtc::MediaStreamInterface;
+using webrtc::MockSetSessionDescriptionObserver;
+using webrtc::PeerConnectionInterface;
+using webrtc::SessionDescriptionInterface;
+using webrtc::VideoTrackInterface;
+
+void PeerConnectionTestWrapper::Connect(PeerConnectionTestWrapper* caller,
+ PeerConnectionTestWrapper* callee) {
+ caller->SignalOnIceCandidateReady.connect(
+ callee, &PeerConnectionTestWrapper::AddIceCandidate);
+ callee->SignalOnIceCandidateReady.connect(
+ caller, &PeerConnectionTestWrapper::AddIceCandidate);
+
+ caller->SignalOnSdpReady.connect(
+ callee, &PeerConnectionTestWrapper::ReceiveOfferSdp);
+ callee->SignalOnSdpReady.connect(
+ caller, &PeerConnectionTestWrapper::ReceiveAnswerSdp);
+}
+
+PeerConnectionTestWrapper::PeerConnectionTestWrapper(const std::string& name)
+ : name_(name) {}
+
+PeerConnectionTestWrapper::~PeerConnectionTestWrapper() {}
+
+bool PeerConnectionTestWrapper::CreatePc(
+ const MediaConstraintsInterface* constraints) {
+ allocator_factory_ = webrtc::FakePortAllocatorFactory::Create();
+ if (!allocator_factory_) {
+ return false;
+ }
+
+ audio_thread_.Start();
+ fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
+ &audio_thread_);
+ if (fake_audio_capture_module_ == NULL) {
+ return false;
+ }
+
+ peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
+ talk_base::Thread::Current(), talk_base::Thread::Current(),
+ fake_audio_capture_module_, NULL, NULL);
+ if (!peer_connection_factory_) {
+ return false;
+ }
+
+ // CreatePeerConnection with IceServers.
+ webrtc::PeerConnectionInterface::IceServers ice_servers;
+ webrtc::PeerConnectionInterface::IceServer ice_server;
+ ice_server.uri = "stun:stun.l.google.com:19302";
+ ice_servers.push_back(ice_server);
+ peer_connection_ = peer_connection_factory_->CreatePeerConnection(
+ ice_servers, constraints, allocator_factory_.get(), NULL, this);
+
+ return peer_connection_.get() != NULL;
+}
+
+void PeerConnectionTestWrapper::OnAddStream(MediaStreamInterface* stream) {
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": OnAddStream";
+ // TODO(ronghuawu): support multiple streams.
+ if (stream->GetVideoTracks().size() > 0) {
+ renderer_.reset(new FakeVideoTrackRenderer(stream->GetVideoTracks()[0]));
+ }
+}
+
+void PeerConnectionTestWrapper::OnIceCandidate(
+ const IceCandidateInterface* candidate) {
+ std::string sdp;
+ EXPECT_TRUE(candidate->ToString(&sdp));
+ // Give the user a chance to modify sdp for testing.
+ SignalOnIceCandidateCreated(&sdp);
+ SignalOnIceCandidateReady(candidate->sdp_mid(), candidate->sdp_mline_index(),
+ sdp);
+}
+
+void PeerConnectionTestWrapper::OnSuccess(SessionDescriptionInterface* desc) {
+ std::string sdp;
+ EXPECT_TRUE(desc->ToString(&sdp));
+
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": " << desc->type() << " sdp created: " << sdp;
+
+ // Give the user a chance to modify sdp for testing.
+ SignalOnSdpCreated(&sdp);
+
+ SetLocalDescription(desc->type(), sdp);
+
+ SignalOnSdpReady(sdp);
+}
+
+void PeerConnectionTestWrapper::CreateOffer(
+ const MediaConstraintsInterface* constraints) {
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": CreateOffer.";
+ peer_connection_->CreateOffer(this, constraints);
+}
+
+void PeerConnectionTestWrapper::CreateAnswer(
+ const MediaConstraintsInterface* constraints) {
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": CreateAnswer.";
+ peer_connection_->CreateAnswer(this, constraints);
+}
+
+void PeerConnectionTestWrapper::ReceiveOfferSdp(const std::string& sdp) {
+ SetRemoteDescription(SessionDescriptionInterface::kOffer, sdp);
+ CreateAnswer(NULL);
+}
+
+void PeerConnectionTestWrapper::ReceiveAnswerSdp(const std::string& sdp) {
+ SetRemoteDescription(SessionDescriptionInterface::kAnswer, sdp);
+}
+
+void PeerConnectionTestWrapper::SetLocalDescription(const std::string& type,
+ const std::string& sdp) {
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": SetLocalDescription " << type << " " << sdp;
+
+ talk_base::scoped_refptr<MockSetSessionDescriptionObserver>
+ observer(new talk_base::RefCountedObject<
+ MockSetSessionDescriptionObserver>());
+ peer_connection_->SetLocalDescription(
+ observer, webrtc::CreateSessionDescription(type, sdp, NULL));
+}
+
+void PeerConnectionTestWrapper::SetRemoteDescription(const std::string& type,
+ const std::string& sdp) {
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": SetRemoteDescription " << type << " " << sdp;
+
+ talk_base::scoped_refptr<MockSetSessionDescriptionObserver>
+ observer(new talk_base::RefCountedObject<
+ MockSetSessionDescriptionObserver>());
+ peer_connection_->SetRemoteDescription(
+ observer, webrtc::CreateSessionDescription(type, sdp, NULL));
+}
+
+void PeerConnectionTestWrapper::AddIceCandidate(const std::string& sdp_mid,
+ int sdp_mline_index,
+ const std::string& candidate) {
+ EXPECT_TRUE(peer_connection_->AddIceCandidate(
+ webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index,
+ candidate, NULL)));
+}
+
+void PeerConnectionTestWrapper::WaitForCallEstablished() {
+ WaitForConnection();
+ WaitForAudio();
+ WaitForVideo();
+}
+
+void PeerConnectionTestWrapper::WaitForConnection() {
+ EXPECT_TRUE_WAIT(CheckForConnection(), kMaxWait);
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": Connected.";
+}
+
+bool PeerConnectionTestWrapper::CheckForConnection() {
+ return (peer_connection_->ice_connection_state() ==
+ PeerConnectionInterface::kIceConnectionConnected);
+}
+
+void PeerConnectionTestWrapper::WaitForAudio() {
+ EXPECT_TRUE_WAIT(CheckForAudio(), kMaxWait);
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": Got enough audio frames.";
+}
+
+bool PeerConnectionTestWrapper::CheckForAudio() {
+ return (fake_audio_capture_module_->frames_received() >=
+ kTestAudioFrameCount);
+}
+
+void PeerConnectionTestWrapper::WaitForVideo() {
+ EXPECT_TRUE_WAIT(CheckForVideo(), kMaxWait);
+ LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
+ << ": Got enough video frames.";
+}
+
+bool PeerConnectionTestWrapper::CheckForVideo() {
+ if (!renderer_) {
+ return false;
+ }
+ return (renderer_->num_rendered_frames() >= kTestVideoFrameCount);
+}
+
+void PeerConnectionTestWrapper::GetAndAddUserMedia(
+ bool audio, const webrtc::FakeConstraints& audio_constraints,
+ bool video, const webrtc::FakeConstraints& video_constraints) {
+ talk_base::scoped_refptr<webrtc::MediaStreamInterface> stream =
+ GetUserMedia(audio, audio_constraints, video, video_constraints);
+ EXPECT_TRUE(peer_connection_->AddStream(stream, NULL));
+}
+
+talk_base::scoped_refptr<webrtc::MediaStreamInterface>
+ PeerConnectionTestWrapper::GetUserMedia(
+ bool audio, const webrtc::FakeConstraints& audio_constraints,
+ bool video, const webrtc::FakeConstraints& video_constraints) {
+ std::string label = kStreamLabelBase +
+ talk_base::ToString<int>(
+ static_cast<int>(peer_connection_->local_streams()->count()));
+ talk_base::scoped_refptr<webrtc::MediaStreamInterface> stream =
+ peer_connection_factory_->CreateLocalMediaStream(label);
+
+ if (audio) {
+ FakeConstraints constraints = audio_constraints;
+ // Disable highpass filter so that we can get all the test audio frames.
+ constraints.AddMandatory(
+ MediaConstraintsInterface::kHighpassFilter, false);
+ talk_base::scoped_refptr<webrtc::AudioSourceInterface> source =
+ peer_connection_factory_->CreateAudioSource(&constraints);
+ talk_base::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
+ peer_connection_factory_->CreateAudioTrack(kAudioTrackLabelBase,
+ source));
+ stream->AddTrack(audio_track);
+ }
+
+ if (video) {
+ // Set max frame rate to 10fps to reduce the risk of the tests to be flaky.
+ FakeConstraints constraints = video_constraints;
+ constraints.SetMandatoryMaxFrameRate(10);
+
+ talk_base::scoped_refptr<webrtc::VideoSourceInterface> source =
+ peer_connection_factory_->CreateVideoSource(
+ new webrtc::FakePeriodicVideoCapturer(), &constraints);
+ std::string videotrack_label = label + kVideoTrackLabelBase;
+ talk_base::scoped_refptr<webrtc::VideoTrackInterface> video_track(
+ peer_connection_factory_->CreateVideoTrack(videotrack_label, source));
+
+ stream->AddTrack(video_track);
+ }
+ return stream;
+}
diff --git a/app/webrtc/test/peerconnectiontestwrapper.h b/app/webrtc/test/peerconnectiontestwrapper.h
new file mode 100644
index 0000000..46fefaf
--- /dev/null
+++ b/app/webrtc/test/peerconnectiontestwrapper.h
@@ -0,0 +1,119 @@
+/*
+ * libjingle
+ * Copyright 2013, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_APP_WEBRTC_TEST_PEERCONNECTIONTESTWRAPPER_H_
+#define TALK_APP_WEBRTC_TEST_PEERCONNECTIONTESTWRAPPER_H_
+
+#include "talk/app/webrtc/peerconnectioninterface.h"
+#include "talk/app/webrtc/test/fakeaudiocapturemodule.h"
+#include "talk/app/webrtc/test/fakeconstraints.h"
+#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
+#include "talk/base/sigslot.h"
+#include "talk/base/thread.h"
+
+namespace webrtc {
+class PortAllocatorFactoryInterface;
+}
+
+class PeerConnectionTestWrapper
+ : public webrtc::PeerConnectionObserver,
+ public webrtc::CreateSessionDescriptionObserver,
+ public sigslot::has_slots<> {
+ public:
+ static void Connect(PeerConnectionTestWrapper* caller,
+ PeerConnectionTestWrapper* callee);
+
+ explicit PeerConnectionTestWrapper(const std::string& name);
+ virtual ~PeerConnectionTestWrapper();
+
+ bool CreatePc(const webrtc::MediaConstraintsInterface* constraints);
+
+ // Implements PeerConnectionObserver.
+ virtual void OnError() {}
+ virtual void OnSignalingChange(
+ webrtc::PeerConnectionInterface::SignalingState new_state) {}
+ virtual void OnStateChange(
+ webrtc::PeerConnectionObserver::StateType state_changed) {}
+ virtual void OnAddStream(webrtc::MediaStreamInterface* stream);
+ virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) {}
+ virtual void OnDataChannel(webrtc::DataChannelInterface* data_channel) {}
+ virtual void OnRenegotiationNeeded() {}
+ virtual void OnIceConnectionChange(
+ webrtc::PeerConnectionInterface::IceConnectionState new_state) {}
+ virtual void OnIceGatheringChange(
+ webrtc::PeerConnectionInterface::IceGatheringState new_state) {}
+ virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate);
+ virtual void OnIceComplete() {}
+
+ // Implements CreateSessionDescriptionObserver.
+ virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc);
+ virtual void OnFailure(const std::string& error) {}
+
+ void CreateOffer(const webrtc::MediaConstraintsInterface* constraints);
+ void CreateAnswer(const webrtc::MediaConstraintsInterface* constraints);
+ void ReceiveOfferSdp(const std::string& sdp);
+ void ReceiveAnswerSdp(const std::string& sdp);
+ void AddIceCandidate(const std::string& sdp_mid, int sdp_mline_index,
+ const std::string& candidate);
+ void WaitForCallEstablished();
+ void WaitForConnection();
+ void WaitForAudio();
+ void WaitForVideo();
+ void GetAndAddUserMedia(
+ bool audio, const webrtc::FakeConstraints& audio_constraints,
+ bool video, const webrtc::FakeConstraints& video_constraints);
+
+ // sigslots
+ sigslot::signal1<std::string*> SignalOnIceCandidateCreated;
+ sigslot::signal3<const std::string&,
+ int,
+ const std::string&> SignalOnIceCandidateReady;
+ sigslot::signal1<std::string*> SignalOnSdpCreated;
+ sigslot::signal1<const std::string&> SignalOnSdpReady;
+
+ private:
+ void SetLocalDescription(const std::string& type, const std::string& sdp);
+ void SetRemoteDescription(const std::string& type, const std::string& sdp);
+ bool CheckForConnection();
+ bool CheckForAudio();
+ bool CheckForVideo();
+ talk_base::scoped_refptr<webrtc::MediaStreamInterface> GetUserMedia(
+ bool audio, const webrtc::FakeConstraints& audio_constraints,
+ bool video, const webrtc::FakeConstraints& video_constraints);
+
+ std::string name_;
+ talk_base::Thread audio_thread_;
+ talk_base::scoped_refptr<webrtc::PortAllocatorFactoryInterface>
+ allocator_factory_;
+ talk_base::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
+ talk_base::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
+ peer_connection_factory_;
+ talk_base::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
+ talk_base::scoped_ptr<webrtc::FakeVideoTrackRenderer> renderer_;
+};
+
+#endif // TALK_APP_WEBRTC_TEST_PEERCONNECTIONTESTWRAPPER_H_
diff --git a/app/webrtc/webrtcsession.cc b/app/webrtc/webrtcsession.cc
index 565eee3..7e153b3 100644
--- a/app/webrtc/webrtcsession.cc
+++ b/app/webrtc/webrtcsession.cc
@@ -526,7 +526,7 @@
this, &WebRtcSession::OnIdentityReady);
if (options.disable_encryption) {
- webrtc_session_desc_factory_->set_secure(cricket::SEC_DISABLED);
+ webrtc_session_desc_factory_->SetSecure(cricket::SEC_DISABLED);
}
return true;
@@ -554,13 +554,13 @@
return true;
}
-void WebRtcSession::set_secure_policy(
+void WebRtcSession::SetSecurePolicy(
cricket::SecureMediaPolicy secure_policy) {
- webrtc_session_desc_factory_->set_secure(secure_policy);
+ webrtc_session_desc_factory_->SetSecure(secure_policy);
}
-cricket::SecureMediaPolicy WebRtcSession::secure_policy() const {
- return webrtc_session_desc_factory_->secure();
+cricket::SecureMediaPolicy WebRtcSession::SecurePolicy() const {
+ return webrtc_session_desc_factory_->Secure();
}
bool WebRtcSession::GetSslRole(talk_base::SSLRole* role) {
@@ -610,7 +610,7 @@
}
cricket::SecureMediaPolicy secure_policy =
- webrtc_session_desc_factory_->secure();
+ webrtc_session_desc_factory_->Secure();
// Update the MediaContentDescription crypto settings as per the policy set.
UpdateSessionDescriptionSecurePolicy(secure_policy, desc->description());
@@ -1483,7 +1483,7 @@
// Verify crypto settings.
std::string crypto_error;
- if (webrtc_session_desc_factory_->secure() == cricket::SEC_REQUIRED &&
+ if (webrtc_session_desc_factory_->Secure() == cricket::SEC_REQUIRED &&
!VerifyCrypto(sdesc->description(), dtls_enabled_, &crypto_error)) {
return BadSdp(source, crypto_error, error_desc);
}
diff --git a/app/webrtc/webrtcsession.h b/app/webrtc/webrtcsession.h
index da994c5..4c83906 100644
--- a/app/webrtc/webrtcsession.h
+++ b/app/webrtc/webrtcsession.h
@@ -42,20 +42,17 @@
#include "talk/session/media/mediasession.h"
namespace cricket {
-
+class BaseChannel;
class ChannelManager;
class DataChannel;
class StatsReport;
class Transport;
class VideoCapturer;
-class BaseChannel;
class VideoChannel;
class VoiceChannel;
-
} // namespace cricket
namespace webrtc {
-
class IceRestartAnswerLatch;
class MediaStreamSignaling;
class WebRtcSessionDescriptionFactory;
@@ -79,6 +76,7 @@
// ICE state callback interface.
class IceObserver {
public:
+ IceObserver() {}
// Called any time the IceConnectionState changes
virtual void OnIceConnectionChange(
PeerConnectionInterface::IceConnectionState new_state) {}
@@ -94,6 +92,9 @@
protected:
~IceObserver() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IceObserver);
};
class WebRtcSession : public cricket::BaseSession,
@@ -131,8 +132,8 @@
return data_channel_.get();
}
- void set_secure_policy(cricket::SecureMediaPolicy secure_policy);
- cricket::SecureMediaPolicy secure_policy() const;
+ void SetSecurePolicy(cricket::SecureMediaPolicy secure_policy);
+ cricket::SecureMediaPolicy SecurePolicy() const;
// Get current ssl role from transport.
bool GetSslRole(talk_base::SSLRole* role);
@@ -330,8 +331,9 @@
sigslot::signal0<> SignalVoiceChannelDestroyed;
sigslot::signal0<> SignalVideoChannelDestroyed;
sigslot::signal0<> SignalDataChannelDestroyed;
-};
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSession);
+};
} // namespace webrtc
#endif // TALK_APP_WEBRTC_WEBRTCSESSION_H_
diff --git a/app/webrtc/webrtcsession_unittest.cc b/app/webrtc/webrtcsession_unittest.cc
index 0ddc16c..5ec880a 100644
--- a/app/webrtc/webrtcsession_unittest.cc
+++ b/app/webrtc/webrtcsession_unittest.cc
@@ -86,20 +86,21 @@
using webrtc::SessionDescriptionInterface;
using webrtc::StreamCollection;
using webrtc::WebRtcSession;
+using webrtc::kBundleWithoutRtcpMux;
using webrtc::kMlineMismatch;
+using webrtc::kPushDownAnswerTDFailed;
+using webrtc::kPushDownPranswerTDFailed;
using webrtc::kSdpWithoutCrypto;
-using webrtc::kSdpWithoutSdesAndDtlsDisabled;
using webrtc::kSdpWithoutIceUfragPwd;
+using webrtc::kSdpWithoutSdesAndDtlsDisabled;
using webrtc::kSessionError;
using webrtc::kSetLocalSdpFailed;
using webrtc::kSetRemoteSdpFailed;
-using webrtc::kPushDownAnswerTDFailed;
-using webrtc::kPushDownPranswerTDFailed;
-using webrtc::kBundleWithoutRtcpMux;
-static const SocketAddress kClientAddr1("11.11.11.11", 0);
-static const SocketAddress kClientAddr2("22.22.22.22", 0);
-static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
+static const int kClientAddrPort = 0;
+static const char kClientAddrHost1[] = "11.11.11.11";
+static const char kClientAddrHost2[] = "22.22.22.22";
+static const char kStunAddrHost[] = "99.99.99.1";
static const char kSessionVersion[] = "1";
@@ -113,11 +114,6 @@
static const int kIceCandidatesTimeout = 10000;
-static const cricket::AudioCodec
- kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
-static const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
-static const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
-
static const char kFakeDtlsFingerprint[] =
"BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
"0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
@@ -159,11 +155,17 @@
// Found a new candidate.
virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
- if (candidate->sdp_mline_index() == kMediaContentIndex0) {
- mline_0_candidates_.push_back(candidate->candidate());
- } else if (candidate->sdp_mline_index() == kMediaContentIndex1) {
- mline_1_candidates_.push_back(candidate->candidate());
+ switch (candidate->sdp_mline_index()) {
+ case kMediaContentIndex0:
+ mline_0_candidates_.push_back(candidate->candidate());
+ break;
+ case kMediaContentIndex1:
+ mline_1_candidates_.push_back(candidate->candidate());
+ break;
+ default:
+ ASSERT(false);
}
+
// The ICE gathering state should always be Gathering when a candidate is
// received (or possibly Completed in the case of the final candidate).
EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
@@ -281,8 +283,10 @@
vss_(new talk_base::VirtualSocketServer(pss_.get())),
fss_(new talk_base::FirewallSocketServer(vss_.get())),
ss_scope_(fss_.get()),
- stun_server_(talk_base::Thread::Current(), kStunAddr),
- allocator_(&network_manager_, kStunAddr,
+ stun_socket_addr_(talk_base::SocketAddress(kStunAddrHost,
+ cricket::STUN_SERVER_PORT)),
+ stun_server_(talk_base::Thread::Current(), stun_socket_addr_),
+ allocator_(&network_manager_, stun_socket_addr_,
SocketAddress(), SocketAddress(), SocketAddress()),
mediastream_signaling_(channel_manager_.get()) {
tdesc_factory_->set_protocol(cricket::ICEPROTO_HYBRID);
@@ -324,6 +328,8 @@
void InitWithDtmfCodec() {
// Add kTelephoneEventCodec for dtmf test.
+ const cricket::AudioCodec kTelephoneEventCodec(
+ 106, "telephone-event", 8000, 0, 1, 0);
std::vector<cricket::AudioCodec> codecs;
codecs.push_back(kTelephoneEventCodec);
media_engine_->SetAudioCodecs(codecs);
@@ -370,12 +376,12 @@
return observer->ReleaseDescription();
}
- bool ChannelsExist() {
+ bool ChannelsExist() const {
return (session_->voice_channel() != NULL &&
session_->video_channel() != NULL);
}
- void CheckTransportChannels() {
+ void CheckTransportChannels() const {
EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
@@ -710,7 +716,7 @@
}
void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
- AddInterface(kClientAddr1);
+ AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
FakeConstraints constraints;
@@ -780,7 +786,7 @@
// New -> Checking -> Connected -> Disconnected -> Connected.
// The Gathering state should go: New -> Gathering -> Completed.
void TestLoopbackCall() {
- AddInterface(kClientAddr1);
+ AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
SessionDescriptionInterface* offer = CreateOffer(NULL);
@@ -815,7 +821,10 @@
// Adding firewall rule to block ping requests, which should cause
// transport channel failure.
- fss_->AddRule(false, talk_base::FP_ANY, talk_base::FD_ANY, kClientAddr1);
+ fss_->AddRule(false,
+ talk_base::FP_ANY,
+ talk_base::FD_ANY,
+ talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
observer_.ice_connection_state_,
kIceCandidatesTimeout);
@@ -840,7 +849,10 @@
// Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
void AddCNCodecs() {
- // Add kTelephoneEventCodec for dtmf test.
+ const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
+ const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
+
+ // Add kCNCodec for dtmf test.
std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
codecs.push_back(kCNCodec1);
codecs.push_back(kCNCodec2);
@@ -918,6 +930,7 @@
talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
talk_base::SocketServerScope ss_scope_;
+ talk_base::SocketAddress stun_socket_addr_;
cricket::TestStunServer stun_server_;
talk_base::FakeNetworkManager network_manager_;
cricket::BasicPortAllocator allocator_;
@@ -941,7 +954,7 @@
// Verifies that WebRtcSession uses SEC_REQUIRED by default.
TEST_F(WebRtcSessionTest, TestDefaultSetSecurePolicy) {
Init(NULL);
- EXPECT_EQ(cricket::SEC_REQUIRED, session_->secure_policy());
+ EXPECT_EQ(cricket::SEC_REQUIRED, session_->SecurePolicy());
}
TEST_F(WebRtcSessionTest, TestSessionCandidates) {
@@ -959,8 +972,8 @@
}
TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
- AddInterface(kClientAddr1);
- AddInterface(kClientAddr2);
+ AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+ AddInterface(talk_base::SocketAddress(kClientAddrHost2, kClientAddrPort));
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
InitiateCall();
@@ -970,13 +983,16 @@
}
TEST_F(WebRtcSessionTest, TestStunError) {
- AddInterface(kClientAddr1);
- AddInterface(kClientAddr2);
- fss_->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY, kClientAddr1);
+ AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
+ AddInterface(talk_base::SocketAddress(kClientAddrHost2, kClientAddrPort));
+ fss_->AddRule(false,
+ talk_base::FP_UDP,
+ talk_base::FD_ANY,
+ talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
InitiateCall();
- // Since kClientAddr1 is blocked, not expecting stun candidates for it.
+ // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
@@ -1420,7 +1436,7 @@
// Test that local candidates are added to the local session description and
// that they are retained if the local session description is changed.
TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
- AddInterface(kClientAddr1);
+ AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
CreateAndSetRemoteOfferAndLocalAnswer();
@@ -1484,7 +1500,7 @@
// Test that offers and answers contains ice candidates when Ice candidates have
// been gathered.
TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
- AddInterface(kClientAddr1);
+ AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
Init(NULL);
mediastream_signaling_.SendAudioVideoStream1();
// Ice is started but candidates are not provided until SetLocalDescription
diff --git a/app/webrtc/webrtcsessiondescriptionfactory.cc b/app/webrtc/webrtcsessiondescriptionfactory.cc
index 51427d2..b6f523c 100644
--- a/app/webrtc/webrtcsessiondescriptionfactory.cc
+++ b/app/webrtc/webrtcsessiondescriptionfactory.cc
@@ -33,10 +33,10 @@
#include "talk/app/webrtc/mediastreamsignaling.h"
#include "talk/app/webrtc/webrtcsession.h"
+using cricket::MediaSessionOptions;
+
namespace webrtc {
-
namespace {
-
static const char kFailedDueToIdentityFailed[] =
" failed because DTLS identity request failed";
@@ -46,25 +46,24 @@
static const uint64 kInitSessionVersion = 2;
-typedef cricket::MediaSessionOptions::Stream Stream;
-typedef cricket::MediaSessionOptions::Streams Streams;
-
-static bool CompareStream(const Stream& stream1, const Stream& stream2) {
- return (stream1.id < stream2.id);
+static bool CompareStream(const MediaSessionOptions::Stream& stream1,
+ const MediaSessionOptions::Stream& stream2) {
+ return stream1.id < stream2.id;
}
-static bool SameId(const Stream& stream1, const Stream& stream2) {
- return (stream1.id == stream2.id);
+static bool SameId(const MediaSessionOptions::Stream& stream1,
+ const MediaSessionOptions::Stream& stream2) {
+ return stream1.id == stream2.id;
}
// Checks if each Stream within the |streams| has unique id.
-static bool ValidStreams(const Streams& streams) {
- Streams sorted_streams = streams;
+static bool ValidStreams(const MediaSessionOptions::Streams& streams) {
+ MediaSessionOptions::Streams sorted_streams = streams;
std::sort(sorted_streams.begin(), sorted_streams.end(), CompareStream);
- Streams::iterator it =
+ MediaSessionOptions::Streams::iterator it =
std::adjacent_find(sorted_streams.begin(), sorted_streams.end(),
SameId);
- return (it == sorted_streams.end());
+ return it == sorted_streams.end();
}
enum {
@@ -83,7 +82,6 @@
std::string error;
talk_base::scoped_ptr<webrtc::SessionDescriptionInterface> description;
};
-
} // namespace
// static
@@ -130,33 +128,35 @@
transport_desc_factory_.set_protocol(cricket::ICEPROTO_HYBRID);
session_desc_factory_.set_add_legacy_streams(false);
// By default SRTP-SDES is enabled in WebRtc.
- set_secure(cricket::SEC_REQUIRED);
+ SetSecure(cricket::SEC_REQUIRED);
- if (dtls_enabled) {
- if (identity_service_.get()) {
- identity_request_observer_ =
- new talk_base::RefCountedObject<WebRtcIdentityRequestObserver>();
+ if (!dtls_enabled) {
+ return;
+ }
- identity_request_observer_->SignalRequestFailed.connect(
- this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed);
- identity_request_observer_->SignalIdentityReady.connect(
- this, &WebRtcSessionDescriptionFactory::OnIdentityReady);
+ if (identity_service_.get()) {
+ identity_request_observer_ =
+ new talk_base::RefCountedObject<WebRtcIdentityRequestObserver>();
- if (identity_service_->RequestIdentity(kWebRTCIdentityName,
- kWebRTCIdentityName,
- identity_request_observer_)) {
- LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request.";
- identity_request_state_ = IDENTITY_WAITING;
- } else {
- LOG(LS_ERROR) << "Failed to send DTLS identity request.";
- identity_request_state_ = IDENTITY_FAILED;
- }
- } else {
+ identity_request_observer_->SignalRequestFailed.connect(
+ this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed);
+ identity_request_observer_->SignalIdentityReady.connect(
+ this, &WebRtcSessionDescriptionFactory::OnIdentityReady);
+
+ if (identity_service_->RequestIdentity(kWebRTCIdentityName,
+ kWebRTCIdentityName,
+ identity_request_observer_)) {
+ LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request.";
identity_request_state_ = IDENTITY_WAITING;
- // Do not generate the identity in the constructor since the caller has
- // not got a chance to connect to SignalIdentityReady.
- signaling_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL);
+ } else {
+ LOG(LS_ERROR) << "Failed to send DTLS identity request.";
+ identity_request_state_ = IDENTITY_FAILED;
}
+ } else {
+ identity_request_state_ = IDENTITY_WAITING;
+ // Do not generate the identity in the constructor since the caller has
+ // not got a chance to connect to SignalIdentityReady.
+ signaling_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL);
}
}
@@ -261,19 +261,15 @@
}
}
-void WebRtcSessionDescriptionFactory::set_secure(
+void WebRtcSessionDescriptionFactory::SetSecure(
cricket::SecureMediaPolicy secure_policy) {
session_desc_factory_.set_secure(secure_policy);
}
-cricket::SecureMediaPolicy WebRtcSessionDescriptionFactory::secure() const {
+cricket::SecureMediaPolicy WebRtcSessionDescriptionFactory::Secure() const {
return session_desc_factory_.secure();
}
-bool WebRtcSessionDescriptionFactory::waiting_for_identity() const {
- return identity_request_state_ == IDENTITY_WAITING;
-}
-
void WebRtcSessionDescriptionFactory::OnMessage(talk_base::Message* msg) {
switch (msg->message_id) {
case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: {
@@ -450,5 +446,4 @@
create_session_description_requests_.pop();
}
}
-
} // namespace webrtc
diff --git a/app/webrtc/webrtcsessiondescriptionfactory.h b/app/webrtc/webrtcsessiondescriptionfactory.h
index ba34e91..ca614b4 100644
--- a/app/webrtc/webrtcsessiondescriptionfactory.h
+++ b/app/webrtc/webrtcsessiondescriptionfactory.h
@@ -34,21 +34,17 @@
#include "talk/session/media/mediasession.h"
namespace cricket {
-
class ChannelManager;
class TransportDescriptionFactory;
-
} // namespace cricket
namespace webrtc {
-
class CreateSessionDescriptionObserver;
class MediaConstraintsInterface;
class MediaStreamSignaling;
class SessionDescriptionInterface;
class WebRtcSession;
-
// DTLS identity request callback class.
class WebRtcIdentityRequestObserver : public DTLSIdentityRequestObserver,
public sigslot::has_slots<> {
@@ -116,13 +112,15 @@
CreateSessionDescriptionObserver* observer,
const MediaConstraintsInterface* constraints);
- void set_secure(cricket::SecureMediaPolicy secure_policy);
- cricket::SecureMediaPolicy secure() const;
+ void SetSecure(cricket::SecureMediaPolicy secure_policy);
+ cricket::SecureMediaPolicy Secure() const;
sigslot::signal1<talk_base::SSLIdentity*> SignalIdentityReady;
// For testing.
- bool waiting_for_identity() const;
+ bool waiting_for_identity() const {
+ return identity_request_state_ == IDENTITY_WAITING;
+ }
private:
enum IdentityRequestState {
@@ -166,7 +164,6 @@
DISALLOW_COPY_AND_ASSIGN(WebRtcSessionDescriptionFactory);
};
-
} // namespace webrtc
#endif // TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_
diff --git a/libjingle_examples.gyp b/libjingle_examples.gyp
index a22daf1..c69aa9e 100755
--- a/libjingle_examples.gyp
+++ b/libjingle_examples.gyp
@@ -261,35 +261,6 @@
'-framework UIKit',
],
},
- 'postbuilds': [
- {
- # Ideally app signing would be a part of gyp.
- # Delete if/when that comes to pass.
- 'postbuild_name': 'Sign AppRTCDemo',
- 'variables': {
- 'variables': {
- 'key_id%': '<!(security find-identity -p codesigning -v | grep "iPhone Developer" | awk \'{print $2}\')',
- },
- 'key_id%': '<(key_id)',
- # Total HACK to give a more informative message when multiple
- # codesigning keys are present in the default keychain. Ideally
- # we could pick more intelligently among the keys, but as a
- # first cut just tell the developer to specify a key identity
- # explicitly.
- 'ensure_single_key': '<!(python -c "assert \'\\n\' not in \'\'\'<(key_id)\'\'\', \'key_id gyp variable needs to be set explicitly because there are multiple codesigning keys!\'")',
- },
- 'conditions': [
- ['key_id==""', {
- 'action': [ 'echo', 'Skipping signing' ],
- }, {
- 'action': [
- '/usr/bin/codesign', '-v', '--force', '--sign', '<(key_id)',
- '${BUILT_PRODUCTS_DIR}/AppRTCDemo.app',
- ],
- }],
- ],
- },
- ],
}, # target AppRTCDemo
], # targets
}], # OS=="ios"
diff --git a/libjingle_tests.gyp b/libjingle_tests.gyp
index 44fa8f7..a88942f 100755
--- a/libjingle_tests.gyp
+++ b/libjingle_tests.gyp
@@ -383,6 +383,7 @@
# 'app/webrtc/mediastreamhandler_unittest.cc',
'app/webrtc/mediastreamsignaling_unittest.cc',
'app/webrtc/peerconnection_unittest.cc',
+ 'app/webrtc/peerconnectionendtoend_unittest.cc',
'app/webrtc/peerconnectionfactory_unittest.cc',
'app/webrtc/peerconnectioninterface_unittest.cc',
# 'app/webrtc/peerconnectionproxy_unittest.cc',
@@ -397,6 +398,8 @@
'app/webrtc/test/fakeperiodicvideocapturer.h',
'app/webrtc/test/fakevideotrackrenderer.h',
'app/webrtc/test/mockpeerconnectionobservers.h',
+ 'app/webrtc/test/peerconnectiontestwrapper.h',
+ 'app/webrtc/test/peerconnectiontestwrapper.cc',
'app/webrtc/test/testsdpstrings.h',
'app/webrtc/videosource_unittest.cc',
'app/webrtc/videotrack_unittest.cc',
diff --git a/media/base/videoadapter.h b/media/base/videoadapter.h
index 2bd31d5..38a8c9d 100644
--- a/media/base/videoadapter.h
+++ b/media/base/videoadapter.h
@@ -109,7 +109,7 @@
: public VideoAdapter, public sigslot::has_slots<> {
public:
enum AdaptRequest { UPGRADE, KEEP, DOWNGRADE };
- enum {
+ enum AdaptReasonEnum {
ADAPTREASON_CPU = 1,
ADAPTREASON_BANDWIDTH = 2,
ADAPTREASON_VIEW = 4
diff --git a/media/webrtc/fakewebrtcvoiceengine.h b/media/webrtc/fakewebrtcvoiceengine.h
index 9696518..4ecefff 100644
--- a/media/webrtc/fakewebrtcvoiceengine.h
+++ b/media/webrtc/fakewebrtcvoiceengine.h
@@ -252,6 +252,19 @@
true);
}
}
+ int AddChannel() {
+ if (fail_create_channel_) {
+ return -1;
+ }
+ Channel* ch = new Channel();
+ for (int i = 0; i < NumOfCodecs(); ++i) {
+ webrtc::CodecInst codec;
+ GetCodec(i, codec);
+ ch->recv_codecs.push_back(codec);
+ }
+ channels_[++last_channel_] = ch;
+ return last_channel_;
+ }
WEBRTC_STUB(Release, ());
@@ -275,18 +288,13 @@
return NULL;
}
WEBRTC_FUNC(CreateChannel, ()) {
- if (fail_create_channel_) {
- return -1;
- }
- Channel* ch = new Channel();
- for (int i = 0; i < NumOfCodecs(); ++i) {
- webrtc::CodecInst codec;
- GetCodec(i, codec);
- ch->recv_codecs.push_back(codec);
- }
- channels_[++last_channel_] = ch;
- return last_channel_;
+ return AddChannel();
}
+#ifdef USE_WEBRTC_DEV_BRANCH
+ WEBRTC_FUNC(CreateChannel, (const webrtc::Config& /*config*/)) {
+ return AddChannel();
+ }
+#endif
WEBRTC_FUNC(DeleteChannel, (int channel)) {
WEBRTC_CHECK_CHANNEL(channel);
delete channels_[channel];
diff --git a/p2p/base/session.cc b/p2p/base/session.cc
index e5c86c1..e0f8dd3 100644
--- a/p2p/base/session.cc
+++ b/p2p/base/session.cc
@@ -998,10 +998,11 @@
return true;
}
-bool Session::SendInfoMessage(const XmlElements& elems) {
+bool Session::SendInfoMessage(const XmlElements& elems,
+ const std::string& remote_name) {
ASSERT(signaling_thread()->IsCurrent());
SessionError error;
- if (!SendMessage(ACTION_SESSION_INFO, elems, &error)) {
+ if (!SendMessage(ACTION_SESSION_INFO, elems, remote_name, &error)) {
LOG(LS_ERROR) << "Could not send info message " << error.text;
return false;
}
@@ -1644,11 +1645,16 @@
bool Session::SendMessage(ActionType type, const XmlElements& action_elems,
SessionError* error) {
+ return SendMessage(type, action_elems, remote_name(), error);
+}
+
+bool Session::SendMessage(ActionType type, const XmlElements& action_elems,
+ const std::string& remote_name, SessionError* error) {
talk_base::scoped_ptr<buzz::XmlElement> stanza(
new buzz::XmlElement(buzz::QN_IQ));
SessionMessage msg(current_protocol_, type, id(), initiator_name());
- msg.to = remote_name();
+ msg.to = remote_name;
WriteSessionMessage(msg, action_elems, stanza.get());
SignalOutgoingMessage(this, stanza.get());
diff --git a/p2p/base/session.h b/p2p/base/session.h
index 292e7a5..637c942 100644
--- a/p2p/base/session.h
+++ b/p2p/base/session.h
@@ -584,7 +584,8 @@
// arbitrary XML messages, which are called "info" messages. Sending
// takes ownership of the given elements. The signal does not; the
// parent element will be deleted after the signal.
- bool SendInfoMessage(const XmlElements& elems);
+ bool SendInfoMessage(const XmlElements& elems,
+ const std::string& remote_name);
bool SendDescriptionInfoMessage(const ContentInfos& contents);
sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
@@ -638,7 +639,7 @@
bool ResendAllTransportInfoMessages(SessionError* error);
bool SendAllUnsentTransportInfoMessages(SessionError* error);
- // Both versions of SendMessage send a message of the given type to
+ // All versions of SendMessage send a message of the given type to
// the other client. Can pass either a set of elements or an
// "action", which must have a WriteSessionAction method to go along
// with it. Sending with an action supports sending a "hybrid"
@@ -648,6 +649,10 @@
// Takes ownership of action_elems.
bool SendMessage(ActionType type, const XmlElements& action_elems,
SessionError* error);
+ // Sends a messge, but overrides the remote name.
+ bool SendMessage(ActionType type, const XmlElements& action_elems,
+ const std::string& remote_name,
+ SessionError* error);
// When passing an action, may be Hybrid protocol.
template <typename Action>
bool SendMessage(ActionType type, const Action& action,
diff --git a/session/media/call.cc b/session/media/call.cc
index 51a721b..967846b 100644
--- a/session/media/call.cc
+++ b/session/media/call.cc
@@ -186,7 +186,7 @@
return false;
}
- return session->SendInfoMessage(elems);
+ return session->SendInfoMessage(elems, session->remote_name());
}
void Call::SetLocalRenderer(VideoRenderer* renderer) {