| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * libjingle | |
| 3 * Copyright 2012 Google Inc. | |
| 4 * | |
| 5 * Redistribution and use in source and binary forms, with or without | |
| 6 * modification, are permitted provided that the following conditions are met: | |
| 7 * | |
| 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. | |
| 15 * | |
| 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. | |
| 26 */ | |
| 27 | |
| 28 #include <string> | |
| 29 #include <utility> | |
| 30 | |
| 31 #include "talk/app/webrtc/mediastreaminterface.h" | |
| 32 #include "talk/app/webrtc/peerconnectionfactory.h" | |
| 33 #ifdef WEBRTC_ANDROID | |
| 34 #include "talk/app/webrtc/test/androidtestinitializer.h" | |
| 35 #endif | |
| 36 #include "talk/app/webrtc/test/fakedtlsidentitystore.h" | |
| 37 #include "talk/app/webrtc/test/fakevideotrackrenderer.h" | |
| 38 #include "talk/app/webrtc/videosourceinterface.h" | |
| 39 #include "webrtc/base/gunit.h" | |
| 40 #include "webrtc/base/scoped_ptr.h" | |
| 41 #include "webrtc/base/thread.h" | |
| 42 #include "webrtc/media/base/fakevideocapturer.h" | |
| 43 #include "webrtc/media/webrtc/webrtccommon.h" | |
| 44 #include "webrtc/media/webrtc/webrtcvoe.h" | |
| 45 #include "webrtc/p2p/client/fakeportallocator.h" | |
| 46 | |
| 47 using webrtc::DataChannelInterface; | |
| 48 using webrtc::DtlsIdentityStoreInterface; | |
| 49 using webrtc::FakeVideoTrackRenderer; | |
| 50 using webrtc::MediaStreamInterface; | |
| 51 using webrtc::PeerConnectionFactoryInterface; | |
| 52 using webrtc::PeerConnectionInterface; | |
| 53 using webrtc::PeerConnectionObserver; | |
| 54 using webrtc::VideoSourceInterface; | |
| 55 using webrtc::VideoTrackInterface; | |
| 56 | |
| 57 namespace { | |
| 58 | |
| 59 static const char kStunIceServer[] = "stun:stun.l.google.com:19302"; | |
| 60 static const char kTurnIceServer[] = "turn:test%40hello.com@test.com:1234"; | |
| 61 static const char kTurnIceServerWithTransport[] = | |
| 62 "turn:test@hello.com?transport=tcp"; | |
| 63 static const char kSecureTurnIceServer[] = | |
| 64 "turns:test@hello.com?transport=tcp"; | |
| 65 static const char kSecureTurnIceServerWithoutTransportParam[] = | |
| 66 "turns:test_no_transport@hello.com:443"; | |
| 67 static const char kSecureTurnIceServerWithoutTransportAndPortParam[] = | |
| 68 "turns:test_no_transport@hello.com"; | |
| 69 static const char kTurnIceServerWithNoUsernameInUri[] = | |
| 70 "turn:test.com:1234"; | |
| 71 static const char kTurnPassword[] = "turnpassword"; | |
| 72 static const int kDefaultStunPort = 3478; | |
| 73 static const int kDefaultStunTlsPort = 5349; | |
| 74 static const char kTurnUsername[] = "test"; | |
| 75 static const char kStunIceServerWithIPv4Address[] = "stun:1.2.3.4:1234"; | |
| 76 static const char kStunIceServerWithIPv4AddressWithoutPort[] = "stun:1.2.3.4"; | |
| 77 static const char kStunIceServerWithIPv6Address[] = "stun:[2401:fa00:4::]:1234"; | |
| 78 static const char kStunIceServerWithIPv6AddressWithoutPort[] = | |
| 79 "stun:[2401:fa00:4::]"; | |
| 80 static const char kTurnIceServerWithIPv6Address[] = | |
| 81 "turn:test@[2401:fa00:4::]:1234"; | |
| 82 | |
| 83 class NullPeerConnectionObserver : public PeerConnectionObserver { | |
| 84 public: | |
| 85 virtual void OnMessage(const std::string& msg) {} | |
| 86 virtual void OnSignalingMessage(const std::string& msg) {} | |
| 87 virtual void OnSignalingChange( | |
| 88 PeerConnectionInterface::SignalingState new_state) {} | |
| 89 virtual void OnAddStream(MediaStreamInterface* stream) {} | |
| 90 virtual void OnRemoveStream(MediaStreamInterface* stream) {} | |
| 91 virtual void OnDataChannel(DataChannelInterface* data_channel) {} | |
| 92 virtual void OnRenegotiationNeeded() {} | |
| 93 virtual void OnIceConnectionChange( | |
| 94 PeerConnectionInterface::IceConnectionState new_state) {} | |
| 95 virtual void OnIceGatheringChange( | |
| 96 PeerConnectionInterface::IceGatheringState new_state) {} | |
| 97 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {} | |
| 98 }; | |
| 99 | |
| 100 } // namespace | |
| 101 | |
| 102 class PeerConnectionFactoryTest : public testing::Test { | |
| 103 void SetUp() { | |
| 104 #ifdef WEBRTC_ANDROID | |
| 105 webrtc::InitializeAndroidObjects(); | |
| 106 #endif | |
| 107 factory_ = webrtc::CreatePeerConnectionFactory(rtc::Thread::Current(), | |
| 108 rtc::Thread::Current(), | |
| 109 NULL, | |
| 110 NULL, | |
| 111 NULL); | |
| 112 | |
| 113 ASSERT_TRUE(factory_.get() != NULL); | |
| 114 port_allocator_.reset( | |
| 115 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr)); | |
| 116 raw_port_allocator_ = port_allocator_.get(); | |
| 117 } | |
| 118 | |
| 119 protected: | |
| 120 void VerifyStunServers(cricket::ServerAddresses stun_servers) { | |
| 121 EXPECT_EQ(stun_servers, raw_port_allocator_->stun_servers()); | |
| 122 } | |
| 123 | |
| 124 void VerifyTurnServers(std::vector<cricket::RelayServerConfig> turn_servers) { | |
| 125 EXPECT_EQ(turn_servers.size(), raw_port_allocator_->turn_servers().size()); | |
| 126 for (size_t i = 0; i < turn_servers.size(); ++i) { | |
| 127 ASSERT_EQ(1u, turn_servers[i].ports.size()); | |
| 128 EXPECT_EQ(1u, raw_port_allocator_->turn_servers()[i].ports.size()); | |
| 129 EXPECT_EQ( | |
| 130 turn_servers[i].ports[0].address.ToString(), | |
| 131 raw_port_allocator_->turn_servers()[i].ports[0].address.ToString()); | |
| 132 EXPECT_EQ(turn_servers[i].ports[0].proto, | |
| 133 raw_port_allocator_->turn_servers()[i].ports[0].proto); | |
| 134 EXPECT_EQ(turn_servers[i].credentials.username, | |
| 135 raw_port_allocator_->turn_servers()[i].credentials.username); | |
| 136 EXPECT_EQ(turn_servers[i].credentials.password, | |
| 137 raw_port_allocator_->turn_servers()[i].credentials.password); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory_; | |
| 142 NullPeerConnectionObserver observer_; | |
| 143 rtc::scoped_ptr<cricket::FakePortAllocator> port_allocator_; | |
| 144 // Since the PC owns the port allocator after it's been initialized, | |
| 145 // this should only be used when known to be safe. | |
| 146 cricket::FakePortAllocator* raw_port_allocator_; | |
| 147 }; | |
| 148 | |
| 149 // Verify creation of PeerConnection using internal ADM, video factory and | |
| 150 // internal libjingle threads. | |
| 151 TEST(PeerConnectionFactoryTestInternal, CreatePCUsingInternalModules) { | |
| 152 #ifdef WEBRTC_ANDROID | |
| 153 webrtc::InitializeAndroidObjects(); | |
| 154 #endif | |
| 155 | |
| 156 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory( | |
| 157 webrtc::CreatePeerConnectionFactory()); | |
| 158 | |
| 159 NullPeerConnectionObserver observer; | |
| 160 webrtc::PeerConnectionInterface::RTCConfiguration config; | |
| 161 | |
| 162 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store( | |
| 163 new FakeDtlsIdentityStore()); | |
| 164 rtc::scoped_refptr<PeerConnectionInterface> pc(factory->CreatePeerConnection( | |
| 165 config, nullptr, nullptr, std::move(dtls_identity_store), &observer)); | |
| 166 | |
| 167 EXPECT_TRUE(pc.get() != nullptr); | |
| 168 } | |
| 169 | |
| 170 // This test verifies creation of PeerConnection with valid STUN and TURN | |
| 171 // configuration. Also verifies the URL's parsed correctly as expected. | |
| 172 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServers) { | |
| 173 PeerConnectionInterface::RTCConfiguration config; | |
| 174 webrtc::PeerConnectionInterface::IceServer ice_server; | |
| 175 ice_server.uri = kStunIceServer; | |
| 176 config.servers.push_back(ice_server); | |
| 177 ice_server.uri = kTurnIceServer; | |
| 178 ice_server.password = kTurnPassword; | |
| 179 config.servers.push_back(ice_server); | |
| 180 ice_server.uri = kTurnIceServerWithTransport; | |
| 181 ice_server.password = kTurnPassword; | |
| 182 config.servers.push_back(ice_server); | |
| 183 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
| 184 new FakeDtlsIdentityStore()); | |
| 185 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
| 186 config, nullptr, std::move(port_allocator_), | |
| 187 std::move(dtls_identity_store), &observer_)); | |
| 188 ASSERT_TRUE(pc.get() != NULL); | |
| 189 cricket::ServerAddresses stun_servers; | |
| 190 rtc::SocketAddress stun1("stun.l.google.com", 19302); | |
| 191 stun_servers.insert(stun1); | |
| 192 VerifyStunServers(stun_servers); | |
| 193 std::vector<cricket::RelayServerConfig> turn_servers; | |
| 194 cricket::RelayServerConfig turn1("test.com", 1234, "test@hello.com", | |
| 195 kTurnPassword, cricket::PROTO_UDP, false); | |
| 196 turn_servers.push_back(turn1); | |
| 197 cricket::RelayServerConfig turn2("hello.com", kDefaultStunPort, "test", | |
| 198 kTurnPassword, cricket::PROTO_TCP, false); | |
| 199 turn_servers.push_back(turn2); | |
| 200 VerifyTurnServers(turn_servers); | |
| 201 } | |
| 202 | |
| 203 // This test verifies creation of PeerConnection with valid STUN and TURN | |
| 204 // configuration. Also verifies the list of URL's parsed correctly as expected. | |
| 205 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServersUrls) { | |
| 206 PeerConnectionInterface::RTCConfiguration config; | |
| 207 webrtc::PeerConnectionInterface::IceServer ice_server; | |
| 208 ice_server.urls.push_back(kStunIceServer); | |
| 209 ice_server.urls.push_back(kTurnIceServer); | |
| 210 ice_server.urls.push_back(kTurnIceServerWithTransport); | |
| 211 ice_server.password = kTurnPassword; | |
| 212 config.servers.push_back(ice_server); | |
| 213 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
| 214 new FakeDtlsIdentityStore()); | |
| 215 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
| 216 config, nullptr, std::move(port_allocator_), | |
| 217 std::move(dtls_identity_store), &observer_)); | |
| 218 ASSERT_TRUE(pc.get() != NULL); | |
| 219 cricket::ServerAddresses stun_servers; | |
| 220 rtc::SocketAddress stun1("stun.l.google.com", 19302); | |
| 221 stun_servers.insert(stun1); | |
| 222 VerifyStunServers(stun_servers); | |
| 223 std::vector<cricket::RelayServerConfig> turn_servers; | |
| 224 cricket::RelayServerConfig turn1("test.com", 1234, "test@hello.com", | |
| 225 kTurnPassword, cricket::PROTO_UDP, false); | |
| 226 turn_servers.push_back(turn1); | |
| 227 cricket::RelayServerConfig turn2("hello.com", kDefaultStunPort, "test", | |
| 228 kTurnPassword, cricket::PROTO_TCP, false); | |
| 229 turn_servers.push_back(turn2); | |
| 230 VerifyTurnServers(turn_servers); | |
| 231 } | |
| 232 | |
| 233 TEST_F(PeerConnectionFactoryTest, CreatePCUsingNoUsernameInUri) { | |
| 234 PeerConnectionInterface::RTCConfiguration config; | |
| 235 webrtc::PeerConnectionInterface::IceServer ice_server; | |
| 236 ice_server.uri = kStunIceServer; | |
| 237 config.servers.push_back(ice_server); | |
| 238 ice_server.uri = kTurnIceServerWithNoUsernameInUri; | |
| 239 ice_server.username = kTurnUsername; | |
| 240 ice_server.password = kTurnPassword; | |
| 241 config.servers.push_back(ice_server); | |
| 242 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
| 243 new FakeDtlsIdentityStore()); | |
| 244 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
| 245 config, nullptr, std::move(port_allocator_), | |
| 246 std::move(dtls_identity_store), &observer_)); | |
| 247 ASSERT_TRUE(pc.get() != NULL); | |
| 248 std::vector<cricket::RelayServerConfig> turn_servers; | |
| 249 cricket::RelayServerConfig turn("test.com", 1234, kTurnUsername, | |
| 250 kTurnPassword, cricket::PROTO_UDP, false); | |
| 251 turn_servers.push_back(turn); | |
| 252 VerifyTurnServers(turn_servers); | |
| 253 } | |
| 254 | |
| 255 // This test verifies the PeerConnection created properly with TURN url which | |
| 256 // has transport parameter in it. | |
| 257 TEST_F(PeerConnectionFactoryTest, CreatePCUsingTurnUrlWithTransportParam) { | |
| 258 PeerConnectionInterface::RTCConfiguration config; | |
| 259 webrtc::PeerConnectionInterface::IceServer ice_server; | |
| 260 ice_server.uri = kTurnIceServerWithTransport; | |
| 261 ice_server.password = kTurnPassword; | |
| 262 config.servers.push_back(ice_server); | |
| 263 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
| 264 new FakeDtlsIdentityStore()); | |
| 265 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
| 266 config, nullptr, std::move(port_allocator_), | |
| 267 std::move(dtls_identity_store), &observer_)); | |
| 268 ASSERT_TRUE(pc.get() != NULL); | |
| 269 std::vector<cricket::RelayServerConfig> turn_servers; | |
| 270 cricket::RelayServerConfig turn("hello.com", kDefaultStunPort, "test", | |
| 271 kTurnPassword, cricket::PROTO_TCP, false); | |
| 272 turn_servers.push_back(turn); | |
| 273 VerifyTurnServers(turn_servers); | |
| 274 } | |
| 275 | |
| 276 TEST_F(PeerConnectionFactoryTest, CreatePCUsingSecureTurnUrl) { | |
| 277 PeerConnectionInterface::RTCConfiguration config; | |
| 278 webrtc::PeerConnectionInterface::IceServer ice_server; | |
| 279 ice_server.uri = kSecureTurnIceServer; | |
| 280 ice_server.password = kTurnPassword; | |
| 281 config.servers.push_back(ice_server); | |
| 282 ice_server.uri = kSecureTurnIceServerWithoutTransportParam; | |
| 283 ice_server.password = kTurnPassword; | |
| 284 config.servers.push_back(ice_server); | |
| 285 ice_server.uri = kSecureTurnIceServerWithoutTransportAndPortParam; | |
| 286 ice_server.password = kTurnPassword; | |
| 287 config.servers.push_back(ice_server); | |
| 288 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
| 289 new FakeDtlsIdentityStore()); | |
| 290 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
| 291 config, nullptr, std::move(port_allocator_), | |
| 292 std::move(dtls_identity_store), &observer_)); | |
| 293 ASSERT_TRUE(pc.get() != NULL); | |
| 294 std::vector<cricket::RelayServerConfig> turn_servers; | |
| 295 cricket::RelayServerConfig turn1("hello.com", kDefaultStunTlsPort, "test", | |
| 296 kTurnPassword, cricket::PROTO_TCP, true); | |
| 297 turn_servers.push_back(turn1); | |
| 298 // TURNS with transport param should be default to tcp. | |
| 299 cricket::RelayServerConfig turn2("hello.com", 443, "test_no_transport", | |
| 300 kTurnPassword, cricket::PROTO_TCP, true); | |
| 301 turn_servers.push_back(turn2); | |
| 302 cricket::RelayServerConfig turn3("hello.com", kDefaultStunTlsPort, | |
| 303 "test_no_transport", kTurnPassword, | |
| 304 cricket::PROTO_TCP, true); | |
| 305 turn_servers.push_back(turn3); | |
| 306 VerifyTurnServers(turn_servers); | |
| 307 } | |
| 308 | |
| 309 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIPLiteralAddress) { | |
| 310 PeerConnectionInterface::RTCConfiguration config; | |
| 311 webrtc::PeerConnectionInterface::IceServer ice_server; | |
| 312 ice_server.uri = kStunIceServerWithIPv4Address; | |
| 313 config.servers.push_back(ice_server); | |
| 314 ice_server.uri = kStunIceServerWithIPv4AddressWithoutPort; | |
| 315 config.servers.push_back(ice_server); | |
| 316 ice_server.uri = kStunIceServerWithIPv6Address; | |
| 317 config.servers.push_back(ice_server); | |
| 318 ice_server.uri = kStunIceServerWithIPv6AddressWithoutPort; | |
| 319 config.servers.push_back(ice_server); | |
| 320 ice_server.uri = kTurnIceServerWithIPv6Address; | |
| 321 ice_server.password = kTurnPassword; | |
| 322 config.servers.push_back(ice_server); | |
| 323 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
| 324 new FakeDtlsIdentityStore()); | |
| 325 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
| 326 config, nullptr, std::move(port_allocator_), | |
| 327 std::move(dtls_identity_store), &observer_)); | |
| 328 ASSERT_TRUE(pc.get() != NULL); | |
| 329 cricket::ServerAddresses stun_servers; | |
| 330 rtc::SocketAddress stun1("1.2.3.4", 1234); | |
| 331 stun_servers.insert(stun1); | |
| 332 rtc::SocketAddress stun2("1.2.3.4", 3478); | |
| 333 stun_servers.insert(stun2); // Default port | |
| 334 rtc::SocketAddress stun3("2401:fa00:4::", 1234); | |
| 335 stun_servers.insert(stun3); | |
| 336 rtc::SocketAddress stun4("2401:fa00:4::", 3478); | |
| 337 stun_servers.insert(stun4); // Default port | |
| 338 VerifyStunServers(stun_servers); | |
| 339 | |
| 340 std::vector<cricket::RelayServerConfig> turn_servers; | |
| 341 cricket::RelayServerConfig turn1("2401:fa00:4::", 1234, "test", kTurnPassword, | |
| 342 cricket::PROTO_UDP, false); | |
| 343 turn_servers.push_back(turn1); | |
| 344 VerifyTurnServers(turn_servers); | |
| 345 } | |
| 346 | |
| 347 // This test verifies the captured stream is rendered locally using a | |
| 348 // local video track. | |
| 349 TEST_F(PeerConnectionFactoryTest, LocalRendering) { | |
| 350 cricket::FakeVideoCapturer* capturer = new cricket::FakeVideoCapturer(); | |
| 351 // The source take ownership of |capturer|. | |
| 352 rtc::scoped_refptr<VideoSourceInterface> source( | |
| 353 factory_->CreateVideoSource(capturer, NULL)); | |
| 354 ASSERT_TRUE(source.get() != NULL); | |
| 355 rtc::scoped_refptr<VideoTrackInterface> track( | |
| 356 factory_->CreateVideoTrack("testlabel", source)); | |
| 357 ASSERT_TRUE(track.get() != NULL); | |
| 358 FakeVideoTrackRenderer local_renderer(track); | |
| 359 | |
| 360 EXPECT_EQ(0, local_renderer.num_rendered_frames()); | |
| 361 EXPECT_TRUE(capturer->CaptureFrame()); | |
| 362 EXPECT_EQ(1, local_renderer.num_rendered_frames()); | |
| 363 EXPECT_FALSE(local_renderer.black_frame()); | |
| 364 | |
| 365 track->set_enabled(false); | |
| 366 EXPECT_TRUE(capturer->CaptureFrame()); | |
| 367 EXPECT_EQ(2, local_renderer.num_rendered_frames()); | |
| 368 EXPECT_TRUE(local_renderer.black_frame()); | |
| 369 | |
| 370 track->set_enabled(true); | |
| 371 EXPECT_TRUE(capturer->CaptureFrame()); | |
| 372 EXPECT_EQ(3, local_renderer.num_rendered_frames()); | |
| 373 EXPECT_FALSE(local_renderer.black_frame()); | |
| 374 } | |
| OLD | NEW |