| 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 |