xref: /aosp_15_r20/external/webrtc/pc/peer_connection_integrationtest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker // Integration tests for PeerConnection.
12*d9f75844SAndroid Build Coastguard Worker // These tests exercise a full stack over a simulated network.
13*d9f75844SAndroid Build Coastguard Worker //
14*d9f75844SAndroid Build Coastguard Worker // NOTE: If your test takes a while (guideline: more than 5 seconds),
15*d9f75844SAndroid Build Coastguard Worker // do NOT add it here, but instead add it to the file
16*d9f75844SAndroid Build Coastguard Worker // slow_peer_connection_integrationtest.cc
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
21*d9f75844SAndroid Build Coastguard Worker #include <memory>
22*d9f75844SAndroid Build Coastguard Worker #include <string>
23*d9f75844SAndroid Build Coastguard Worker #include <tuple>
24*d9f75844SAndroid Build Coastguard Worker #include <utility>
25*d9f75844SAndroid Build Coastguard Worker #include <vector>
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker #include "absl/algorithm/container.h"
28*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
29*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
30*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/async_resolver_factory.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/candidate.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/crypto_options.h"
34*d9f75844SAndroid Build Coastguard Worker #include "api/dtmf_sender_interface.h"
35*d9f75844SAndroid Build Coastguard Worker #include "api/ice_transport_interface.h"
36*d9f75844SAndroid Build Coastguard Worker #include "api/jsep.h"
37*d9f75844SAndroid Build Coastguard Worker #include "api/media_stream_interface.h"
38*d9f75844SAndroid Build Coastguard Worker #include "api/media_types.h"
39*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
40*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h"
41*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_event_log/rtc_event.h"
42*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_event_log/rtc_event_log.h"
43*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_event_log_output.h"
44*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h"
45*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_receiver_interface.h"
46*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_sender_interface.h"
47*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_transceiver_direction.h"
48*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_transceiver_interface.h"
49*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
50*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtc_stats.h"
51*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtc_stats_report.h"
52*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtcstats_objects.h"
53*d9f75844SAndroid Build Coastguard Worker #include "api/test/mock_encoder_selector.h"
54*d9f75844SAndroid Build Coastguard Worker #include "api/transport/rtp/rtp_source.h"
55*d9f75844SAndroid Build Coastguard Worker #include "api/uma_metrics.h"
56*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
57*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_rotation.h"
58*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/fake_rtc_event_log.h"
59*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
60*d9f75844SAndroid Build Coastguard Worker #include "media/base/codec.h"
61*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_constants.h"
62*d9f75844SAndroid Build Coastguard Worker #include "media/base/stream_params.h"
63*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/mock_async_resolver.h"
64*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port.h"
65*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
66*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_interface.h"
67*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/test_stun_server.h"
68*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/test_turn_customizer.h"
69*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/test_turn_server.h"
70*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/transport_description.h"
71*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/transport_info.h"
72*d9f75844SAndroid Build Coastguard Worker #include "pc/media_session.h"
73*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection.h"
74*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_factory.h"
75*d9f75844SAndroid Build Coastguard Worker #include "pc/session_description.h"
76*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_periodic_video_source.h"
77*d9f75844SAndroid Build Coastguard Worker #include "pc/test/integration_test_helpers.h"
78*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_peer_connection_observers.h"
79*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_clock.h"
80*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_mdns_responder.h"
81*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_network.h"
82*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/firewall_socket_server.h"
83*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
84*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/helpers.h"
85*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
86*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_address.h"
87*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_certificate.h"
88*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_fingerprint.h"
89*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_identity.h"
90*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_stream_adapter.h"
91*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue_for_test.h"
92*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/test_certificate_verifier.h"
93*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
94*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
95*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/virtual_socket_server.h"
96*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/metrics.h"
97*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
98*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
99*d9f75844SAndroid Build Coastguard Worker 
100*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
101*d9f75844SAndroid Build Coastguard Worker 
102*d9f75844SAndroid Build Coastguard Worker namespace {
103*d9f75844SAndroid Build Coastguard Worker 
104*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationTest
105*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionIntegrationBaseTest,
106*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<
107*d9f75844SAndroid Build Coastguard Worker           std::tuple<SdpSemantics, std::string>> {
108*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionIntegrationTest()109*d9f75844SAndroid Build Coastguard Worker   PeerConnectionIntegrationTest()
110*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
111*d9f75844SAndroid Build Coastguard Worker                                           std::get<1>(GetParam())) {}
112*d9f75844SAndroid Build Coastguard Worker };
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker // Fake clock must be set before threads are started to prevent race on
115*d9f75844SAndroid Build Coastguard Worker // Set/GetClockForTesting().
116*d9f75844SAndroid Build Coastguard Worker // To achieve that, multiple inheritance is used as a mixin pattern
117*d9f75844SAndroid Build Coastguard Worker // where order of construction is finely controlled.
118*d9f75844SAndroid Build Coastguard Worker // This also ensures peerconnection is closed before switching back to non-fake
119*d9f75844SAndroid Build Coastguard Worker // clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
120*d9f75844SAndroid Build Coastguard Worker class FakeClockForTest : public rtc::ScopedFakeClock {
121*d9f75844SAndroid Build Coastguard Worker  protected:
FakeClockForTest()122*d9f75844SAndroid Build Coastguard Worker   FakeClockForTest() {
123*d9f75844SAndroid Build Coastguard Worker     // Some things use a time of "0" as a special value, so we need to start out
124*d9f75844SAndroid Build Coastguard Worker     // the fake clock at a nonzero time.
125*d9f75844SAndroid Build Coastguard Worker     // TODO(deadbeef): Fix this.
126*d9f75844SAndroid Build Coastguard Worker     AdvanceTime(webrtc::TimeDelta::Seconds(1));
127*d9f75844SAndroid Build Coastguard Worker   }
128*d9f75844SAndroid Build Coastguard Worker 
129*d9f75844SAndroid Build Coastguard Worker   // Explicit handle.
FakeClock()130*d9f75844SAndroid Build Coastguard Worker   ScopedFakeClock& FakeClock() { return *this; }
131*d9f75844SAndroid Build Coastguard Worker };
132*d9f75844SAndroid Build Coastguard Worker 
133*d9f75844SAndroid Build Coastguard Worker // Ensure FakeClockForTest is constructed first (see class for rationale).
134*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationTestWithFakeClock
135*d9f75844SAndroid Build Coastguard Worker     : public FakeClockForTest,
136*d9f75844SAndroid Build Coastguard Worker       public PeerConnectionIntegrationTest {};
137*d9f75844SAndroid Build Coastguard Worker 
138*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationTestPlanB
139*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionIntegrationBaseTest {
140*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionIntegrationTestPlanB()141*d9f75844SAndroid Build Coastguard Worker   PeerConnectionIntegrationTestPlanB()
142*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
143*d9f75844SAndroid Build Coastguard Worker };
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationTestUnifiedPlan
146*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionIntegrationBaseTest {
147*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionIntegrationTestUnifiedPlan()148*d9f75844SAndroid Build Coastguard Worker   PeerConnectionIntegrationTestUnifiedPlan()
149*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
150*d9f75844SAndroid Build Coastguard Worker };
151*d9f75844SAndroid Build Coastguard Worker 
152*d9f75844SAndroid Build Coastguard Worker // Test the OnFirstPacketReceived callback from audio/video RtpReceivers.  This
153*d9f75844SAndroid Build Coastguard Worker // includes testing that the callback is invoked if an observer is connected
154*d9f75844SAndroid Build Coastguard Worker // after the first packet has already been received.
TEST_P(PeerConnectionIntegrationTest,RtpReceiverObserverOnFirstPacketReceived)155*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
156*d9f75844SAndroid Build Coastguard Worker        RtpReceiverObserverOnFirstPacketReceived) {
157*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
158*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
159*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
160*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
161*d9f75844SAndroid Build Coastguard Worker   // Start offer/answer exchange and wait for it to complete.
162*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
163*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
164*d9f75844SAndroid Build Coastguard Worker   // Should be one receiver each for audio/video.
165*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
166*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
167*d9f75844SAndroid Build Coastguard Worker   // Wait for all "first packet received" callbacks to be fired.
168*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(
169*d9f75844SAndroid Build Coastguard Worker       absl::c_all_of(caller()->rtp_receiver_observers(),
170*d9f75844SAndroid Build Coastguard Worker                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
171*d9f75844SAndroid Build Coastguard Worker                        return o->first_packet_received();
172*d9f75844SAndroid Build Coastguard Worker                      }),
173*d9f75844SAndroid Build Coastguard Worker       kMaxWaitForFramesMs);
174*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(
175*d9f75844SAndroid Build Coastguard Worker       absl::c_all_of(callee()->rtp_receiver_observers(),
176*d9f75844SAndroid Build Coastguard Worker                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
177*d9f75844SAndroid Build Coastguard Worker                        return o->first_packet_received();
178*d9f75844SAndroid Build Coastguard Worker                      }),
179*d9f75844SAndroid Build Coastguard Worker       kMaxWaitForFramesMs);
180*d9f75844SAndroid Build Coastguard Worker   // If new observers are set after the first packet was already received, the
181*d9f75844SAndroid Build Coastguard Worker   // callback should still be invoked.
182*d9f75844SAndroid Build Coastguard Worker   caller()->ResetRtpReceiverObservers();
183*d9f75844SAndroid Build Coastguard Worker   callee()->ResetRtpReceiverObservers();
184*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
185*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
186*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
187*d9f75844SAndroid Build Coastguard Worker       absl::c_all_of(caller()->rtp_receiver_observers(),
188*d9f75844SAndroid Build Coastguard Worker                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
189*d9f75844SAndroid Build Coastguard Worker                        return o->first_packet_received();
190*d9f75844SAndroid Build Coastguard Worker                      }));
191*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
192*d9f75844SAndroid Build Coastguard Worker       absl::c_all_of(callee()->rtp_receiver_observers(),
193*d9f75844SAndroid Build Coastguard Worker                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
194*d9f75844SAndroid Build Coastguard Worker                        return o->first_packet_received();
195*d9f75844SAndroid Build Coastguard Worker                      }));
196*d9f75844SAndroid Build Coastguard Worker }
197*d9f75844SAndroid Build Coastguard Worker 
198*d9f75844SAndroid Build Coastguard Worker class DummyDtmfObserver : public DtmfSenderObserverInterface {
199*d9f75844SAndroid Build Coastguard Worker  public:
DummyDtmfObserver()200*d9f75844SAndroid Build Coastguard Worker   DummyDtmfObserver() : completed_(false) {}
201*d9f75844SAndroid Build Coastguard Worker 
202*d9f75844SAndroid Build Coastguard Worker   // Implements DtmfSenderObserverInterface.
OnToneChange(const std::string & tone)203*d9f75844SAndroid Build Coastguard Worker   void OnToneChange(const std::string& tone) override {
204*d9f75844SAndroid Build Coastguard Worker     tones_.push_back(tone);
205*d9f75844SAndroid Build Coastguard Worker     if (tone.empty()) {
206*d9f75844SAndroid Build Coastguard Worker       completed_ = true;
207*d9f75844SAndroid Build Coastguard Worker     }
208*d9f75844SAndroid Build Coastguard Worker   }
209*d9f75844SAndroid Build Coastguard Worker 
tones() const210*d9f75844SAndroid Build Coastguard Worker   const std::vector<std::string>& tones() const { return tones_; }
completed() const211*d9f75844SAndroid Build Coastguard Worker   bool completed() const { return completed_; }
212*d9f75844SAndroid Build Coastguard Worker 
213*d9f75844SAndroid Build Coastguard Worker  private:
214*d9f75844SAndroid Build Coastguard Worker   bool completed_;
215*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> tones_;
216*d9f75844SAndroid Build Coastguard Worker };
217*d9f75844SAndroid Build Coastguard Worker 
218*d9f75844SAndroid Build Coastguard Worker // Assumes `sender` already has an audio track added and the offer/answer
219*d9f75844SAndroid Build Coastguard Worker // exchange is done.
TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper * sender,PeerConnectionIntegrationWrapper * receiver)220*d9f75844SAndroid Build Coastguard Worker void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
221*d9f75844SAndroid Build Coastguard Worker                                   PeerConnectionIntegrationWrapper* receiver) {
222*d9f75844SAndroid Build Coastguard Worker   // We should be able to get a DTMF sender from the local sender.
223*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
224*d9f75844SAndroid Build Coastguard Worker       sender->pc()->GetSenders().at(0)->GetDtmfSender();
225*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(dtmf_sender);
226*d9f75844SAndroid Build Coastguard Worker   DummyDtmfObserver observer;
227*d9f75844SAndroid Build Coastguard Worker   dtmf_sender->RegisterObserver(&observer);
228*d9f75844SAndroid Build Coastguard Worker 
229*d9f75844SAndroid Build Coastguard Worker   // Test the DtmfSender object just created.
230*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
231*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
232*d9f75844SAndroid Build Coastguard Worker 
233*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
234*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> tones = {"1", "a", ""};
235*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(tones, observer.tones());
236*d9f75844SAndroid Build Coastguard Worker   dtmf_sender->UnregisterObserver();
237*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Verify the tones were actually received end-to-end.
238*d9f75844SAndroid Build Coastguard Worker }
239*d9f75844SAndroid Build Coastguard Worker 
240*d9f75844SAndroid Build Coastguard Worker // Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
241*d9f75844SAndroid Build Coastguard Worker // direction).
TEST_P(PeerConnectionIntegrationTest,DtmfSenderObserver)242*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
243*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
244*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
245*d9f75844SAndroid Build Coastguard Worker   // Only need audio for DTMF.
246*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
247*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
248*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
249*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
250*d9f75844SAndroid Build Coastguard Worker   // DTLS must finish before the DTMF sender can be used reliably.
251*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
252*d9f75844SAndroid Build Coastguard Worker   TestDtmfFromSenderToReceiver(caller(), callee());
253*d9f75844SAndroid Build Coastguard Worker   TestDtmfFromSenderToReceiver(callee(), caller());
254*d9f75844SAndroid Build Coastguard Worker }
255*d9f75844SAndroid Build Coastguard Worker 
256*d9f75844SAndroid Build Coastguard Worker // Basic end-to-end test, verifying media can be encoded/transmitted/decoded
257*d9f75844SAndroid Build Coastguard Worker // between two connections, using DTLS-SRTP.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithDtls)258*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
259*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
260*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
261*d9f75844SAndroid Build Coastguard Worker 
262*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
263*d9f75844SAndroid Build Coastguard Worker   // direction.
264*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
265*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
266*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
267*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
268*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
269*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
270*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
271*d9f75844SAndroid Build Coastguard Worker }
272*d9f75844SAndroid Build Coastguard Worker 
273*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_FUCHSIA)
274*d9f75844SAndroid Build Coastguard Worker // Uses SDES instead of DTLS for key agreement.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithSdes)275*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
276*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration sdes_config;
277*d9f75844SAndroid Build Coastguard Worker   sdes_config.enable_dtls_srtp.emplace(false);
278*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
279*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
280*d9f75844SAndroid Build Coastguard Worker 
281*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
282*d9f75844SAndroid Build Coastguard Worker   // direction.
283*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
284*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
285*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
286*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
287*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
288*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
289*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
290*d9f75844SAndroid Build Coastguard Worker }
291*d9f75844SAndroid Build Coastguard Worker #endif
292*d9f75844SAndroid Build Coastguard Worker 
293*d9f75844SAndroid Build Coastguard Worker // Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
294*d9f75844SAndroid Build Coastguard Worker // option to offer encrypted versions of all header extensions alongside the
295*d9f75844SAndroid Build Coastguard Worker // unencrypted versions.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithEncryptedRtpHeaderExtensions)296*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
297*d9f75844SAndroid Build Coastguard Worker        EndToEndCallWithEncryptedRtpHeaderExtensions) {
298*d9f75844SAndroid Build Coastguard Worker   CryptoOptions crypto_options;
299*d9f75844SAndroid Build Coastguard Worker   crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
300*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
301*d9f75844SAndroid Build Coastguard Worker   config.crypto_options = crypto_options;
302*d9f75844SAndroid Build Coastguard Worker   // Note: This allows offering >14 RTP header extensions.
303*d9f75844SAndroid Build Coastguard Worker   config.offer_extmap_allow_mixed = true;
304*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
305*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
306*d9f75844SAndroid Build Coastguard Worker 
307*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
308*d9f75844SAndroid Build Coastguard Worker   // direction.
309*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
310*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
311*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
312*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
313*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
314*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
315*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
316*d9f75844SAndroid Build Coastguard Worker }
317*d9f75844SAndroid Build Coastguard Worker 
318*d9f75844SAndroid Build Coastguard Worker // This test sets up a call between two parties with a source resolution of
319*d9f75844SAndroid Build Coastguard Worker // 1280x720 and verifies that a 16:9 aspect ratio is received.
TEST_P(PeerConnectionIntegrationTest,Send1280By720ResolutionAndReceive16To9AspectRatio)320*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
321*d9f75844SAndroid Build Coastguard Worker        Send1280By720ResolutionAndReceive16To9AspectRatio) {
322*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
323*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
324*d9f75844SAndroid Build Coastguard Worker 
325*d9f75844SAndroid Build Coastguard Worker   // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
326*d9f75844SAndroid Build Coastguard Worker   webrtc::FakePeriodicVideoSource::Config config;
327*d9f75844SAndroid Build Coastguard Worker   config.width = 1280;
328*d9f75844SAndroid Build Coastguard Worker   config.height = 720;
329*d9f75844SAndroid Build Coastguard Worker   config.timestamp_offset_ms = rtc::TimeMillis();
330*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
331*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
332*d9f75844SAndroid Build Coastguard Worker 
333*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for at least one frame to be received in
334*d9f75844SAndroid Build Coastguard Worker   // each direction.
335*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
336*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
337*d9f75844SAndroid Build Coastguard Worker                        callee()->min_video_frames_received_per_track() > 0,
338*d9f75844SAndroid Build Coastguard Worker                    kMaxWaitForFramesMs);
339*d9f75844SAndroid Build Coastguard Worker 
340*d9f75844SAndroid Build Coastguard Worker   // Check rendered aspect ratio.
341*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
342*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
343*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
344*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
345*d9f75844SAndroid Build Coastguard Worker }
346*d9f75844SAndroid Build Coastguard Worker 
347*d9f75844SAndroid Build Coastguard Worker // This test sets up an one-way call, with media only from caller to
348*d9f75844SAndroid Build Coastguard Worker // callee.
TEST_P(PeerConnectionIntegrationTest,OneWayMediaCall)349*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
350*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
351*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
352*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
353*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
354*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
355*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
356*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsNoAudio();
357*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsNoVideo();
358*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
359*d9f75844SAndroid Build Coastguard Worker }
360*d9f75844SAndroid Build Coastguard Worker 
361*d9f75844SAndroid Build Coastguard Worker // Tests that send only works without the caller having a decoder factory and
362*d9f75844SAndroid Build Coastguard Worker // the callee having an encoder factory.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithSendOnlyVideo)363*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
364*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
365*d9f75844SAndroid Build Coastguard Worker       CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
366*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
367*d9f75844SAndroid Build Coastguard Worker   // Add one-directional video, from caller to callee.
368*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
369*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
370*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(caller_track);
371*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
372*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_video = 0;
373*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
374*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
375*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
376*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
377*d9f75844SAndroid Build Coastguard Worker 
378*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in one direction.
379*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
380*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsNoVideo();
381*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeVideo();
382*d9f75844SAndroid Build Coastguard Worker 
383*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
384*d9f75844SAndroid Build Coastguard Worker }
385*d9f75844SAndroid Build Coastguard Worker 
386*d9f75844SAndroid Build Coastguard Worker // Tests that receive only works without the caller having an encoder factory
387*d9f75844SAndroid Build Coastguard Worker // and the callee having a decoder factory.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithReceiveOnlyVideo)388*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
389*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
390*d9f75844SAndroid Build Coastguard Worker       CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
391*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
392*d9f75844SAndroid Build Coastguard Worker   // Add one-directional video, from callee to caller.
393*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
394*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrack();
395*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee_track);
396*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
397*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_video = 1;
398*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
399*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
400*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
401*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
402*d9f75844SAndroid Build Coastguard Worker 
403*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in one direction.
404*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
405*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsSomeVideo();
406*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsNoVideo();
407*d9f75844SAndroid Build Coastguard Worker 
408*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
409*d9f75844SAndroid Build Coastguard Worker }
410*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,EndToEndCallAddReceiveVideoToSendOnlyCall)411*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
412*d9f75844SAndroid Build Coastguard Worker        EndToEndCallAddReceiveVideoToSendOnlyCall) {
413*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
414*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
415*d9f75844SAndroid Build Coastguard Worker   // Add one-directional video, from caller to callee.
416*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
417*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
418*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(caller_track);
419*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
420*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
421*d9f75844SAndroid Build Coastguard Worker 
422*d9f75844SAndroid Build Coastguard Worker   // Add receive video.
423*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
424*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrack();
425*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee_track);
426*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
427*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
428*d9f75844SAndroid Build Coastguard Worker 
429*d9f75844SAndroid Build Coastguard Worker   // Ensure that video frames are received end-to-end.
430*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
431*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
432*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
433*d9f75844SAndroid Build Coastguard Worker }
434*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,EndToEndCallAddSendVideoToReceiveOnlyCall)435*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
436*d9f75844SAndroid Build Coastguard Worker        EndToEndCallAddSendVideoToReceiveOnlyCall) {
437*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
438*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
439*d9f75844SAndroid Build Coastguard Worker   // Add one-directional video, from callee to caller.
440*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
441*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrack();
442*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee_track);
443*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
444*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
445*d9f75844SAndroid Build Coastguard Worker 
446*d9f75844SAndroid Build Coastguard Worker   // Add send video.
447*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
448*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
449*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(caller_track);
450*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
451*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
452*d9f75844SAndroid Build Coastguard Worker 
453*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in one direction.
454*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
455*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
456*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
457*d9f75844SAndroid Build Coastguard Worker }
458*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,EndToEndCallRemoveReceiveVideoFromSendReceiveCall)459*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
460*d9f75844SAndroid Build Coastguard Worker        EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
461*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
462*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
463*d9f75844SAndroid Build Coastguard Worker   // Add send video, from caller to callee.
464*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
465*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
466*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
467*d9f75844SAndroid Build Coastguard Worker       caller()->AddTrack(caller_track);
468*d9f75844SAndroid Build Coastguard Worker   // Add receive video, from callee to caller.
469*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
470*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrack();
471*d9f75844SAndroid Build Coastguard Worker 
472*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
473*d9f75844SAndroid Build Coastguard Worker       callee()->AddTrack(callee_track);
474*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
475*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
476*d9f75844SAndroid Build Coastguard Worker 
477*d9f75844SAndroid Build Coastguard Worker   // Remove receive video (i.e., callee sender track).
478*d9f75844SAndroid Build Coastguard Worker   callee()->pc()->RemoveTrackOrError(callee_sender);
479*d9f75844SAndroid Build Coastguard Worker 
480*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
481*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
482*d9f75844SAndroid Build Coastguard Worker 
483*d9f75844SAndroid Build Coastguard Worker   // Expect one-directional video.
484*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
485*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsNoVideo();
486*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeVideo();
487*d9f75844SAndroid Build Coastguard Worker 
488*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
489*d9f75844SAndroid Build Coastguard Worker }
490*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,EndToEndCallRemoveSendVideoFromSendReceiveCall)491*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
492*d9f75844SAndroid Build Coastguard Worker        EndToEndCallRemoveSendVideoFromSendReceiveCall) {
493*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
494*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
495*d9f75844SAndroid Build Coastguard Worker   // Add send video, from caller to callee.
496*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
497*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
498*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
499*d9f75844SAndroid Build Coastguard Worker       caller()->AddTrack(caller_track);
500*d9f75844SAndroid Build Coastguard Worker   // Add receive video, from callee to caller.
501*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
502*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrack();
503*d9f75844SAndroid Build Coastguard Worker 
504*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
505*d9f75844SAndroid Build Coastguard Worker       callee()->AddTrack(callee_track);
506*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
507*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
508*d9f75844SAndroid Build Coastguard Worker 
509*d9f75844SAndroid Build Coastguard Worker   // Remove send video (i.e., caller sender track).
510*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->RemoveTrackOrError(caller_sender);
511*d9f75844SAndroid Build Coastguard Worker 
512*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
513*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
514*d9f75844SAndroid Build Coastguard Worker 
515*d9f75844SAndroid Build Coastguard Worker   // Expect one-directional video.
516*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
517*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsNoVideo();
518*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsSomeVideo();
519*d9f75844SAndroid Build Coastguard Worker 
520*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
521*d9f75844SAndroid Build Coastguard Worker }
522*d9f75844SAndroid Build Coastguard Worker 
523*d9f75844SAndroid Build Coastguard Worker // This test sets up a audio call initially, with the callee rejecting video
524*d9f75844SAndroid Build Coastguard Worker // initially. Then later the callee decides to upgrade to audio/video, and
525*d9f75844SAndroid Build Coastguard Worker // initiates a new offer/answer exchange.
TEST_P(PeerConnectionIntegrationTest,AudioToVideoUpgrade)526*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
527*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
528*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
529*d9f75844SAndroid Build Coastguard Worker   // Initially, offer an audio/video stream from the caller, but refuse to
530*d9f75844SAndroid Build Coastguard Worker   // send/receive video on the callee side.
531*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
532*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
533*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
534*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
535*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_video = 0;
536*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
537*d9f75844SAndroid Build Coastguard Worker   } else {
538*d9f75844SAndroid Build Coastguard Worker     callee()->SetRemoteOfferHandler([this] {
539*d9f75844SAndroid Build Coastguard Worker       callee()
540*d9f75844SAndroid Build Coastguard Worker           ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
541*d9f75844SAndroid Build Coastguard Worker           ->StopInternal();
542*d9f75844SAndroid Build Coastguard Worker     });
543*d9f75844SAndroid Build Coastguard Worker   }
544*d9f75844SAndroid Build Coastguard Worker   // Do offer/answer and make sure audio is still received end-to-end.
545*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
546*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
547*d9f75844SAndroid Build Coastguard Worker   {
548*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
549*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectBidirectionalAudio();
550*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectNoVideo();
551*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
552*d9f75844SAndroid Build Coastguard Worker   }
553*d9f75844SAndroid Build Coastguard Worker   // Sanity check that the callee's description has a rejected video section.
554*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee()->pc()->local_description());
555*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* callee_video_content =
556*d9f75844SAndroid Build Coastguard Worker       GetFirstVideoContent(callee()->pc()->local_description()->description());
557*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee_video_content);
558*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_video_content->rejected);
559*d9f75844SAndroid Build Coastguard Worker 
560*d9f75844SAndroid Build Coastguard Worker   // Now negotiate with video and ensure negotiation succeeds, with video
561*d9f75844SAndroid Build Coastguard Worker   // frames and additional audio frames being received.
562*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
563*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
564*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
565*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_video = 1;
566*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
567*d9f75844SAndroid Build Coastguard Worker   } else {
568*d9f75844SAndroid Build Coastguard Worker     callee()->SetRemoteOfferHandler(nullptr);
569*d9f75844SAndroid Build Coastguard Worker     caller()->SetRemoteOfferHandler([this] {
570*d9f75844SAndroid Build Coastguard Worker       // The caller creates a new transceiver to receive video on when receiving
571*d9f75844SAndroid Build Coastguard Worker       // the offer, but by default it is send only.
572*d9f75844SAndroid Build Coastguard Worker       auto transceivers = caller()->pc()->GetTransceivers();
573*d9f75844SAndroid Build Coastguard Worker       ASSERT_EQ(2U, transceivers.size());
574*d9f75844SAndroid Build Coastguard Worker       ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
575*d9f75844SAndroid Build Coastguard Worker                 transceivers[1]->receiver()->media_type());
576*d9f75844SAndroid Build Coastguard Worker       transceivers[1]->sender()->SetTrack(
577*d9f75844SAndroid Build Coastguard Worker           caller()->CreateLocalVideoTrack().get());
578*d9f75844SAndroid Build Coastguard Worker       transceivers[1]->SetDirectionWithError(
579*d9f75844SAndroid Build Coastguard Worker           RtpTransceiverDirection::kSendRecv);
580*d9f75844SAndroid Build Coastguard Worker     });
581*d9f75844SAndroid Build Coastguard Worker   }
582*d9f75844SAndroid Build Coastguard Worker   callee()->CreateAndSetAndSignalOffer();
583*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
584*d9f75844SAndroid Build Coastguard Worker   {
585*d9f75844SAndroid Build Coastguard Worker     // Expect additional audio frames to be received after the upgrade.
586*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
587*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectBidirectionalAudioAndVideo();
588*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
589*d9f75844SAndroid Build Coastguard Worker   }
590*d9f75844SAndroid Build Coastguard Worker }
591*d9f75844SAndroid Build Coastguard Worker 
592*d9f75844SAndroid Build Coastguard Worker // Simpler than the above test; just add an audio track to an established
593*d9f75844SAndroid Build Coastguard Worker // video-only connection.
TEST_P(PeerConnectionIntegrationTest,AddAudioToVideoOnlyCall)594*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
595*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
596*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
597*d9f75844SAndroid Build Coastguard Worker   // Do initial offer/answer with just a video track.
598*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
599*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
600*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
601*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
602*d9f75844SAndroid Build Coastguard Worker   // Now add an audio track and do another offer/answer.
603*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
604*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
605*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
606*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
607*d9f75844SAndroid Build Coastguard Worker   // Ensure both audio and video frames are received end-to-end.
608*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
609*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
610*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
611*d9f75844SAndroid Build Coastguard Worker }
612*d9f75844SAndroid Build Coastguard Worker 
613*d9f75844SAndroid Build Coastguard Worker // This test sets up a non-bundled call and negotiates bundling at the same
614*d9f75844SAndroid Build Coastguard Worker // time as starting an ICE restart. When bundling is in effect in the restart,
615*d9f75844SAndroid Build Coastguard Worker // the DTLS-SRTP context should be successfully reset.
TEST_P(PeerConnectionIntegrationTest,BundlingEnabledWhileIceRestartOccurs)616*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
617*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
618*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
619*d9f75844SAndroid Build Coastguard Worker 
620*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
621*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
622*d9f75844SAndroid Build Coastguard Worker   // Remove the bundle group from the SDP received by the callee.
623*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
624*d9f75844SAndroid Build Coastguard Worker     desc->RemoveGroupByName("BUNDLE");
625*d9f75844SAndroid Build Coastguard Worker   });
626*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
627*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
628*d9f75844SAndroid Build Coastguard Worker   {
629*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
630*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectBidirectionalAudioAndVideo();
631*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
632*d9f75844SAndroid Build Coastguard Worker   }
633*d9f75844SAndroid Build Coastguard Worker   // Now stop removing the BUNDLE group, and trigger an ICE restart.
634*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(nullptr);
635*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
636*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
637*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
638*d9f75844SAndroid Build Coastguard Worker 
639*d9f75844SAndroid Build Coastguard Worker   // Expect additional frames to be received after the ICE restart.
640*d9f75844SAndroid Build Coastguard Worker   {
641*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
642*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectBidirectionalAudioAndVideo();
643*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
644*d9f75844SAndroid Build Coastguard Worker   }
645*d9f75844SAndroid Build Coastguard Worker }
646*d9f75844SAndroid Build Coastguard Worker 
647*d9f75844SAndroid Build Coastguard Worker // Test CVO (Coordination of Video Orientation). If a video source is rotated
648*d9f75844SAndroid Build Coastguard Worker // and both peers support the CVO RTP header extension, the actual video frames
649*d9f75844SAndroid Build Coastguard Worker // don't need to be encoded in different resolutions, since the rotation is
650*d9f75844SAndroid Build Coastguard Worker // communicated through the RTP header extension.
TEST_P(PeerConnectionIntegrationTest,RotatedVideoWithCVOExtension)651*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
652*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
653*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
654*d9f75844SAndroid Build Coastguard Worker   // Add rotated video tracks.
655*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(
656*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
657*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(
658*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
659*d9f75844SAndroid Build Coastguard Worker 
660*d9f75844SAndroid Build Coastguard Worker   // Wait for video frames to be received by both sides.
661*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
662*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
663*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
664*d9f75844SAndroid Build Coastguard Worker                        callee()->min_video_frames_received_per_track() > 0,
665*d9f75844SAndroid Build Coastguard Worker                    kMaxWaitForFramesMs);
666*d9f75844SAndroid Build Coastguard Worker 
667*d9f75844SAndroid Build Coastguard Worker   // Ensure that the aspect ratio is unmodified.
668*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
669*d9f75844SAndroid Build Coastguard Worker   // not just assumed.
670*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
671*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
672*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
673*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
674*d9f75844SAndroid Build Coastguard Worker   // Ensure that the CVO bits were surfaced to the renderer.
675*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
676*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
677*d9f75844SAndroid Build Coastguard Worker }
678*d9f75844SAndroid Build Coastguard Worker 
679*d9f75844SAndroid Build Coastguard Worker // Test that when the CVO extension isn't supported, video is rotated the
680*d9f75844SAndroid Build Coastguard Worker // old-fashioned way, by encoding rotated frames.
TEST_P(PeerConnectionIntegrationTest,RotatedVideoWithoutCVOExtension)681*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
682*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
683*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
684*d9f75844SAndroid Build Coastguard Worker   // Add rotated video tracks.
685*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(
686*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
687*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(
688*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
689*d9f75844SAndroid Build Coastguard Worker 
690*d9f75844SAndroid Build Coastguard Worker   // Remove the CVO extension from the offered SDP.
691*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
692*d9f75844SAndroid Build Coastguard Worker     cricket::VideoContentDescription* video =
693*d9f75844SAndroid Build Coastguard Worker         GetFirstVideoContentDescription(desc);
694*d9f75844SAndroid Build Coastguard Worker     video->ClearRtpHeaderExtensions();
695*d9f75844SAndroid Build Coastguard Worker   });
696*d9f75844SAndroid Build Coastguard Worker   // Wait for video frames to be received by both sides.
697*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
698*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
699*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
700*d9f75844SAndroid Build Coastguard Worker                        callee()->min_video_frames_received_per_track() > 0,
701*d9f75844SAndroid Build Coastguard Worker                    kMaxWaitForFramesMs);
702*d9f75844SAndroid Build Coastguard Worker 
703*d9f75844SAndroid Build Coastguard Worker   // Expect that the aspect ratio is inversed to account for the 90/270 degree
704*d9f75844SAndroid Build Coastguard Worker   // rotation.
705*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
706*d9f75844SAndroid Build Coastguard Worker   // not just assumed.
707*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
708*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
709*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
710*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
711*d9f75844SAndroid Build Coastguard Worker   // Expect that each endpoint is unaware of the rotation of the other endpoint.
712*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
713*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
714*d9f75844SAndroid Build Coastguard Worker }
715*d9f75844SAndroid Build Coastguard Worker 
716*d9f75844SAndroid Build Coastguard Worker // Test that if the answerer rejects the audio m= section, no audio is sent or
717*d9f75844SAndroid Build Coastguard Worker // received, but video still can be.
TEST_P(PeerConnectionIntegrationTest,AnswererRejectsAudioSection)718*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
719*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
720*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
721*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
722*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
723*d9f75844SAndroid Build Coastguard Worker     // Only add video track for callee, and set offer_to_receive_audio to 0, so
724*d9f75844SAndroid Build Coastguard Worker     // it will reject the audio m= section completely.
725*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
726*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_audio = 0;
727*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
728*d9f75844SAndroid Build Coastguard Worker   } else {
729*d9f75844SAndroid Build Coastguard Worker     // Stopping the audio RtpTransceiver will cause the media section to be
730*d9f75844SAndroid Build Coastguard Worker     // rejected in the answer.
731*d9f75844SAndroid Build Coastguard Worker     callee()->SetRemoteOfferHandler([this] {
732*d9f75844SAndroid Build Coastguard Worker       callee()
733*d9f75844SAndroid Build Coastguard Worker           ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
734*d9f75844SAndroid Build Coastguard Worker           ->StopInternal();
735*d9f75844SAndroid Build Coastguard Worker     });
736*d9f75844SAndroid Build Coastguard Worker   }
737*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee()->CreateLocalVideoTrack());
738*d9f75844SAndroid Build Coastguard Worker   // Do offer/answer and wait for successful end-to-end video frames.
739*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
740*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
741*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
742*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
743*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectNoAudio();
744*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
745*d9f75844SAndroid Build Coastguard Worker 
746*d9f75844SAndroid Build Coastguard Worker   // Sanity check that the callee's description has a rejected audio section.
747*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee()->pc()->local_description());
748*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* callee_audio_content =
749*d9f75844SAndroid Build Coastguard Worker       GetFirstAudioContent(callee()->pc()->local_description()->description());
750*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee_audio_content);
751*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_audio_content->rejected);
752*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
753*d9f75844SAndroid Build Coastguard Worker     // The caller's transceiver should have stopped after receiving the answer,
754*d9f75844SAndroid Build Coastguard Worker     // and thus no longer listed in transceivers.
755*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr,
756*d9f75844SAndroid Build Coastguard Worker               caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
757*d9f75844SAndroid Build Coastguard Worker   }
758*d9f75844SAndroid Build Coastguard Worker }
759*d9f75844SAndroid Build Coastguard Worker 
760*d9f75844SAndroid Build Coastguard Worker // Test that if the answerer rejects the video m= section, no video is sent or
761*d9f75844SAndroid Build Coastguard Worker // received, but audio still can be.
TEST_P(PeerConnectionIntegrationTest,AnswererRejectsVideoSection)762*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
763*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
764*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
765*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
766*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
767*d9f75844SAndroid Build Coastguard Worker     // Only add audio track for callee, and set offer_to_receive_video to 0, so
768*d9f75844SAndroid Build Coastguard Worker     // it will reject the video m= section completely.
769*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
770*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_video = 0;
771*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
772*d9f75844SAndroid Build Coastguard Worker   } else {
773*d9f75844SAndroid Build Coastguard Worker     // Stopping the video RtpTransceiver will cause the media section to be
774*d9f75844SAndroid Build Coastguard Worker     // rejected in the answer.
775*d9f75844SAndroid Build Coastguard Worker     callee()->SetRemoteOfferHandler([this] {
776*d9f75844SAndroid Build Coastguard Worker       callee()
777*d9f75844SAndroid Build Coastguard Worker           ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
778*d9f75844SAndroid Build Coastguard Worker           ->StopInternal();
779*d9f75844SAndroid Build Coastguard Worker     });
780*d9f75844SAndroid Build Coastguard Worker   }
781*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee()->CreateLocalAudioTrack());
782*d9f75844SAndroid Build Coastguard Worker   // Do offer/answer and wait for successful end-to-end audio frames.
783*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
784*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
785*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
786*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudio();
787*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectNoVideo();
788*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
789*d9f75844SAndroid Build Coastguard Worker 
790*d9f75844SAndroid Build Coastguard Worker   // Sanity check that the callee's description has a rejected video section.
791*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee()->pc()->local_description());
792*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* callee_video_content =
793*d9f75844SAndroid Build Coastguard Worker       GetFirstVideoContent(callee()->pc()->local_description()->description());
794*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee_video_content);
795*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_video_content->rejected);
796*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
797*d9f75844SAndroid Build Coastguard Worker     // The caller's transceiver should have stopped after receiving the answer,
798*d9f75844SAndroid Build Coastguard Worker     // and thus is no longer present.
799*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr,
800*d9f75844SAndroid Build Coastguard Worker               caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
801*d9f75844SAndroid Build Coastguard Worker   }
802*d9f75844SAndroid Build Coastguard Worker }
803*d9f75844SAndroid Build Coastguard Worker 
804*d9f75844SAndroid Build Coastguard Worker // Test that if the answerer rejects both audio and video m= sections, nothing
805*d9f75844SAndroid Build Coastguard Worker // bad happens.
806*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Test that a data channel still works. Currently this doesn't
807*d9f75844SAndroid Build Coastguard Worker // test anything but the fact that negotiation succeeds, which doesn't mean
808*d9f75844SAndroid Build Coastguard Worker // much.
TEST_P(PeerConnectionIntegrationTest,AnswererRejectsAudioAndVideoSections)809*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
810*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
811*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
812*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
813*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
814*d9f75844SAndroid Build Coastguard Worker     // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
815*d9f75844SAndroid Build Coastguard Worker     // will reject both audio and video m= sections.
816*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
817*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_audio = 0;
818*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_video = 0;
819*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
820*d9f75844SAndroid Build Coastguard Worker   } else {
821*d9f75844SAndroid Build Coastguard Worker     callee()->SetRemoteOfferHandler([this] {
822*d9f75844SAndroid Build Coastguard Worker       // Stopping all transceivers will cause all media sections to be rejected.
823*d9f75844SAndroid Build Coastguard Worker       for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
824*d9f75844SAndroid Build Coastguard Worker         transceiver->StopInternal();
825*d9f75844SAndroid Build Coastguard Worker       }
826*d9f75844SAndroid Build Coastguard Worker     });
827*d9f75844SAndroid Build Coastguard Worker   }
828*d9f75844SAndroid Build Coastguard Worker   // Do offer/answer and wait for stable signaling state.
829*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
830*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
831*d9f75844SAndroid Build Coastguard Worker 
832*d9f75844SAndroid Build Coastguard Worker   // Sanity check that the callee's description has rejected m= sections.
833*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee()->pc()->local_description());
834*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* callee_audio_content =
835*d9f75844SAndroid Build Coastguard Worker       GetFirstAudioContent(callee()->pc()->local_description()->description());
836*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee_audio_content);
837*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_audio_content->rejected);
838*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* callee_video_content =
839*d9f75844SAndroid Build Coastguard Worker       GetFirstVideoContent(callee()->pc()->local_description()->description());
840*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee_video_content);
841*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_video_content->rejected);
842*d9f75844SAndroid Build Coastguard Worker }
843*d9f75844SAndroid Build Coastguard Worker 
844*d9f75844SAndroid Build Coastguard Worker // This test sets up an audio and video call between two parties. After the
845*d9f75844SAndroid Build Coastguard Worker // call runs for a while, the caller sends an updated offer with video being
846*d9f75844SAndroid Build Coastguard Worker // rejected. Once the re-negotiation is done, the video flow should stop and
847*d9f75844SAndroid Build Coastguard Worker // the audio flow should continue.
TEST_P(PeerConnectionIntegrationTest,VideoRejectedInSubsequentOffer)848*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
849*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
850*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
851*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
852*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
853*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
854*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
855*d9f75844SAndroid Build Coastguard Worker   {
856*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
857*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectBidirectionalAudioAndVideo();
858*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
859*d9f75844SAndroid Build Coastguard Worker   }
860*d9f75844SAndroid Build Coastguard Worker   // Renegotiate, rejecting the video m= section.
861*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
862*d9f75844SAndroid Build Coastguard Worker     caller()->SetGeneratedSdpMunger(
863*d9f75844SAndroid Build Coastguard Worker         [](cricket::SessionDescription* description) {
864*d9f75844SAndroid Build Coastguard Worker           for (cricket::ContentInfo& content : description->contents()) {
865*d9f75844SAndroid Build Coastguard Worker             if (cricket::IsVideoContent(&content)) {
866*d9f75844SAndroid Build Coastguard Worker               content.rejected = true;
867*d9f75844SAndroid Build Coastguard Worker             }
868*d9f75844SAndroid Build Coastguard Worker           }
869*d9f75844SAndroid Build Coastguard Worker         });
870*d9f75844SAndroid Build Coastguard Worker   } else {
871*d9f75844SAndroid Build Coastguard Worker     caller()
872*d9f75844SAndroid Build Coastguard Worker         ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
873*d9f75844SAndroid Build Coastguard Worker         ->StopInternal();
874*d9f75844SAndroid Build Coastguard Worker   }
875*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
876*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
877*d9f75844SAndroid Build Coastguard Worker 
878*d9f75844SAndroid Build Coastguard Worker   // Sanity check that the caller's description has a rejected video section.
879*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, caller()->pc()->local_description());
880*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* caller_video_content =
881*d9f75844SAndroid Build Coastguard Worker       GetFirstVideoContent(caller()->pc()->local_description()->description());
882*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, caller_video_content);
883*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller_video_content->rejected);
884*d9f75844SAndroid Build Coastguard Worker   // Wait for some additional audio frames to be received.
885*d9f75844SAndroid Build Coastguard Worker   {
886*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
887*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectBidirectionalAudio();
888*d9f75844SAndroid Build Coastguard Worker     media_expectations.ExpectNoVideo();
889*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
890*d9f75844SAndroid Build Coastguard Worker   }
891*d9f75844SAndroid Build Coastguard Worker }
892*d9f75844SAndroid Build Coastguard Worker 
893*d9f75844SAndroid Build Coastguard Worker // Do one offer/answer with audio, another that disables it (rejecting the m=
894*d9f75844SAndroid Build Coastguard Worker // section), and another that re-enables it. Regression test for:
895*d9f75844SAndroid Build Coastguard Worker // bugs.webrtc.org/6023
TEST_F(PeerConnectionIntegrationTestPlanB,EnableAudioAfterRejecting)896*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
897*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
898*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
899*d9f75844SAndroid Build Coastguard Worker 
900*d9f75844SAndroid Build Coastguard Worker   // Add audio track, do normal offer/answer.
901*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
902*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalAudioTrack();
903*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
904*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
905*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
906*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
907*d9f75844SAndroid Build Coastguard Worker 
908*d9f75844SAndroid Build Coastguard Worker   // Remove audio track, and set offer_to_receive_audio to false to cause the
909*d9f75844SAndroid Build Coastguard Worker   // m= section to be completely disabled, not just "recvonly".
910*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->RemoveTrackOrError(sender);
911*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
912*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio = 0;
913*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
914*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
915*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
916*d9f75844SAndroid Build Coastguard Worker 
917*d9f75844SAndroid Build Coastguard Worker   // Add the audio track again, expecting negotiation to succeed and frames to
918*d9f75844SAndroid Build Coastguard Worker   // flow.
919*d9f75844SAndroid Build Coastguard Worker   sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
920*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio = 1;
921*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
922*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
923*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
924*d9f75844SAndroid Build Coastguard Worker 
925*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
926*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio();
927*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
928*d9f75844SAndroid Build Coastguard Worker }
929*d9f75844SAndroid Build Coastguard Worker 
930*d9f75844SAndroid Build Coastguard Worker // Basic end-to-end test, but without SSRC/MSID signaling. This functionality
931*d9f75844SAndroid Build Coastguard Worker // is needed to support legacy endpoints.
932*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): When we support the MID extension and demuxing on MID, also
933*d9f75844SAndroid Build Coastguard Worker // add a test for an end-to-end test without MID signaling either (basically,
934*d9f75844SAndroid Build Coastguard Worker // the minimum acceptable SDP).
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithoutSsrcOrMsidSignaling)935*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
936*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
937*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
938*d9f75844SAndroid Build Coastguard Worker   // Add audio and video, testing that packets can be demuxed on payload type.
939*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
940*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
941*d9f75844SAndroid Build Coastguard Worker   // Remove SSRCs and MSIDs from the received offer SDP.
942*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
943*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
944*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
945*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
946*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
947*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
948*d9f75844SAndroid Build Coastguard Worker }
949*d9f75844SAndroid Build Coastguard Worker 
950*d9f75844SAndroid Build Coastguard Worker // Basic end-to-end test, without SSRC signaling. This means that the track
951*d9f75844SAndroid Build Coastguard Worker // was created properly and frames are delivered when the MSIDs are communicated
952*d9f75844SAndroid Build Coastguard Worker // with a=msid lines and no a=ssrc lines.
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,EndToEndCallWithoutSsrcSignaling)953*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
954*d9f75844SAndroid Build Coastguard Worker        EndToEndCallWithoutSsrcSignaling) {
955*d9f75844SAndroid Build Coastguard Worker   const char kStreamId[] = "streamId";
956*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
957*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
958*d9f75844SAndroid Build Coastguard Worker   // Add just audio tracks.
959*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
960*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
961*d9f75844SAndroid Build Coastguard Worker 
962*d9f75844SAndroid Build Coastguard Worker   // Remove SSRCs from the received offer SDP.
963*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
964*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
965*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
966*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
967*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudio();
968*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
969*d9f75844SAndroid Build Coastguard Worker }
970*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,EndToEndCallAddReceiveVideoToSendOnlyCall)971*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
972*d9f75844SAndroid Build Coastguard Worker        EndToEndCallAddReceiveVideoToSendOnlyCall) {
973*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
974*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
975*d9f75844SAndroid Build Coastguard Worker   // Add one-directional video, from caller to callee.
976*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
977*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
978*d9f75844SAndroid Build Coastguard Worker 
979*d9f75844SAndroid Build Coastguard Worker   RtpTransceiverInit video_transceiver_init;
980*d9f75844SAndroid Build Coastguard Worker   video_transceiver_init.stream_ids = {"video1"};
981*d9f75844SAndroid Build Coastguard Worker   video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
982*d9f75844SAndroid Build Coastguard Worker   auto video_sender =
983*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
984*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
985*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
986*d9f75844SAndroid Build Coastguard Worker 
987*d9f75844SAndroid Build Coastguard Worker   // Add receive direction.
988*d9f75844SAndroid Build Coastguard Worker   video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
989*d9f75844SAndroid Build Coastguard Worker 
990*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
991*d9f75844SAndroid Build Coastguard Worker       callee()->CreateLocalVideoTrack();
992*d9f75844SAndroid Build Coastguard Worker 
993*d9f75844SAndroid Build Coastguard Worker   callee()->AddTrack(callee_track);
994*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
995*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
996*d9f75844SAndroid Build Coastguard Worker   // Ensure that video frames are received end-to-end.
997*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
998*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
999*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1000*d9f75844SAndroid Build Coastguard Worker }
1001*d9f75844SAndroid Build Coastguard Worker 
1002*d9f75844SAndroid Build Coastguard Worker // Tests that video flows between multiple video tracks when SSRCs are not
1003*d9f75844SAndroid Build Coastguard Worker // signaled. This exercises the MID RTP header extension which is needed to
1004*d9f75844SAndroid Build Coastguard Worker // demux the incoming video tracks.
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc)1005*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1006*d9f75844SAndroid Build Coastguard Worker        EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1007*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1008*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1009*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1010*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1011*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
1012*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
1013*d9f75844SAndroid Build Coastguard Worker 
1014*d9f75844SAndroid Build Coastguard Worker   caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1015*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1016*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1017*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1018*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1019*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1020*d9f75844SAndroid Build Coastguard Worker 
1021*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in both directions on both tracks.
1022*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1023*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
1024*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
1025*d9f75844SAndroid Build Coastguard Worker }
1026*d9f75844SAndroid Build Coastguard Worker 
1027*d9f75844SAndroid Build Coastguard Worker // Used for the test below.
RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription * desc)1028*d9f75844SAndroid Build Coastguard Worker void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1029*d9f75844SAndroid Build Coastguard Worker   RemoveSsrcsAndKeepMsids(desc);
1030*d9f75844SAndroid Build Coastguard Worker   desc->RemoveGroupByName("BUNDLE");
1031*d9f75844SAndroid Build Coastguard Worker   for (ContentInfo& content : desc->contents()) {
1032*d9f75844SAndroid Build Coastguard Worker     cricket::MediaContentDescription* media = content.media_description();
1033*d9f75844SAndroid Build Coastguard Worker     cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1034*d9f75844SAndroid Build Coastguard Worker     extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1035*d9f75844SAndroid Build Coastguard Worker                                     [](const RtpExtension& extension) {
1036*d9f75844SAndroid Build Coastguard Worker                                       return extension.uri ==
1037*d9f75844SAndroid Build Coastguard Worker                                              RtpExtension::kMidUri;
1038*d9f75844SAndroid Build Coastguard Worker                                     }),
1039*d9f75844SAndroid Build Coastguard Worker                      extensions.end());
1040*d9f75844SAndroid Build Coastguard Worker     media->set_rtp_header_extensions(extensions);
1041*d9f75844SAndroid Build Coastguard Worker   }
1042*d9f75844SAndroid Build Coastguard Worker }
1043*d9f75844SAndroid Build Coastguard Worker 
1044*d9f75844SAndroid Build Coastguard Worker // Tests that video flows between multiple video tracks when BUNDLE is not used,
1045*d9f75844SAndroid Build Coastguard Worker // SSRCs are not signaled and the MID RTP header extension is not used. This
1046*d9f75844SAndroid Build Coastguard Worker // relies on demuxing by payload type, which normally doesn't work if you have
1047*d9f75844SAndroid Build Coastguard Worker // multiple media sections using the same payload type, but which should work as
1048*d9f75844SAndroid Build Coastguard Worker // long as the media sections aren't bundled.
1049*d9f75844SAndroid Build Coastguard Worker // Regression test for: http://crbug.com/webrtc/12023
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid)1050*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1051*d9f75844SAndroid Build Coastguard Worker        EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1052*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1053*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1054*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1055*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1056*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
1057*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
1058*d9f75844SAndroid Build Coastguard Worker   caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1059*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1060*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1061*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1062*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1063*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1064*d9f75844SAndroid Build Coastguard Worker   // Make sure we are not bundled.
1065*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1066*d9f75844SAndroid Build Coastguard Worker             caller()->pc()->GetSenders()[1]->dtls_transport());
1067*d9f75844SAndroid Build Coastguard Worker 
1068*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in both directions on both tracks.
1069*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1070*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
1071*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
1072*d9f75844SAndroid Build Coastguard Worker }
1073*d9f75844SAndroid Build Coastguard Worker 
1074*d9f75844SAndroid Build Coastguard Worker // Used for the test below.
ModifyPayloadTypesAndRemoveMidExtension(cricket::SessionDescription * desc)1075*d9f75844SAndroid Build Coastguard Worker void ModifyPayloadTypesAndRemoveMidExtension(
1076*d9f75844SAndroid Build Coastguard Worker     cricket::SessionDescription* desc) {
1077*d9f75844SAndroid Build Coastguard Worker   int pt = 96;
1078*d9f75844SAndroid Build Coastguard Worker   for (ContentInfo& content : desc->contents()) {
1079*d9f75844SAndroid Build Coastguard Worker     cricket::MediaContentDescription* media = content.media_description();
1080*d9f75844SAndroid Build Coastguard Worker     cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1081*d9f75844SAndroid Build Coastguard Worker     extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1082*d9f75844SAndroid Build Coastguard Worker                                     [](const RtpExtension& extension) {
1083*d9f75844SAndroid Build Coastguard Worker                                       return extension.uri ==
1084*d9f75844SAndroid Build Coastguard Worker                                              RtpExtension::kMidUri;
1085*d9f75844SAndroid Build Coastguard Worker                                     }),
1086*d9f75844SAndroid Build Coastguard Worker                      extensions.end());
1087*d9f75844SAndroid Build Coastguard Worker     media->set_rtp_header_extensions(extensions);
1088*d9f75844SAndroid Build Coastguard Worker     cricket::VideoContentDescription* video = media->as_video();
1089*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(video != nullptr);
1090*d9f75844SAndroid Build Coastguard Worker     std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1091*d9f75844SAndroid Build Coastguard Worker     video->set_codecs(codecs);
1092*d9f75844SAndroid Build Coastguard Worker   }
1093*d9f75844SAndroid Build Coastguard Worker }
1094*d9f75844SAndroid Build Coastguard Worker 
1095*d9f75844SAndroid Build Coastguard Worker // Tests that two video tracks can be demultiplexed by payload type alone, by
1096*d9f75844SAndroid Build Coastguard Worker // using different payload types for the same codec in different m= sections.
1097*d9f75844SAndroid Build Coastguard Worker // This practice is discouraged but historically has been supported.
1098*d9f75844SAndroid Build Coastguard Worker // Regression test for: http://crbug.com/webrtc/12029
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType)1099*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1100*d9f75844SAndroid Build Coastguard Worker        EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1101*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1102*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1103*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1104*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1105*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
1106*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
1107*d9f75844SAndroid Build Coastguard Worker   caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1108*d9f75844SAndroid Build Coastguard Worker   callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1109*d9f75844SAndroid Build Coastguard Worker   // We can't remove SSRCs from the generated SDP because then no send streams
1110*d9f75844SAndroid Build Coastguard Worker   // would be created.
1111*d9f75844SAndroid Build Coastguard Worker   caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1112*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1113*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1114*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1115*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1116*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1117*d9f75844SAndroid Build Coastguard Worker   // Make sure we are bundled.
1118*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1119*d9f75844SAndroid Build Coastguard Worker             caller()->pc()->GetSenders()[1]->dtls_transport());
1120*d9f75844SAndroid Build Coastguard Worker 
1121*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in both directions on both tracks.
1122*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1123*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
1124*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
1125*d9f75844SAndroid Build Coastguard Worker }
1126*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,NoStreamsMsidLinePresent)1127*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1128*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1129*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1130*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1131*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1132*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1133*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1134*d9f75844SAndroid Build Coastguard Worker   auto callee_receivers = callee()->pc()->GetReceivers();
1135*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee_receivers.size());
1136*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1137*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1138*d9f75844SAndroid Build Coastguard Worker }
1139*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,NoStreamsMsidLineMissing)1140*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1141*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1142*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1143*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1144*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1145*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1146*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1147*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1148*d9f75844SAndroid Build Coastguard Worker   auto callee_receivers = callee()->pc()->GetReceivers();
1149*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(2u, callee_receivers.size());
1150*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1151*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1152*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1153*d9f75844SAndroid Build Coastguard Worker             callee_receivers[1]->stream_ids()[0]);
1154*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(callee_receivers[0]->streams()[0],
1155*d9f75844SAndroid Build Coastguard Worker             callee_receivers[1]->streams()[0]);
1156*d9f75844SAndroid Build Coastguard Worker }
1157*d9f75844SAndroid Build Coastguard Worker 
1158*d9f75844SAndroid Build Coastguard Worker // Test that if two video tracks are sent (from caller to callee, in this test),
1159*d9f75844SAndroid Build Coastguard Worker // they're transmitted correctly end-to-end.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithTwoVideoTracks)1160*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
1161*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1162*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1163*d9f75844SAndroid Build Coastguard Worker   // Add one audio/video stream, and one video-only stream.
1164*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1165*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
1166*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1167*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1168*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
1169*d9f75844SAndroid Build Coastguard Worker 
1170*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1171*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
1172*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1173*d9f75844SAndroid Build Coastguard Worker }
1174*d9f75844SAndroid Build Coastguard Worker 
MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription * desc)1175*d9f75844SAndroid Build Coastguard Worker static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1176*d9f75844SAndroid Build Coastguard Worker   bool first = true;
1177*d9f75844SAndroid Build Coastguard Worker   for (cricket::ContentInfo& content : desc->contents()) {
1178*d9f75844SAndroid Build Coastguard Worker     if (first) {
1179*d9f75844SAndroid Build Coastguard Worker       first = false;
1180*d9f75844SAndroid Build Coastguard Worker       continue;
1181*d9f75844SAndroid Build Coastguard Worker     }
1182*d9f75844SAndroid Build Coastguard Worker     content.bundle_only = true;
1183*d9f75844SAndroid Build Coastguard Worker   }
1184*d9f75844SAndroid Build Coastguard Worker   first = true;
1185*d9f75844SAndroid Build Coastguard Worker   for (cricket::TransportInfo& transport : desc->transport_infos()) {
1186*d9f75844SAndroid Build Coastguard Worker     if (first) {
1187*d9f75844SAndroid Build Coastguard Worker       first = false;
1188*d9f75844SAndroid Build Coastguard Worker       continue;
1189*d9f75844SAndroid Build Coastguard Worker     }
1190*d9f75844SAndroid Build Coastguard Worker     transport.description.ice_ufrag.clear();
1191*d9f75844SAndroid Build Coastguard Worker     transport.description.ice_pwd.clear();
1192*d9f75844SAndroid Build Coastguard Worker     transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1193*d9f75844SAndroid Build Coastguard Worker     transport.description.identity_fingerprint.reset(nullptr);
1194*d9f75844SAndroid Build Coastguard Worker   }
1195*d9f75844SAndroid Build Coastguard Worker }
1196*d9f75844SAndroid Build Coastguard Worker 
1197*d9f75844SAndroid Build Coastguard Worker // Test that if applying a true "max bundle" offer, which uses ports of 0,
1198*d9f75844SAndroid Build Coastguard Worker // "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1199*d9f75844SAndroid Build Coastguard Worker // "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1200*d9f75844SAndroid Build Coastguard Worker // successfully and media flows.
1201*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1202*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Won't need this test once we start generating actual
1203*d9f75844SAndroid Build Coastguard Worker // standards-compliant SDP.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithSpecCompliantMaxBundleOffer)1204*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1205*d9f75844SAndroid Build Coastguard Worker        EndToEndCallWithSpecCompliantMaxBundleOffer) {
1206*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1207*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1208*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1209*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1210*d9f75844SAndroid Build Coastguard Worker   // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1211*d9f75844SAndroid Build Coastguard Worker   // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1212*d9f75844SAndroid Build Coastguard Worker   // but the first m= section.
1213*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1214*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1215*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1216*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1217*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
1218*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1219*d9f75844SAndroid Build Coastguard Worker }
1220*d9f75844SAndroid Build Coastguard Worker 
1221*d9f75844SAndroid Build Coastguard Worker // Test that we can receive the audio output level from a remote audio track.
1222*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Use a fake audio source and verify that the output level is
1223*d9f75844SAndroid Build Coastguard Worker // exactly what the source on the other side was configured with.
TEST_P(PeerConnectionIntegrationTest,GetAudioOutputLevelStatsWithOldStatsApi)1224*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
1225*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1226*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1227*d9f75844SAndroid Build Coastguard Worker   // Just add an audio track.
1228*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1229*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1230*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1231*d9f75844SAndroid Build Coastguard Worker 
1232*d9f75844SAndroid Build Coastguard Worker   // Get the audio output level stats. Note that the level is not available
1233*d9f75844SAndroid Build Coastguard Worker   // until an RTCP packet has been received.
1234*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
1235*d9f75844SAndroid Build Coastguard Worker                    kMaxWaitForFramesMs);
1236*d9f75844SAndroid Build Coastguard Worker }
1237*d9f75844SAndroid Build Coastguard Worker 
1238*d9f75844SAndroid Build Coastguard Worker // Test that an audio input level is reported.
1239*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Use a fake audio source and verify that the input level is
1240*d9f75844SAndroid Build Coastguard Worker // exactly what the source was configured with.
TEST_P(PeerConnectionIntegrationTest,GetAudioInputLevelStatsWithOldStatsApi)1241*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
1242*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1243*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1244*d9f75844SAndroid Build Coastguard Worker   // Just add an audio track.
1245*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1246*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1247*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1248*d9f75844SAndroid Build Coastguard Worker 
1249*d9f75844SAndroid Build Coastguard Worker   // Get the audio input level stats. The level should be available very
1250*d9f75844SAndroid Build Coastguard Worker   // soon after the test starts.
1251*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
1252*d9f75844SAndroid Build Coastguard Worker                    kMaxWaitForStatsMs);
1253*d9f75844SAndroid Build Coastguard Worker }
1254*d9f75844SAndroid Build Coastguard Worker 
1255*d9f75844SAndroid Build Coastguard Worker // Test that we can get incoming byte counts from both audio and video tracks.
TEST_P(PeerConnectionIntegrationTest,GetBytesReceivedStatsWithOldStatsApi)1256*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
1257*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1258*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1259*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1260*d9f75844SAndroid Build Coastguard Worker   // Do offer/answer, wait for the callee to receive some frames.
1261*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1262*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1263*d9f75844SAndroid Build Coastguard Worker 
1264*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1265*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
1266*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1267*d9f75844SAndroid Build Coastguard Worker 
1268*d9f75844SAndroid Build Coastguard Worker   // Get a handle to the remote tracks created, so they can be used as GetStats
1269*d9f75844SAndroid Build Coastguard Worker   // filters.
1270*d9f75844SAndroid Build Coastguard Worker   for (const auto& receiver : callee()->pc()->GetReceivers()) {
1271*d9f75844SAndroid Build Coastguard Worker     // We received frames, so we definitely should have nonzero "received bytes"
1272*d9f75844SAndroid Build Coastguard Worker     // stats at this point.
1273*d9f75844SAndroid Build Coastguard Worker     EXPECT_GT(
1274*d9f75844SAndroid Build Coastguard Worker         callee()->OldGetStatsForTrack(receiver->track().get())->BytesReceived(),
1275*d9f75844SAndroid Build Coastguard Worker         0);
1276*d9f75844SAndroid Build Coastguard Worker   }
1277*d9f75844SAndroid Build Coastguard Worker }
1278*d9f75844SAndroid Build Coastguard Worker 
1279*d9f75844SAndroid Build Coastguard Worker // Test that we can get outgoing byte counts from both audio and video tracks.
TEST_P(PeerConnectionIntegrationTest,GetBytesSentStatsWithOldStatsApi)1280*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
1281*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1282*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1283*d9f75844SAndroid Build Coastguard Worker   auto audio_track = caller()->CreateLocalAudioTrack();
1284*d9f75844SAndroid Build Coastguard Worker   auto video_track = caller()->CreateLocalVideoTrack();
1285*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(audio_track);
1286*d9f75844SAndroid Build Coastguard Worker   caller()->AddTrack(video_track);
1287*d9f75844SAndroid Build Coastguard Worker   // Do offer/answer, wait for the callee to receive some frames.
1288*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1289*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1290*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1291*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
1292*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1293*d9f75844SAndroid Build Coastguard Worker 
1294*d9f75844SAndroid Build Coastguard Worker   // The callee received frames, so we definitely should have nonzero "sent
1295*d9f75844SAndroid Build Coastguard Worker   // bytes" stats at this point.
1296*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(caller()->OldGetStatsForTrack(audio_track.get())->BytesSent(), 0);
1297*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(caller()->OldGetStatsForTrack(video_track.get())->BytesSent(), 0);
1298*d9f75844SAndroid Build Coastguard Worker }
1299*d9f75844SAndroid Build Coastguard Worker 
1300*d9f75844SAndroid Build Coastguard Worker // Test that the track ID is associated with all local and remote SSRC stats
1301*d9f75844SAndroid Build Coastguard Worker // using the old GetStats() and more than 1 audio and more than 1 video track.
1302*d9f75844SAndroid Build Coastguard Worker // This is a regression test for crbug.com/906988
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,OldGetStatsAssociatesTrackIdForManyMediaSections)1303*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1304*d9f75844SAndroid Build Coastguard Worker        OldGetStatsAssociatesTrackIdForManyMediaSections) {
1305*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1306*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1307*d9f75844SAndroid Build Coastguard Worker   auto audio_sender_1 = caller()->AddAudioTrack();
1308*d9f75844SAndroid Build Coastguard Worker   auto video_sender_1 = caller()->AddVideoTrack();
1309*d9f75844SAndroid Build Coastguard Worker   auto audio_sender_2 = caller()->AddAudioTrack();
1310*d9f75844SAndroid Build Coastguard Worker   auto video_sender_2 = caller()->AddVideoTrack();
1311*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1312*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1313*d9f75844SAndroid Build Coastguard Worker 
1314*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1315*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
1316*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1317*d9f75844SAndroid Build Coastguard Worker 
1318*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> track_ids = {
1319*d9f75844SAndroid Build Coastguard Worker       audio_sender_1->track()->id(), video_sender_1->track()->id(),
1320*d9f75844SAndroid Build Coastguard Worker       audio_sender_2->track()->id(), video_sender_2->track()->id()};
1321*d9f75844SAndroid Build Coastguard Worker 
1322*d9f75844SAndroid Build Coastguard Worker   auto caller_stats = caller()->OldGetStats();
1323*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1324*d9f75844SAndroid Build Coastguard Worker   auto callee_stats = callee()->OldGetStats();
1325*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1326*d9f75844SAndroid Build Coastguard Worker }
1327*d9f75844SAndroid Build Coastguard Worker 
1328*d9f75844SAndroid Build Coastguard Worker // Test that the new GetStats() returns stats for all outgoing/incoming streams
1329*d9f75844SAndroid Build Coastguard Worker // with the correct track IDs if there are more than one audio and more than one
1330*d9f75844SAndroid Build Coastguard Worker // video senders/receivers.
TEST_P(PeerConnectionIntegrationTest,NewGetStatsManyAudioAndManyVideoStreams)1331*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1332*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1333*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1334*d9f75844SAndroid Build Coastguard Worker   auto audio_sender_1 = caller()->AddAudioTrack();
1335*d9f75844SAndroid Build Coastguard Worker   auto video_sender_1 = caller()->AddVideoTrack();
1336*d9f75844SAndroid Build Coastguard Worker   auto audio_sender_2 = caller()->AddAudioTrack();
1337*d9f75844SAndroid Build Coastguard Worker   auto video_sender_2 = caller()->AddVideoTrack();
1338*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1339*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1340*d9f75844SAndroid Build Coastguard Worker 
1341*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1342*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
1343*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1344*d9f75844SAndroid Build Coastguard Worker 
1345*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> track_ids = {
1346*d9f75844SAndroid Build Coastguard Worker       audio_sender_1->track()->id(), video_sender_1->track()->id(),
1347*d9f75844SAndroid Build Coastguard Worker       audio_sender_2->track()->id(), video_sender_2->track()->id()};
1348*d9f75844SAndroid Build Coastguard Worker 
1349*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1350*d9f75844SAndroid Build Coastguard Worker       caller()->NewGetStats();
1351*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller_report);
1352*d9f75844SAndroid Build Coastguard Worker   auto outbound_stream_stats =
1353*d9f75844SAndroid Build Coastguard Worker       caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
1354*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(outbound_stream_stats.size(), 4u);
1355*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> outbound_track_ids;
1356*d9f75844SAndroid Build Coastguard Worker   for (const auto& stat : outbound_stream_stats) {
1357*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(stat->bytes_sent.is_defined());
1358*d9f75844SAndroid Build Coastguard Worker     EXPECT_LT(0u, *stat->bytes_sent);
1359*d9f75844SAndroid Build Coastguard Worker     if (*stat->kind == "video") {
1360*d9f75844SAndroid Build Coastguard Worker       ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1361*d9f75844SAndroid Build Coastguard Worker       EXPECT_GT(*stat->key_frames_encoded, 0u);
1362*d9f75844SAndroid Build Coastguard Worker       ASSERT_TRUE(stat->frames_encoded.is_defined());
1363*d9f75844SAndroid Build Coastguard Worker       EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1364*d9f75844SAndroid Build Coastguard Worker     }
1365*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(stat->track_id.is_defined());
1366*d9f75844SAndroid Build Coastguard Worker     const auto* track_stat =
1367*d9f75844SAndroid Build Coastguard Worker         caller_report->GetAs<webrtc::DEPRECATED_RTCMediaStreamTrackStats>(
1368*d9f75844SAndroid Build Coastguard Worker             *stat->track_id);
1369*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(track_stat);
1370*d9f75844SAndroid Build Coastguard Worker     outbound_track_ids.push_back(*track_stat->track_identifier);
1371*d9f75844SAndroid Build Coastguard Worker   }
1372*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1373*d9f75844SAndroid Build Coastguard Worker 
1374*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1375*d9f75844SAndroid Build Coastguard Worker       callee()->NewGetStats();
1376*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee_report);
1377*d9f75844SAndroid Build Coastguard Worker   auto inbound_stream_stats =
1378*d9f75844SAndroid Build Coastguard Worker       callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1379*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(4u, inbound_stream_stats.size());
1380*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> inbound_track_ids;
1381*d9f75844SAndroid Build Coastguard Worker   for (const auto& stat : inbound_stream_stats) {
1382*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(stat->bytes_received.is_defined());
1383*d9f75844SAndroid Build Coastguard Worker     EXPECT_LT(0u, *stat->bytes_received);
1384*d9f75844SAndroid Build Coastguard Worker     if (*stat->kind == "video") {
1385*d9f75844SAndroid Build Coastguard Worker       ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1386*d9f75844SAndroid Build Coastguard Worker       EXPECT_GT(*stat->key_frames_decoded, 0u);
1387*d9f75844SAndroid Build Coastguard Worker       ASSERT_TRUE(stat->frames_decoded.is_defined());
1388*d9f75844SAndroid Build Coastguard Worker       EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1389*d9f75844SAndroid Build Coastguard Worker     }
1390*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(stat->track_id.is_defined());
1391*d9f75844SAndroid Build Coastguard Worker     const auto* track_stat =
1392*d9f75844SAndroid Build Coastguard Worker         callee_report->GetAs<webrtc::DEPRECATED_RTCMediaStreamTrackStats>(
1393*d9f75844SAndroid Build Coastguard Worker             *stat->track_id);
1394*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(track_stat);
1395*d9f75844SAndroid Build Coastguard Worker     inbound_track_ids.push_back(*track_stat->track_identifier);
1396*d9f75844SAndroid Build Coastguard Worker   }
1397*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1398*d9f75844SAndroid Build Coastguard Worker }
1399*d9f75844SAndroid Build Coastguard Worker 
1400*d9f75844SAndroid Build Coastguard Worker // Test that we can get stats (using the new stats implementation) for
1401*d9f75844SAndroid Build Coastguard Worker // unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1402*d9f75844SAndroid Build Coastguard Worker // SDP.
TEST_P(PeerConnectionIntegrationTest,GetStatsForUnsignaledStreamWithNewStatsApi)1403*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1404*d9f75844SAndroid Build Coastguard Worker        GetStatsForUnsignaledStreamWithNewStatsApi) {
1405*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1406*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1407*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1408*d9f75844SAndroid Build Coastguard Worker   // Remove SSRCs and MSIDs from the received offer SDP.
1409*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1410*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1411*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1412*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1413*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio(1);
1414*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1415*d9f75844SAndroid Build Coastguard Worker 
1416*d9f75844SAndroid Build Coastguard Worker   // We received a frame, so we should have nonzero "bytes received" stats for
1417*d9f75844SAndroid Build Coastguard Worker   // the unsignaled stream, if stats are working for it.
1418*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1419*d9f75844SAndroid Build Coastguard Worker       callee()->NewGetStats();
1420*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, report);
1421*d9f75844SAndroid Build Coastguard Worker   auto inbound_stream_stats =
1422*d9f75844SAndroid Build Coastguard Worker       report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1423*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1U, inbound_stream_stats.size());
1424*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1425*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
1426*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1427*d9f75844SAndroid Build Coastguard Worker }
1428*d9f75844SAndroid Build Coastguard Worker 
1429*d9f75844SAndroid Build Coastguard Worker // Same as above but for the legacy stats implementation.
TEST_P(PeerConnectionIntegrationTest,GetStatsForUnsignaledStreamWithOldStatsApi)1430*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1431*d9f75844SAndroid Build Coastguard Worker        GetStatsForUnsignaledStreamWithOldStatsApi) {
1432*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1433*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1434*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1435*d9f75844SAndroid Build Coastguard Worker   // Remove SSRCs and MSIDs from the received offer SDP.
1436*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1437*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1438*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1439*d9f75844SAndroid Build Coastguard Worker 
1440*d9f75844SAndroid Build Coastguard Worker   // Note that, since the old stats implementation associates SSRCs with tracks
1441*d9f75844SAndroid Build Coastguard Worker   // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1442*d9f75844SAndroid Build Coastguard Worker   // associated track ID. So we can't use the track "selector" argument.
1443*d9f75844SAndroid Build Coastguard Worker   //
1444*d9f75844SAndroid Build Coastguard Worker   // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1445*d9f75844SAndroid Build Coastguard Worker   // return cached stats if not enough time has passed since the last update.
1446*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
1447*d9f75844SAndroid Build Coastguard Worker                    kDefaultTimeout);
1448*d9f75844SAndroid Build Coastguard Worker }
1449*d9f75844SAndroid Build Coastguard Worker 
1450*d9f75844SAndroid Build Coastguard Worker // Test that we can successfully get the media related stats (audio level
1451*d9f75844SAndroid Build Coastguard Worker // etc.) for the unsignaled stream.
TEST_P(PeerConnectionIntegrationTest,GetMediaStatsForUnsignaledStreamWithNewStatsApi)1452*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1453*d9f75844SAndroid Build Coastguard Worker        GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1454*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1455*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1456*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1457*d9f75844SAndroid Build Coastguard Worker   // Remove SSRCs and MSIDs from the received offer SDP.
1458*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1459*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1460*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1461*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1462*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio(1);
1463*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeVideo(1);
1464*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1465*d9f75844SAndroid Build Coastguard Worker 
1466*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1467*d9f75844SAndroid Build Coastguard Worker       callee()->NewGetStats();
1468*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, report);
1469*d9f75844SAndroid Build Coastguard Worker 
1470*d9f75844SAndroid Build Coastguard Worker   auto media_stats =
1471*d9f75844SAndroid Build Coastguard Worker       report->GetStatsOfType<webrtc::DEPRECATED_RTCMediaStreamTrackStats>();
1472*d9f75844SAndroid Build Coastguard Worker   auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1473*d9f75844SAndroid Build Coastguard Worker   ASSERT_GE(audio_index, 0);
1474*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
1475*d9f75844SAndroid Build Coastguard Worker }
1476*d9f75844SAndroid Build Coastguard Worker 
1477*d9f75844SAndroid Build Coastguard Worker // Helper for test below.
ModifySsrcs(cricket::SessionDescription * desc)1478*d9f75844SAndroid Build Coastguard Worker void ModifySsrcs(cricket::SessionDescription* desc) {
1479*d9f75844SAndroid Build Coastguard Worker   for (ContentInfo& content : desc->contents()) {
1480*d9f75844SAndroid Build Coastguard Worker     for (StreamParams& stream :
1481*d9f75844SAndroid Build Coastguard Worker          content.media_description()->mutable_streams()) {
1482*d9f75844SAndroid Build Coastguard Worker       for (uint32_t& ssrc : stream.ssrcs) {
1483*d9f75844SAndroid Build Coastguard Worker         ssrc = rtc::CreateRandomId();
1484*d9f75844SAndroid Build Coastguard Worker       }
1485*d9f75844SAndroid Build Coastguard Worker     }
1486*d9f75844SAndroid Build Coastguard Worker   }
1487*d9f75844SAndroid Build Coastguard Worker }
1488*d9f75844SAndroid Build Coastguard Worker 
1489*d9f75844SAndroid Build Coastguard Worker // Test that the "DEPRECATED_RTCMediaStreamTrackStats"  object is updated
1490*d9f75844SAndroid Build Coastguard Worker // correctly when SSRCs are unsignaled, and the SSRC of the received (audio)
1491*d9f75844SAndroid Build Coastguard Worker // stream changes. This should result in two "RTCInboundRTPStreamStats", but
1492*d9f75844SAndroid Build Coastguard Worker // only one "DEPRECATED_RTCMediaStreamTrackStats", whose counters go up
1493*d9f75844SAndroid Build Coastguard Worker // continuously rather than being reset to 0 once the SSRC change occurs.
1494*d9f75844SAndroid Build Coastguard Worker //
1495*d9f75844SAndroid Build Coastguard Worker // Regression test for this bug:
1496*d9f75844SAndroid Build Coastguard Worker // https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1497*d9f75844SAndroid Build Coastguard Worker //
1498*d9f75844SAndroid Build Coastguard Worker // The bug causes the track stats to only represent one of the two streams:
1499*d9f75844SAndroid Build Coastguard Worker // whichever one has the higher SSRC. So with this bug, there was a 50% chance
1500*d9f75844SAndroid Build Coastguard Worker // that the track stat counters would reset to 0 when the new stream is
1501*d9f75844SAndroid Build Coastguard Worker // received, and a 50% chance that they'll stop updating (while
1502*d9f75844SAndroid Build Coastguard Worker // "concealed_samples" continues increasing, due to silence being generated for
1503*d9f75844SAndroid Build Coastguard Worker // the inactive stream).
TEST_P(PeerConnectionIntegrationTest,TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges)1504*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1505*d9f75844SAndroid Build Coastguard Worker        TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
1506*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1507*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1508*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
1509*d9f75844SAndroid Build Coastguard Worker   // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1510*d9f75844SAndroid Build Coastguard Worker   // that doesn't signal SSRCs (from the callee's perspective).
1511*d9f75844SAndroid Build Coastguard Worker   callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1512*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1513*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1514*d9f75844SAndroid Build Coastguard Worker   // Wait for 50 audio frames (500ms of audio) to be received by the callee.
1515*d9f75844SAndroid Build Coastguard Worker   {
1516*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
1517*d9f75844SAndroid Build Coastguard Worker     media_expectations.CalleeExpectsSomeAudio(50);
1518*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
1519*d9f75844SAndroid Build Coastguard Worker   }
1520*d9f75844SAndroid Build Coastguard Worker   // Some audio frames were received, so we should have nonzero "samples
1521*d9f75844SAndroid Build Coastguard Worker   // received" for the track.
1522*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1523*d9f75844SAndroid Build Coastguard Worker       callee()->NewGetStats();
1524*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, report);
1525*d9f75844SAndroid Build Coastguard Worker   auto track_stats =
1526*d9f75844SAndroid Build Coastguard Worker       report->GetStatsOfType<webrtc::DEPRECATED_RTCMediaStreamTrackStats>();
1527*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1U, track_stats.size());
1528*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1529*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1530*d9f75844SAndroid Build Coastguard Worker   // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1531*d9f75844SAndroid Build Coastguard Worker 
1532*d9f75844SAndroid Build Coastguard Worker   // Create a new offer and munge it to cause the caller to use a new SSRC.
1533*d9f75844SAndroid Build Coastguard Worker   caller()->SetGeneratedSdpMunger(ModifySsrcs);
1534*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1535*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1536*d9f75844SAndroid Build Coastguard Worker   // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1537*d9f75844SAndroid Build Coastguard Worker   // SSRC.
1538*d9f75844SAndroid Build Coastguard Worker   {
1539*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
1540*d9f75844SAndroid Build Coastguard Worker     media_expectations.CalleeExpectsSomeAudio(25);
1541*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
1542*d9f75844SAndroid Build Coastguard Worker   }
1543*d9f75844SAndroid Build Coastguard Worker 
1544*d9f75844SAndroid Build Coastguard Worker   report = callee()->NewGetStats();
1545*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, report);
1546*d9f75844SAndroid Build Coastguard Worker   track_stats =
1547*d9f75844SAndroid Build Coastguard Worker       report->GetStatsOfType<webrtc::DEPRECATED_RTCMediaStreamTrackStats>();
1548*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1U, track_stats.size());
1549*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1550*d9f75844SAndroid Build Coastguard Worker   // The "total samples received" stat should only be greater than it was
1551*d9f75844SAndroid Build Coastguard Worker   // before.
1552*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1553*d9f75844SAndroid Build Coastguard Worker   // Right now, the new SSRC will cause the counters to reset to 0.
1554*d9f75844SAndroid Build Coastguard Worker   // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1555*d9f75844SAndroid Build Coastguard Worker 
1556*d9f75844SAndroid Build Coastguard Worker   // Additionally, the percentage of concealed samples (samples generated to
1557*d9f75844SAndroid Build Coastguard Worker   // conceal packet loss) should be less than 50%. If it's greater, that's a
1558*d9f75844SAndroid Build Coastguard Worker   // good sign that we're seeing stats from the old stream that's no longer
1559*d9f75844SAndroid Build Coastguard Worker   // receiving packets, and is generating concealed samples of silence.
1560*d9f75844SAndroid Build Coastguard Worker   constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
1561*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1562*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(*track_stats[0]->concealed_samples,
1563*d9f75844SAndroid Build Coastguard Worker             *track_stats[0]->total_samples_received *
1564*d9f75844SAndroid Build Coastguard Worker                 kAcceptableConcealedSamplesPercentage);
1565*d9f75844SAndroid Build Coastguard Worker 
1566*d9f75844SAndroid Build Coastguard Worker   // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1567*d9f75844SAndroid Build Coastguard Worker   // sanity check that the SSRC really changed.
1568*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): This isn't working right now, because we're not returning
1569*d9f75844SAndroid Build Coastguard Worker   // *any* stats for the inactive stream. Uncomment when the bug is completely
1570*d9f75844SAndroid Build Coastguard Worker   // fixed.
1571*d9f75844SAndroid Build Coastguard Worker   // auto inbound_stream_stats =
1572*d9f75844SAndroid Build Coastguard Worker   //     report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1573*d9f75844SAndroid Build Coastguard Worker   // ASSERT_EQ(2U, inbound_stream_stats.size());
1574*d9f75844SAndroid Build Coastguard Worker }
1575*d9f75844SAndroid Build Coastguard Worker 
1576*d9f75844SAndroid Build Coastguard Worker // Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithDtls10)1577*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
1578*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options dtls_10_options;
1579*d9f75844SAndroid Build Coastguard Worker   dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1580*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1581*d9f75844SAndroid Build Coastguard Worker                                                       dtls_10_options));
1582*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1583*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
1584*d9f75844SAndroid Build Coastguard Worker   // direction.
1585*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1586*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1587*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1588*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1589*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1590*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
1591*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1592*d9f75844SAndroid Build Coastguard Worker }
1593*d9f75844SAndroid Build Coastguard Worker 
1594*d9f75844SAndroid Build Coastguard Worker // Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
TEST_P(PeerConnectionIntegrationTest,Dtls10CipherStatsAndUmaMetrics)1595*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
1596*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options dtls_10_options;
1597*d9f75844SAndroid Build Coastguard Worker   dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1598*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1599*d9f75844SAndroid Build Coastguard Worker                                                       dtls_10_options));
1600*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1601*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1602*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1603*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1604*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1605*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
1606*d9f75844SAndroid Build Coastguard Worker                        caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
1607*d9f75844SAndroid Build Coastguard Worker                    kDefaultTimeout);
1608*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
1609*d9f75844SAndroid Build Coastguard Worker                  caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
1610*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/9456): Fix it.
1611*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1612*d9f75844SAndroid Build Coastguard Worker                           "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1613*d9f75844SAndroid Build Coastguard Worker                           kDefaultSrtpCryptoSuite));
1614*d9f75844SAndroid Build Coastguard Worker }
1615*d9f75844SAndroid Build Coastguard Worker 
1616*d9f75844SAndroid Build Coastguard Worker // Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
TEST_P(PeerConnectionIntegrationTest,Dtls12CipherStatsAndUmaMetrics)1617*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
1618*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options dtls_12_options;
1619*d9f75844SAndroid Build Coastguard Worker   dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1620*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1621*d9f75844SAndroid Build Coastguard Worker                                                       dtls_12_options));
1622*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1623*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1624*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1625*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1626*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
1627*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
1628*d9f75844SAndroid Build Coastguard Worker                        caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
1629*d9f75844SAndroid Build Coastguard Worker                    kDefaultTimeout);
1630*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
1631*d9f75844SAndroid Build Coastguard Worker                  caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
1632*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/9456): Fix it.
1633*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1634*d9f75844SAndroid Build Coastguard Worker                           "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1635*d9f75844SAndroid Build Coastguard Worker                           kDefaultSrtpCryptoSuite));
1636*d9f75844SAndroid Build Coastguard Worker }
1637*d9f75844SAndroid Build Coastguard Worker 
1638*d9f75844SAndroid Build Coastguard Worker // Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1639*d9f75844SAndroid Build Coastguard Worker // callee only supports 1.0.
TEST_P(PeerConnectionIntegrationTest,CallerDtls12ToCalleeDtls10)1640*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
1641*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options caller_options;
1642*d9f75844SAndroid Build Coastguard Worker   caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1643*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options callee_options;
1644*d9f75844SAndroid Build Coastguard Worker   callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1645*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
1646*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1647*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1648*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
1649*d9f75844SAndroid Build Coastguard Worker   // direction.
1650*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1651*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1652*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1653*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1654*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1655*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
1656*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1657*d9f75844SAndroid Build Coastguard Worker }
1658*d9f75844SAndroid Build Coastguard Worker 
1659*d9f75844SAndroid Build Coastguard Worker // Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1660*d9f75844SAndroid Build Coastguard Worker // callee supports 1.2.
TEST_P(PeerConnectionIntegrationTest,CallerDtls10ToCalleeDtls12)1661*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
1662*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options caller_options;
1663*d9f75844SAndroid Build Coastguard Worker   caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1664*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options callee_options;
1665*d9f75844SAndroid Build Coastguard Worker   callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1666*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
1667*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1668*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1669*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
1670*d9f75844SAndroid Build Coastguard Worker   // direction.
1671*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1672*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1673*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1674*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1675*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1676*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
1677*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1678*d9f75844SAndroid Build Coastguard Worker }
1679*d9f75844SAndroid Build Coastguard Worker 
1680*d9f75844SAndroid Build Coastguard Worker // The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1681*d9f75844SAndroid Build Coastguard Worker // works as expected; the cipher should only be used if enabled by both sides.
TEST_P(PeerConnectionIntegrationTest,Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported)1682*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1683*d9f75844SAndroid Build Coastguard Worker        Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1684*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options caller_options;
1685*d9f75844SAndroid Build Coastguard Worker   caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
1686*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options callee_options;
1687*d9f75844SAndroid Build Coastguard Worker   callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1688*d9f75844SAndroid Build Coastguard Worker       false;
1689*d9f75844SAndroid Build Coastguard Worker   int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
1690*d9f75844SAndroid Build Coastguard Worker   TestNegotiatedCipherSuite(caller_options, callee_options,
1691*d9f75844SAndroid Build Coastguard Worker                             expected_cipher_suite);
1692*d9f75844SAndroid Build Coastguard Worker }
1693*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported)1694*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1695*d9f75844SAndroid Build Coastguard Worker        Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1696*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options caller_options;
1697*d9f75844SAndroid Build Coastguard Worker   caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1698*d9f75844SAndroid Build Coastguard Worker       false;
1699*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options callee_options;
1700*d9f75844SAndroid Build Coastguard Worker   callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
1701*d9f75844SAndroid Build Coastguard Worker   int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
1702*d9f75844SAndroid Build Coastguard Worker   TestNegotiatedCipherSuite(caller_options, callee_options,
1703*d9f75844SAndroid Build Coastguard Worker                             expected_cipher_suite);
1704*d9f75844SAndroid Build Coastguard Worker }
1705*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,Aes128Sha1_32_CipherUsedWhenSupported)1706*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1707*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options caller_options;
1708*d9f75844SAndroid Build Coastguard Worker   caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
1709*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options callee_options;
1710*d9f75844SAndroid Build Coastguard Worker   callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
1711*d9f75844SAndroid Build Coastguard Worker   int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
1712*d9f75844SAndroid Build Coastguard Worker   TestNegotiatedCipherSuite(caller_options, callee_options,
1713*d9f75844SAndroid Build Coastguard Worker                             expected_cipher_suite);
1714*d9f75844SAndroid Build Coastguard Worker }
1715*d9f75844SAndroid Build Coastguard Worker 
1716*d9f75844SAndroid Build Coastguard Worker // Test that a non-GCM cipher is used if both sides only support non-GCM.
TEST_P(PeerConnectionIntegrationTest,NonGcmCipherUsedWhenGcmNotSupported)1717*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
1718*d9f75844SAndroid Build Coastguard Worker   bool local_gcm_enabled = false;
1719*d9f75844SAndroid Build Coastguard Worker   bool remote_gcm_enabled = false;
1720*d9f75844SAndroid Build Coastguard Worker   bool aes_ctr_enabled = true;
1721*d9f75844SAndroid Build Coastguard Worker   int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1722*d9f75844SAndroid Build Coastguard Worker   TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
1723*d9f75844SAndroid Build Coastguard Worker                                     aes_ctr_enabled, expected_cipher_suite);
1724*d9f75844SAndroid Build Coastguard Worker }
1725*d9f75844SAndroid Build Coastguard Worker 
1726*d9f75844SAndroid Build Coastguard Worker // Test that a GCM cipher is used if both ends support it and non-GCM is
1727*d9f75844SAndroid Build Coastguard Worker // disabled.
TEST_P(PeerConnectionIntegrationTest,GcmCipherUsedWhenOnlyGcmSupported)1728*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
1729*d9f75844SAndroid Build Coastguard Worker   bool local_gcm_enabled = true;
1730*d9f75844SAndroid Build Coastguard Worker   bool remote_gcm_enabled = true;
1731*d9f75844SAndroid Build Coastguard Worker   bool aes_ctr_enabled = false;
1732*d9f75844SAndroid Build Coastguard Worker   int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1733*d9f75844SAndroid Build Coastguard Worker   TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
1734*d9f75844SAndroid Build Coastguard Worker                                     aes_ctr_enabled, expected_cipher_suite);
1735*d9f75844SAndroid Build Coastguard Worker }
1736*d9f75844SAndroid Build Coastguard Worker 
1737*d9f75844SAndroid Build Coastguard Worker // Verify that media can be transmitted end-to-end when GCM crypto suites are
1738*d9f75844SAndroid Build Coastguard Worker // enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1739*d9f75844SAndroid Build Coastguard Worker // only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1740*d9f75844SAndroid Build Coastguard Worker // works with it.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithGcmCipher)1741*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
1742*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactory::Options gcm_options;
1743*d9f75844SAndroid Build Coastguard Worker   gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
1744*d9f75844SAndroid Build Coastguard Worker   gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
1745*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
1746*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1747*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1748*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
1749*d9f75844SAndroid Build Coastguard Worker   // direction.
1750*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1751*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1752*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1753*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1754*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
1755*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
1756*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
1757*d9f75844SAndroid Build Coastguard Worker }
1758*d9f75844SAndroid Build Coastguard Worker 
1759*d9f75844SAndroid Build Coastguard Worker // Test that the ICE connection and gathering states eventually reach
1760*d9f75844SAndroid Build Coastguard Worker // "complete".
TEST_P(PeerConnectionIntegrationTest,IceStatesReachCompletion)1761*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
1762*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1763*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1764*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer.
1765*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1766*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1767*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1768*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1769*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1770*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1771*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1772*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1773*d9f75844SAndroid Build Coastguard Worker   // After the best candidate pair is selected and all candidates are signaled,
1774*d9f75844SAndroid Build Coastguard Worker   // the ICE connection state should reach "complete".
1775*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1776*d9f75844SAndroid Build Coastguard Worker   // answerer/"callee" by default) only reaches "connected". When this is
1777*d9f75844SAndroid Build Coastguard Worker   // fixed, this test should be updated.
1778*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1779*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kDefaultTimeout);
1780*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1781*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kDefaultTimeout);
1782*d9f75844SAndroid Build Coastguard Worker }
1783*d9f75844SAndroid Build Coastguard Worker 
1784*d9f75844SAndroid Build Coastguard Worker constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1785*d9f75844SAndroid Build Coastguard Worker                                 cricket::PORTALLOCATOR_DISABLE_RELAY |
1786*d9f75844SAndroid Build Coastguard Worker                                 cricket::PORTALLOCATOR_DISABLE_TCP;
1787*d9f75844SAndroid Build Coastguard Worker 
1788*d9f75844SAndroid Build Coastguard Worker // Use a mock resolver to resolve the hostname back to the original IP on both
1789*d9f75844SAndroid Build Coastguard Worker // sides and check that the ICE connection connects.
TEST_P(PeerConnectionIntegrationTest,IceStatesReachCompletionWithRemoteHostname)1790*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
1791*d9f75844SAndroid Build Coastguard Worker        IceStatesReachCompletionWithRemoteHostname) {
1792*d9f75844SAndroid Build Coastguard Worker   auto caller_resolver_factory =
1793*d9f75844SAndroid Build Coastguard Worker       std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
1794*d9f75844SAndroid Build Coastguard Worker   auto callee_resolver_factory =
1795*d9f75844SAndroid Build Coastguard Worker       std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
1796*d9f75844SAndroid Build Coastguard Worker   NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1797*d9f75844SAndroid Build Coastguard Worker   NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
1798*d9f75844SAndroid Build Coastguard Worker 
1799*d9f75844SAndroid Build Coastguard Worker   // This also verifies that the injected AsyncResolverFactory is used by
1800*d9f75844SAndroid Build Coastguard Worker   // P2PTransportChannel.
1801*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*caller_resolver_factory, Create())
1802*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(&caller_async_resolver));
1803*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionDependencies caller_deps(nullptr);
1804*d9f75844SAndroid Build Coastguard Worker   caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1805*d9f75844SAndroid Build Coastguard Worker 
1806*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*callee_resolver_factory, Create())
1807*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(&callee_async_resolver));
1808*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionDependencies callee_deps(nullptr);
1809*d9f75844SAndroid Build Coastguard Worker   callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1810*d9f75844SAndroid Build Coastguard Worker 
1811*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
1812*d9f75844SAndroid Build Coastguard Worker   config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1813*d9f75844SAndroid Build Coastguard Worker   config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1814*d9f75844SAndroid Build Coastguard Worker 
1815*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1816*d9f75844SAndroid Build Coastguard Worker       config, std::move(caller_deps), config, std::move(callee_deps)));
1817*d9f75844SAndroid Build Coastguard Worker 
1818*d9f75844SAndroid Build Coastguard Worker   caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1819*d9f75844SAndroid Build Coastguard Worker   callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1820*d9f75844SAndroid Build Coastguard Worker 
1821*d9f75844SAndroid Build Coastguard Worker   // Enable hostname candidates with mDNS names.
1822*d9f75844SAndroid Build Coastguard Worker   caller()->SetMdnsResponder(
1823*d9f75844SAndroid Build Coastguard Worker       std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
1824*d9f75844SAndroid Build Coastguard Worker   callee()->SetMdnsResponder(
1825*d9f75844SAndroid Build Coastguard Worker       std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
1826*d9f75844SAndroid Build Coastguard Worker 
1827*d9f75844SAndroid Build Coastguard Worker   SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
1828*d9f75844SAndroid Build Coastguard Worker 
1829*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1830*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1831*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1832*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1833*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1834*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1835*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kDefaultTimeout);
1836*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1837*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kDefaultTimeout);
1838*d9f75844SAndroid Build Coastguard Worker 
1839*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1840*d9f75844SAndroid Build Coastguard Worker                           "WebRTC.PeerConnection.CandidatePairType_UDP",
1841*d9f75844SAndroid Build Coastguard Worker                           webrtc::kIceCandidatePairHostNameHostName));
1842*d9f75844SAndroid Build Coastguard Worker   DestroyPeerConnections();
1843*d9f75844SAndroid Build Coastguard Worker }
1844*d9f75844SAndroid Build Coastguard Worker 
1845*d9f75844SAndroid Build Coastguard Worker // Test that firewalling the ICE connection causes the clients to identify the
1846*d9f75844SAndroid Build Coastguard Worker // disconnected state and then removing the firewall causes them to reconnect.
1847*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationIceStatesTest
1848*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionIntegrationBaseTest,
1849*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<
1850*d9f75844SAndroid Build Coastguard Worker           std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
1851*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionIntegrationIceStatesTest()1852*d9f75844SAndroid Build Coastguard Worker   PeerConnectionIntegrationIceStatesTest()
1853*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1854*d9f75844SAndroid Build Coastguard Worker     port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
1855*d9f75844SAndroid Build Coastguard Worker   }
1856*d9f75844SAndroid Build Coastguard Worker 
StartStunServer(const SocketAddress & server_address)1857*d9f75844SAndroid Build Coastguard Worker   void StartStunServer(const SocketAddress& server_address) {
1858*d9f75844SAndroid Build Coastguard Worker     stun_server_.reset(
1859*d9f75844SAndroid Build Coastguard Worker         cricket::TestStunServer::Create(firewall(), server_address));
1860*d9f75844SAndroid Build Coastguard Worker   }
1861*d9f75844SAndroid Build Coastguard Worker 
TestIPv6()1862*d9f75844SAndroid Build Coastguard Worker   bool TestIPv6() {
1863*d9f75844SAndroid Build Coastguard Worker     return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1864*d9f75844SAndroid Build Coastguard Worker   }
1865*d9f75844SAndroid Build Coastguard Worker 
SetPortAllocatorFlags()1866*d9f75844SAndroid Build Coastguard Worker   void SetPortAllocatorFlags() {
1867*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1868*d9f75844SAndroid Build Coastguard Worker         port_allocator_flags_, port_allocator_flags_);
1869*d9f75844SAndroid Build Coastguard Worker   }
1870*d9f75844SAndroid Build Coastguard Worker 
CallerAddresses()1871*d9f75844SAndroid Build Coastguard Worker   std::vector<SocketAddress> CallerAddresses() {
1872*d9f75844SAndroid Build Coastguard Worker     std::vector<SocketAddress> addresses;
1873*d9f75844SAndroid Build Coastguard Worker     addresses.push_back(SocketAddress("1.1.1.1", 0));
1874*d9f75844SAndroid Build Coastguard Worker     if (TestIPv6()) {
1875*d9f75844SAndroid Build Coastguard Worker       addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1876*d9f75844SAndroid Build Coastguard Worker     }
1877*d9f75844SAndroid Build Coastguard Worker     return addresses;
1878*d9f75844SAndroid Build Coastguard Worker   }
1879*d9f75844SAndroid Build Coastguard Worker 
CalleeAddresses()1880*d9f75844SAndroid Build Coastguard Worker   std::vector<SocketAddress> CalleeAddresses() {
1881*d9f75844SAndroid Build Coastguard Worker     std::vector<SocketAddress> addresses;
1882*d9f75844SAndroid Build Coastguard Worker     addresses.push_back(SocketAddress("2.2.2.2", 0));
1883*d9f75844SAndroid Build Coastguard Worker     if (TestIPv6()) {
1884*d9f75844SAndroid Build Coastguard Worker       addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1885*d9f75844SAndroid Build Coastguard Worker     }
1886*d9f75844SAndroid Build Coastguard Worker     return addresses;
1887*d9f75844SAndroid Build Coastguard Worker   }
1888*d9f75844SAndroid Build Coastguard Worker 
SetUpNetworkInterfaces()1889*d9f75844SAndroid Build Coastguard Worker   void SetUpNetworkInterfaces() {
1890*d9f75844SAndroid Build Coastguard Worker     // Remove the default interfaces added by the test infrastructure.
1891*d9f75844SAndroid Build Coastguard Worker     caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1892*d9f75844SAndroid Build Coastguard Worker     callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1893*d9f75844SAndroid Build Coastguard Worker 
1894*d9f75844SAndroid Build Coastguard Worker     // Add network addresses for test.
1895*d9f75844SAndroid Build Coastguard Worker     for (const auto& caller_address : CallerAddresses()) {
1896*d9f75844SAndroid Build Coastguard Worker       caller()->network_manager()->AddInterface(caller_address);
1897*d9f75844SAndroid Build Coastguard Worker     }
1898*d9f75844SAndroid Build Coastguard Worker     for (const auto& callee_address : CalleeAddresses()) {
1899*d9f75844SAndroid Build Coastguard Worker       callee()->network_manager()->AddInterface(callee_address);
1900*d9f75844SAndroid Build Coastguard Worker     }
1901*d9f75844SAndroid Build Coastguard Worker   }
1902*d9f75844SAndroid Build Coastguard Worker 
1903*d9f75844SAndroid Build Coastguard Worker  private:
1904*d9f75844SAndroid Build Coastguard Worker   uint32_t port_allocator_flags_;
1905*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<cricket::TestStunServer> stun_server_;
1906*d9f75844SAndroid Build Coastguard Worker };
1907*d9f75844SAndroid Build Coastguard Worker 
1908*d9f75844SAndroid Build Coastguard Worker // Ensure FakeClockForTest is constructed first (see class for rationale).
1909*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationIceStatesTestWithFakeClock
1910*d9f75844SAndroid Build Coastguard Worker     : public FakeClockForTest,
1911*d9f75844SAndroid Build Coastguard Worker       public PeerConnectionIntegrationIceStatesTest {};
1912*d9f75844SAndroid Build Coastguard Worker 
1913*d9f75844SAndroid Build Coastguard Worker #if !defined(THREAD_SANITIZER)
1914*d9f75844SAndroid Build Coastguard Worker // This test provokes TSAN errors. bugs.webrtc.org/11282
1915*d9f75844SAndroid Build Coastguard Worker 
1916*d9f75844SAndroid Build Coastguard Worker // Tests that if the connection doesn't get set up properly we eventually reach
1917*d9f75844SAndroid Build Coastguard Worker // the "failed" iceConnectionState.
TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,IceStateSetupFailure)1918*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1919*d9f75844SAndroid Build Coastguard Worker        IceStateSetupFailure) {
1920*d9f75844SAndroid Build Coastguard Worker   // Block connections to/from the caller and wait for ICE to become
1921*d9f75844SAndroid Build Coastguard Worker   // disconnected.
1922*d9f75844SAndroid Build Coastguard Worker   for (const auto& caller_address : CallerAddresses()) {
1923*d9f75844SAndroid Build Coastguard Worker     firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1924*d9f75844SAndroid Build Coastguard Worker   }
1925*d9f75844SAndroid Build Coastguard Worker 
1926*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1927*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1928*d9f75844SAndroid Build Coastguard Worker   SetPortAllocatorFlags();
1929*d9f75844SAndroid Build Coastguard Worker   SetUpNetworkInterfaces();
1930*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1931*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1932*d9f75844SAndroid Build Coastguard Worker 
1933*d9f75844SAndroid Build Coastguard Worker   // According to RFC7675, if there is no response within 30 seconds then the
1934*d9f75844SAndroid Build Coastguard Worker   // peer should consider the other side to have rejected the connection. This
1935*d9f75844SAndroid Build Coastguard Worker   // is signaled by the state transitioning to "failed".
1936*d9f75844SAndroid Build Coastguard Worker   constexpr int kConsentTimeout = 30000;
1937*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1938*d9f75844SAndroid Build Coastguard Worker                            caller()->standardized_ice_connection_state(),
1939*d9f75844SAndroid Build Coastguard Worker                            kConsentTimeout, FakeClock());
1940*d9f75844SAndroid Build Coastguard Worker }
1941*d9f75844SAndroid Build Coastguard Worker 
1942*d9f75844SAndroid Build Coastguard Worker #endif  // !defined(THREAD_SANITIZER)
1943*d9f75844SAndroid Build Coastguard Worker 
1944*d9f75844SAndroid Build Coastguard Worker // Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1945*d9f75844SAndroid Build Coastguard Worker // and that the statistics in the metric observers are updated correctly.
1946*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/12591): Flaky on Windows.
1947*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
1948*d9f75844SAndroid Build Coastguard Worker #define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1949*d9f75844SAndroid Build Coastguard Worker #else
1950*d9f75844SAndroid Build Coastguard Worker #define MAYBE_VerifyBestConnection VerifyBestConnection
1951*d9f75844SAndroid Build Coastguard Worker #endif
TEST_P(PeerConnectionIntegrationIceStatesTest,MAYBE_VerifyBestConnection)1952*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
1953*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
1954*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
1955*d9f75844SAndroid Build Coastguard Worker   SetPortAllocatorFlags();
1956*d9f75844SAndroid Build Coastguard Worker   SetUpNetworkInterfaces();
1957*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
1958*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
1959*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
1960*d9f75844SAndroid Build Coastguard Worker 
1961*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1962*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1963*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kDefaultTimeout);
1964*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1965*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kDefaultTimeout);
1966*d9f75844SAndroid Build Coastguard Worker 
1967*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/9456): Fix it.
1968*d9f75844SAndroid Build Coastguard Worker   const int num_best_ipv4 = webrtc::metrics::NumEvents(
1969*d9f75844SAndroid Build Coastguard Worker       "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1970*d9f75844SAndroid Build Coastguard Worker   const int num_best_ipv6 = webrtc::metrics::NumEvents(
1971*d9f75844SAndroid Build Coastguard Worker       "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
1972*d9f75844SAndroid Build Coastguard Worker   if (TestIPv6()) {
1973*d9f75844SAndroid Build Coastguard Worker     // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1974*d9f75844SAndroid Build Coastguard Worker     // connection.
1975*d9f75844SAndroid Build Coastguard Worker     EXPECT_METRIC_EQ(0, num_best_ipv4);
1976*d9f75844SAndroid Build Coastguard Worker     EXPECT_METRIC_EQ(1, num_best_ipv6);
1977*d9f75844SAndroid Build Coastguard Worker   } else {
1978*d9f75844SAndroid Build Coastguard Worker     EXPECT_METRIC_EQ(1, num_best_ipv4);
1979*d9f75844SAndroid Build Coastguard Worker     EXPECT_METRIC_EQ(0, num_best_ipv6);
1980*d9f75844SAndroid Build Coastguard Worker   }
1981*d9f75844SAndroid Build Coastguard Worker 
1982*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
1983*d9f75844SAndroid Build Coastguard Worker                           "WebRTC.PeerConnection.CandidatePairType_UDP",
1984*d9f75844SAndroid Build Coastguard Worker                           webrtc::kIceCandidatePairHostHost));
1985*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1986*d9f75844SAndroid Build Coastguard Worker                           "WebRTC.PeerConnection.CandidatePairType_UDP",
1987*d9f75844SAndroid Build Coastguard Worker                           webrtc::kIceCandidatePairHostPublicHostPublic));
1988*d9f75844SAndroid Build Coastguard Worker }
1989*d9f75844SAndroid Build Coastguard Worker 
1990*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
1991*d9f75844SAndroid Build Coastguard Worker                                       cricket::PORTALLOCATOR_DISABLE_STUN |
1992*d9f75844SAndroid Build Coastguard Worker                                       cricket::PORTALLOCATOR_DISABLE_RELAY;
1993*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kFlagsIPv6NoStun =
1994*d9f75844SAndroid Build Coastguard Worker     cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
1995*d9f75844SAndroid Build Coastguard Worker     cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
1996*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kFlagsIPv4Stun =
1997*d9f75844SAndroid Build Coastguard Worker     cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
1998*d9f75844SAndroid Build Coastguard Worker 
1999*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
2000*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTest,
2001*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationIceStatesTest,
2002*d9f75844SAndroid Build Coastguard Worker     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
2003*d9f75844SAndroid Build Coastguard Worker             Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2004*d9f75844SAndroid Build Coastguard Worker                    std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2005*d9f75844SAndroid Build Coastguard Worker                    std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2006*d9f75844SAndroid Build Coastguard Worker 
2007*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
2008*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTest,
2009*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationIceStatesTestWithFakeClock,
2010*d9f75844SAndroid Build Coastguard Worker     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
2011*d9f75844SAndroid Build Coastguard Worker             Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2012*d9f75844SAndroid Build Coastguard Worker                    std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2013*d9f75844SAndroid Build Coastguard Worker                    std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2014*d9f75844SAndroid Build Coastguard Worker 
2015*d9f75844SAndroid Build Coastguard Worker // This test sets up a call between two parties with audio and video.
2016*d9f75844SAndroid Build Coastguard Worker // During the call, the caller restarts ICE and the test verifies that
2017*d9f75844SAndroid Build Coastguard Worker // new ICE candidates are generated and audio and video still can flow, and the
2018*d9f75844SAndroid Build Coastguard Worker // ICE state reaches completed again.
TEST_P(PeerConnectionIntegrationTest,MediaContinuesFlowingAfterIceRestart)2019*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
2020*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2021*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2022*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for ICE to complete.
2023*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2024*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
2025*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2026*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2027*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2028*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kMaxWaitForFramesMs);
2029*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2030*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kMaxWaitForFramesMs);
2031*d9f75844SAndroid Build Coastguard Worker 
2032*d9f75844SAndroid Build Coastguard Worker   // To verify that the ICE restart actually occurs, get
2033*d9f75844SAndroid Build Coastguard Worker   // ufrag/password/candidates before and after restart.
2034*d9f75844SAndroid Build Coastguard Worker   // Create an SDP string of the first audio candidate for both clients.
2035*d9f75844SAndroid Build Coastguard Worker   const webrtc::IceCandidateCollection* audio_candidates_caller =
2036*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->local_description()->candidates(0);
2037*d9f75844SAndroid Build Coastguard Worker   const webrtc::IceCandidateCollection* audio_candidates_callee =
2038*d9f75844SAndroid Build Coastguard Worker       callee()->pc()->local_description()->candidates(0);
2039*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(audio_candidates_caller->count(), 0u);
2040*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(audio_candidates_callee->count(), 0u);
2041*d9f75844SAndroid Build Coastguard Worker   std::string caller_candidate_pre_restart;
2042*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2043*d9f75844SAndroid Build Coastguard Worker       audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2044*d9f75844SAndroid Build Coastguard Worker   std::string callee_candidate_pre_restart;
2045*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2046*d9f75844SAndroid Build Coastguard Worker       audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2047*d9f75844SAndroid Build Coastguard Worker   const cricket::SessionDescription* desc =
2048*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->local_description()->description();
2049*d9f75844SAndroid Build Coastguard Worker   std::string caller_ufrag_pre_restart =
2050*d9f75844SAndroid Build Coastguard Worker       desc->transport_infos()[0].description.ice_ufrag;
2051*d9f75844SAndroid Build Coastguard Worker   desc = callee()->pc()->local_description()->description();
2052*d9f75844SAndroid Build Coastguard Worker   std::string callee_ufrag_pre_restart =
2053*d9f75844SAndroid Build Coastguard Worker       desc->transport_infos()[0].description.ice_ufrag;
2054*d9f75844SAndroid Build Coastguard Worker 
2055*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
2056*d9f75844SAndroid Build Coastguard Worker   // Have the caller initiate an ICE restart.
2057*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2058*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2059*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2060*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2061*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kMaxWaitForFramesMs);
2062*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2063*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kMaxWaitForFramesMs);
2064*d9f75844SAndroid Build Coastguard Worker 
2065*d9f75844SAndroid Build Coastguard Worker   // Grab the ufrags/candidates again.
2066*d9f75844SAndroid Build Coastguard Worker   audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2067*d9f75844SAndroid Build Coastguard Worker   audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2068*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(audio_candidates_caller->count(), 0u);
2069*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(audio_candidates_callee->count(), 0u);
2070*d9f75844SAndroid Build Coastguard Worker   std::string caller_candidate_post_restart;
2071*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2072*d9f75844SAndroid Build Coastguard Worker       audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2073*d9f75844SAndroid Build Coastguard Worker   std::string callee_candidate_post_restart;
2074*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2075*d9f75844SAndroid Build Coastguard Worker       audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2076*d9f75844SAndroid Build Coastguard Worker   desc = caller()->pc()->local_description()->description();
2077*d9f75844SAndroid Build Coastguard Worker   std::string caller_ufrag_post_restart =
2078*d9f75844SAndroid Build Coastguard Worker       desc->transport_infos()[0].description.ice_ufrag;
2079*d9f75844SAndroid Build Coastguard Worker   desc = callee()->pc()->local_description()->description();
2080*d9f75844SAndroid Build Coastguard Worker   std::string callee_ufrag_post_restart =
2081*d9f75844SAndroid Build Coastguard Worker       desc->transport_infos()[0].description.ice_ufrag;
2082*d9f75844SAndroid Build Coastguard Worker   // Sanity check that an ICE restart was actually negotiated in SDP.
2083*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2084*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2085*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2086*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
2087*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
2088*d9f75844SAndroid Build Coastguard Worker 
2089*d9f75844SAndroid Build Coastguard Worker   // Ensure that additional frames are received after the ICE restart.
2090*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2091*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2092*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2093*d9f75844SAndroid Build Coastguard Worker }
2094*d9f75844SAndroid Build Coastguard Worker 
2095*d9f75844SAndroid Build Coastguard Worker // Verify that audio/video can be received end-to-end when ICE renomination is
2096*d9f75844SAndroid Build Coastguard Worker // enabled.
TEST_P(PeerConnectionIntegrationTest,EndToEndCallWithIceRenomination)2097*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
2098*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
2099*d9f75844SAndroid Build Coastguard Worker   config.enable_ice_renomination = true;
2100*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2101*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2102*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for some frames to be received in each
2103*d9f75844SAndroid Build Coastguard Worker   // direction.
2104*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2105*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
2106*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2107*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2108*d9f75844SAndroid Build Coastguard Worker   // Sanity check that ICE renomination was actually negotiated.
2109*d9f75844SAndroid Build Coastguard Worker   const cricket::SessionDescription* desc =
2110*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->local_description()->description();
2111*d9f75844SAndroid Build Coastguard Worker   for (const cricket::TransportInfo& info : desc->transport_infos()) {
2112*d9f75844SAndroid Build Coastguard Worker     ASSERT_THAT(info.description.transport_options, Contains("renomination"));
2113*d9f75844SAndroid Build Coastguard Worker   }
2114*d9f75844SAndroid Build Coastguard Worker   desc = callee()->pc()->local_description()->description();
2115*d9f75844SAndroid Build Coastguard Worker   for (const cricket::TransportInfo& info : desc->transport_infos()) {
2116*d9f75844SAndroid Build Coastguard Worker     ASSERT_THAT(info.description.transport_options, Contains("renomination"));
2117*d9f75844SAndroid Build Coastguard Worker   }
2118*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2119*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2120*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2121*d9f75844SAndroid Build Coastguard Worker }
2122*d9f75844SAndroid Build Coastguard Worker 
2123*d9f75844SAndroid Build Coastguard Worker // With a max bundle policy and RTCP muxing, adding a new media description to
2124*d9f75844SAndroid Build Coastguard Worker // the connection should not affect ICE at all because the new media will use
2125*d9f75844SAndroid Build Coastguard Worker // the existing connection.
2126*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/12538): Fails on tsan.
2127*d9f75844SAndroid Build Coastguard Worker #if defined(THREAD_SANITIZER)
2128*d9f75844SAndroid Build Coastguard Worker #define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2129*d9f75844SAndroid Build Coastguard Worker   DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2130*d9f75844SAndroid Build Coastguard Worker #else
2131*d9f75844SAndroid Build Coastguard Worker #define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2132*d9f75844SAndroid Build Coastguard Worker   AddMediaToConnectedBundleDoesNotRestartIce
2133*d9f75844SAndroid Build Coastguard Worker #endif
TEST_P(PeerConnectionIntegrationTest,MAYBE_AddMediaToConnectedBundleDoesNotRestartIce)2134*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
2135*d9f75844SAndroid Build Coastguard Worker        MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
2136*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
2137*d9f75844SAndroid Build Coastguard Worker   config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2138*d9f75844SAndroid Build Coastguard Worker   config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2139*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2140*d9f75844SAndroid Build Coastguard Worker       config, PeerConnectionInterface::RTCConfiguration()));
2141*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2142*d9f75844SAndroid Build Coastguard Worker 
2143*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2144*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2145*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2146*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2147*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kDefaultTimeout);
2148*d9f75844SAndroid Build Coastguard Worker 
2149*d9f75844SAndroid Build Coastguard Worker   caller()->clear_ice_connection_state_history();
2150*d9f75844SAndroid Build Coastguard Worker 
2151*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
2152*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2153*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2154*d9f75844SAndroid Build Coastguard Worker 
2155*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2156*d9f75844SAndroid Build Coastguard Worker }
2157*d9f75844SAndroid Build Coastguard Worker 
2158*d9f75844SAndroid Build Coastguard Worker // This test sets up a call between two parties with audio and video. It then
2159*d9f75844SAndroid Build Coastguard Worker // renegotiates setting the video m-line to "port 0", then later renegotiates
2160*d9f75844SAndroid Build Coastguard Worker // again, enabling video.
TEST_P(PeerConnectionIntegrationTest,VideoFlowsAfterMediaSectionIsRejectedAndRecycled)2161*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
2162*d9f75844SAndroid Build Coastguard Worker        VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2163*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2164*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2165*d9f75844SAndroid Build Coastguard Worker 
2166*d9f75844SAndroid Build Coastguard Worker   // Do initial negotiation, only sending media from the caller. Will result in
2167*d9f75844SAndroid Build Coastguard Worker   // video and audio recvonly "m=" sections.
2168*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2169*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2170*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2171*d9f75844SAndroid Build Coastguard Worker 
2172*d9f75844SAndroid Build Coastguard Worker   // Negotiate again, disabling the video "m=" section (the callee will set the
2173*d9f75844SAndroid Build Coastguard Worker   // port to 0 due to offer_to_receive_video = 0).
2174*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
2175*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
2176*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_video = 0;
2177*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
2178*d9f75844SAndroid Build Coastguard Worker   } else {
2179*d9f75844SAndroid Build Coastguard Worker     callee()->SetRemoteOfferHandler([this] {
2180*d9f75844SAndroid Build Coastguard Worker       callee()
2181*d9f75844SAndroid Build Coastguard Worker           ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2182*d9f75844SAndroid Build Coastguard Worker           ->StopInternal();
2183*d9f75844SAndroid Build Coastguard Worker     });
2184*d9f75844SAndroid Build Coastguard Worker   }
2185*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2186*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2187*d9f75844SAndroid Build Coastguard Worker   // Sanity check that video "m=" section was actually rejected.
2188*d9f75844SAndroid Build Coastguard Worker   const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2189*d9f75844SAndroid Build Coastguard Worker       callee()->pc()->local_description()->description());
2190*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, answer_video_content);
2191*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer_video_content->rejected);
2192*d9f75844SAndroid Build Coastguard Worker 
2193*d9f75844SAndroid Build Coastguard Worker   // Enable video and do negotiation again, making sure video is received
2194*d9f75844SAndroid Build Coastguard Worker   // end-to-end, also adding media stream to callee.
2195*d9f75844SAndroid Build Coastguard Worker   if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
2196*d9f75844SAndroid Build Coastguard Worker     PeerConnectionInterface::RTCOfferAnswerOptions options;
2197*d9f75844SAndroid Build Coastguard Worker     options.offer_to_receive_video = 1;
2198*d9f75844SAndroid Build Coastguard Worker     callee()->SetOfferAnswerOptions(options);
2199*d9f75844SAndroid Build Coastguard Worker   } else {
2200*d9f75844SAndroid Build Coastguard Worker     // The caller's transceiver is stopped, so we need to add another track.
2201*d9f75844SAndroid Build Coastguard Worker     auto caller_transceiver =
2202*d9f75844SAndroid Build Coastguard Worker         caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
2203*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, caller_transceiver.get());
2204*d9f75844SAndroid Build Coastguard Worker     caller()->AddVideoTrack();
2205*d9f75844SAndroid Build Coastguard Worker   }
2206*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
2207*d9f75844SAndroid Build Coastguard Worker   callee()->SetRemoteOfferHandler(nullptr);
2208*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2209*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2210*d9f75844SAndroid Build Coastguard Worker 
2211*d9f75844SAndroid Build Coastguard Worker   // Verify the caller receives frames from the newly added stream, and the
2212*d9f75844SAndroid Build Coastguard Worker   // callee receives additional frames from the re-enabled video m= section.
2213*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2214*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio();
2215*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
2216*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2217*d9f75844SAndroid Build Coastguard Worker }
2218*d9f75844SAndroid Build Coastguard Worker 
2219*d9f75844SAndroid Build Coastguard Worker // This tests that if we negotiate after calling CreateSender but before we
2220*d9f75844SAndroid Build Coastguard Worker // have a track, then set a track later, frames from the newly-set track are
2221*d9f75844SAndroid Build Coastguard Worker // received end-to-end.
TEST_F(PeerConnectionIntegrationTestPlanB,MediaFlowsAfterEarlyWarmupWithCreateSender)2222*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestPlanB,
2223*d9f75844SAndroid Build Coastguard Worker        MediaFlowsAfterEarlyWarmupWithCreateSender) {
2224*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2225*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2226*d9f75844SAndroid Build Coastguard Worker   auto caller_audio_sender =
2227*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->CreateSender("audio", "caller_stream");
2228*d9f75844SAndroid Build Coastguard Worker   auto caller_video_sender =
2229*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->CreateSender("video", "caller_stream");
2230*d9f75844SAndroid Build Coastguard Worker   auto callee_audio_sender =
2231*d9f75844SAndroid Build Coastguard Worker       callee()->pc()->CreateSender("audio", "callee_stream");
2232*d9f75844SAndroid Build Coastguard Worker   auto callee_video_sender =
2233*d9f75844SAndroid Build Coastguard Worker       callee()->pc()->CreateSender("video", "callee_stream");
2234*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2235*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2236*d9f75844SAndroid Build Coastguard Worker   // Wait for ICE to complete, without any tracks being set.
2237*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2238*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kMaxWaitForFramesMs);
2239*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2240*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kMaxWaitForFramesMs);
2241*d9f75844SAndroid Build Coastguard Worker   // Now set the tracks, and expect frames to immediately start flowing.
2242*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
2243*d9f75844SAndroid Build Coastguard Worker       caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2244*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
2245*d9f75844SAndroid Build Coastguard Worker       caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2246*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
2247*d9f75844SAndroid Build Coastguard Worker       callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2248*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
2249*d9f75844SAndroid Build Coastguard Worker       callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
2250*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2251*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2252*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2253*d9f75844SAndroid Build Coastguard Worker }
2254*d9f75844SAndroid Build Coastguard Worker 
2255*d9f75844SAndroid Build Coastguard Worker // This tests that if we negotiate after calling AddTransceiver but before we
2256*d9f75844SAndroid Build Coastguard Worker // have a track, then set a track later, frames from the newly-set tracks are
2257*d9f75844SAndroid Build Coastguard Worker // received end-to-end.
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,MediaFlowsAfterEarlyWarmupWithAddTransceiver)2258*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2259*d9f75844SAndroid Build Coastguard Worker        MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2260*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2261*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2262*d9f75844SAndroid Build Coastguard Worker   auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2263*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2264*d9f75844SAndroid Build Coastguard Worker   auto caller_audio_sender = audio_result.MoveValue()->sender();
2265*d9f75844SAndroid Build Coastguard Worker   auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2266*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2267*d9f75844SAndroid Build Coastguard Worker   auto caller_video_sender = video_result.MoveValue()->sender();
2268*d9f75844SAndroid Build Coastguard Worker   callee()->SetRemoteOfferHandler([this] {
2269*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
2270*d9f75844SAndroid Build Coastguard Worker     callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
2271*d9f75844SAndroid Build Coastguard Worker         RtpTransceiverDirection::kSendRecv);
2272*d9f75844SAndroid Build Coastguard Worker     callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
2273*d9f75844SAndroid Build Coastguard Worker         RtpTransceiverDirection::kSendRecv);
2274*d9f75844SAndroid Build Coastguard Worker   });
2275*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2276*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2277*d9f75844SAndroid Build Coastguard Worker   // Wait for ICE to complete, without any tracks being set.
2278*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2279*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kMaxWaitForFramesMs);
2280*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2281*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kMaxWaitForFramesMs);
2282*d9f75844SAndroid Build Coastguard Worker   // Now set the tracks, and expect frames to immediately start flowing.
2283*d9f75844SAndroid Build Coastguard Worker   auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2284*d9f75844SAndroid Build Coastguard Worker   auto callee_video_sender = callee()->pc()->GetSenders()[1];
2285*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2286*d9f75844SAndroid Build Coastguard Worker       caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2287*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2288*d9f75844SAndroid Build Coastguard Worker       caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2289*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2290*d9f75844SAndroid Build Coastguard Worker       callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2291*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2292*d9f75844SAndroid Build Coastguard Worker       callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
2293*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2294*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2295*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2296*d9f75844SAndroid Build Coastguard Worker }
2297*d9f75844SAndroid Build Coastguard Worker 
2298*d9f75844SAndroid Build Coastguard Worker // This test verifies that a remote video track can be added via AddStream,
2299*d9f75844SAndroid Build Coastguard Worker // and sent end-to-end. For this particular test, it's simply echoed back
2300*d9f75844SAndroid Build Coastguard Worker // from the caller to the callee, rather than being forwarded to a third
2301*d9f75844SAndroid Build Coastguard Worker // PeerConnection.
TEST_F(PeerConnectionIntegrationTestPlanB,CanSendRemoteVideoTrack)2302*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
2303*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2304*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2305*d9f75844SAndroid Build Coastguard Worker   // Just send a video track from the caller.
2306*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
2307*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2308*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2309*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1U, callee()->remote_streams()->count());
2310*d9f75844SAndroid Build Coastguard Worker 
2311*d9f75844SAndroid Build Coastguard Worker   // Echo the stream back, and do a new offer/anwer (initiated by callee this
2312*d9f75844SAndroid Build Coastguard Worker   // time).
2313*d9f75844SAndroid Build Coastguard Worker   callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2314*d9f75844SAndroid Build Coastguard Worker   callee()->CreateAndSetAndSignalOffer();
2315*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2316*d9f75844SAndroid Build Coastguard Worker 
2317*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2318*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalVideo();
2319*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2320*d9f75844SAndroid Build Coastguard Worker }
2321*d9f75844SAndroid Build Coastguard Worker 
2322*d9f75844SAndroid Build Coastguard Worker #if !defined(THREAD_SANITIZER)
2323*d9f75844SAndroid Build Coastguard Worker // This test provokes TSAN errors. bugs.webrtc.org/11282
2324*d9f75844SAndroid Build Coastguard Worker 
2325*d9f75844SAndroid Build Coastguard Worker // Test that we achieve the expected end-to-end connection time, using a
2326*d9f75844SAndroid Build Coastguard Worker // fake clock and simulated latency on the media and signaling paths.
2327*d9f75844SAndroid Build Coastguard Worker // We use a TURN<->TURN connection because this is usually the quickest to
2328*d9f75844SAndroid Build Coastguard Worker // set up initially, especially when we're confident the connection will work
2329*d9f75844SAndroid Build Coastguard Worker // and can start sending media before we get a STUN response.
2330*d9f75844SAndroid Build Coastguard Worker //
2331*d9f75844SAndroid Build Coastguard Worker // With various optimizations enabled, here are the network delays we expect to
2332*d9f75844SAndroid Build Coastguard Worker // be on the critical path:
2333*d9f75844SAndroid Build Coastguard Worker // 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2334*d9f75844SAndroid Build Coastguard Worker //                       signaling answer (with DTLS fingerprint).
2335*d9f75844SAndroid Build Coastguard Worker // 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2336*d9f75844SAndroid Build Coastguard Worker //                  using TURN<->TURN pair, and DTLS exchange is 4 packets,
2337*d9f75844SAndroid Build Coastguard Worker //                  the first of which should have arrived before the answer.
TEST_P(PeerConnectionIntegrationTestWithFakeClock,EndToEndConnectionTimeWithTurnTurnPair)2338*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2339*d9f75844SAndroid Build Coastguard Worker        EndToEndConnectionTimeWithTurnTurnPair) {
2340*d9f75844SAndroid Build Coastguard Worker   static constexpr int media_hop_delay_ms = 50;
2341*d9f75844SAndroid Build Coastguard Worker   static constexpr int signaling_trip_delay_ms = 500;
2342*d9f75844SAndroid Build Coastguard Worker   // For explanation of these values, see comment above.
2343*d9f75844SAndroid Build Coastguard Worker   static constexpr int required_media_hops = 9;
2344*d9f75844SAndroid Build Coastguard Worker   static constexpr int required_signaling_trips = 2;
2345*d9f75844SAndroid Build Coastguard Worker   // For internal delays (such as posting an event asychronously).
2346*d9f75844SAndroid Build Coastguard Worker   static constexpr int allowed_internal_delay_ms = 20;
2347*d9f75844SAndroid Build Coastguard Worker   static constexpr int total_connection_time_ms =
2348*d9f75844SAndroid Build Coastguard Worker       media_hop_delay_ms * required_media_hops +
2349*d9f75844SAndroid Build Coastguard Worker       signaling_trip_delay_ms * required_signaling_trips +
2350*d9f75844SAndroid Build Coastguard Worker       allowed_internal_delay_ms;
2351*d9f75844SAndroid Build Coastguard Worker 
2352*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2353*d9f75844SAndroid Build Coastguard Worker                                                                  3478};
2354*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2355*d9f75844SAndroid Build Coastguard Worker                                                                  0};
2356*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2357*d9f75844SAndroid Build Coastguard Worker                                                                  3478};
2358*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2359*d9f75844SAndroid Build Coastguard Worker                                                                  0};
2360*d9f75844SAndroid Build Coastguard Worker   cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2361*d9f75844SAndroid Build Coastguard Worker       turn_server_1_internal_address, turn_server_1_external_address);
2362*d9f75844SAndroid Build Coastguard Worker 
2363*d9f75844SAndroid Build Coastguard Worker   cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2364*d9f75844SAndroid Build Coastguard Worker       turn_server_2_internal_address, turn_server_2_external_address);
2365*d9f75844SAndroid Build Coastguard Worker   // Bypass permission check on received packets so media can be sent before
2366*d9f75844SAndroid Build Coastguard Worker   // the candidate is signaled.
2367*d9f75844SAndroid Build Coastguard Worker   SendTask(network_thread(), [turn_server_1] {
2368*d9f75844SAndroid Build Coastguard Worker     turn_server_1->set_enable_permission_checks(false);
2369*d9f75844SAndroid Build Coastguard Worker   });
2370*d9f75844SAndroid Build Coastguard Worker   SendTask(network_thread(), [turn_server_2] {
2371*d9f75844SAndroid Build Coastguard Worker     turn_server_2->set_enable_permission_checks(false);
2372*d9f75844SAndroid Build Coastguard Worker   });
2373*d9f75844SAndroid Build Coastguard Worker 
2374*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
2375*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server_1;
2376*d9f75844SAndroid Build Coastguard Worker   ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2377*d9f75844SAndroid Build Coastguard Worker   ice_server_1.username = "test";
2378*d9f75844SAndroid Build Coastguard Worker   ice_server_1.password = "test";
2379*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server_1);
2380*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2381*d9f75844SAndroid Build Coastguard Worker   client_1_config.presume_writable_when_fully_relayed = true;
2382*d9f75844SAndroid Build Coastguard Worker 
2383*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
2384*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server_2;
2385*d9f75844SAndroid Build Coastguard Worker   ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2386*d9f75844SAndroid Build Coastguard Worker   ice_server_2.username = "test";
2387*d9f75844SAndroid Build Coastguard Worker   ice_server_2.password = "test";
2388*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server_2);
2389*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2390*d9f75844SAndroid Build Coastguard Worker   client_2_config.presume_writable_when_fully_relayed = true;
2391*d9f75844SAndroid Build Coastguard Worker 
2392*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2393*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2394*d9f75844SAndroid Build Coastguard Worker   // Set up the simulated delays.
2395*d9f75844SAndroid Build Coastguard Worker   SetSignalingDelayMs(signaling_trip_delay_ms);
2396*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2397*d9f75844SAndroid Build Coastguard Worker   virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2398*d9f75844SAndroid Build Coastguard Worker   virtual_socket_server()->UpdateDelayDistribution();
2399*d9f75844SAndroid Build Coastguard Worker 
2400*d9f75844SAndroid Build Coastguard Worker   // Set "offer to receive audio/video" without adding any tracks, so we just
2401*d9f75844SAndroid Build Coastguard Worker   // set up ICE/DTLS with no media.
2402*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
2403*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio = 1;
2404*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_video = 1;
2405*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
2406*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2407*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
2408*d9f75844SAndroid Build Coastguard Worker                              FakeClock());
2409*d9f75844SAndroid Build Coastguard Worker   // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2410*d9f75844SAndroid Build Coastguard Worker   // If this is not done a DCHECK can be hit in ports.cc, because a large
2411*d9f75844SAndroid Build Coastguard Worker   // negative number is calculated for the rtt due to the global clock changing.
2412*d9f75844SAndroid Build Coastguard Worker   ClosePeerConnections();
2413*d9f75844SAndroid Build Coastguard Worker }
2414*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTestWithFakeClock,OnIceCandidateFlushesGetStatsCache)2415*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2416*d9f75844SAndroid Build Coastguard Worker        OnIceCandidateFlushesGetStatsCache) {
2417*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2418*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2419*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2420*d9f75844SAndroid Build Coastguard Worker 
2421*d9f75844SAndroid Build Coastguard Worker   // Call getStats, assert there are no candidates.
2422*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2423*d9f75844SAndroid Build Coastguard Worker       caller()->NewGetStats();
2424*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(first_report);
2425*d9f75844SAndroid Build Coastguard Worker   auto first_candidate_stats =
2426*d9f75844SAndroid Build Coastguard Worker       first_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2427*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(first_candidate_stats.size(), 0u);
2428*d9f75844SAndroid Build Coastguard Worker 
2429*d9f75844SAndroid Build Coastguard Worker   // Create an offer at the caller and set it as remote description on the
2430*d9f75844SAndroid Build Coastguard Worker   // callee.
2431*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2432*d9f75844SAndroid Build Coastguard Worker   // Call getStats again, assert there are candidates now.
2433*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2434*d9f75844SAndroid Build Coastguard Worker       caller()->NewGetStats();
2435*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(second_report);
2436*d9f75844SAndroid Build Coastguard Worker   auto second_candidate_stats =
2437*d9f75844SAndroid Build Coastguard Worker       second_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2438*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(second_candidate_stats.size(), 0u);
2439*d9f75844SAndroid Build Coastguard Worker 
2440*d9f75844SAndroid Build Coastguard Worker   // The fake clock ensures that no time has passed so the cache must have been
2441*d9f75844SAndroid Build Coastguard Worker   // explicitly invalidated.
2442*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2443*d9f75844SAndroid Build Coastguard Worker }
2444*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTestWithFakeClock,AddIceCandidateFlushesGetStatsCache)2445*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2446*d9f75844SAndroid Build Coastguard Worker        AddIceCandidateFlushesGetStatsCache) {
2447*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2448*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignalingForSdpOnly();
2449*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2450*d9f75844SAndroid Build Coastguard Worker 
2451*d9f75844SAndroid Build Coastguard Worker   // Start candidate gathering and wait for it to complete. Candidates are not
2452*d9f75844SAndroid Build Coastguard Worker   // signalled.
2453*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2454*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_SIMULATED_WAIT(caller()->IceGatheringStateComplete(),
2455*d9f75844SAndroid Build Coastguard Worker                              kDefaultTimeout, FakeClock());
2456*d9f75844SAndroid Build Coastguard Worker 
2457*d9f75844SAndroid Build Coastguard Worker   // Call getStats, assert there are no candidates.
2458*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2459*d9f75844SAndroid Build Coastguard Worker       caller()->NewGetStats();
2460*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(first_report);
2461*d9f75844SAndroid Build Coastguard Worker   auto first_candidate_stats =
2462*d9f75844SAndroid Build Coastguard Worker       first_report->GetStatsOfType<webrtc::RTCRemoteIceCandidateStats>();
2463*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(first_candidate_stats.size(), 0u);
2464*d9f75844SAndroid Build Coastguard Worker 
2465*d9f75844SAndroid Build Coastguard Worker   // Add a "fake" candidate.
2466*d9f75844SAndroid Build Coastguard Worker   absl::optional<RTCError> result;
2467*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->AddIceCandidate(
2468*d9f75844SAndroid Build Coastguard Worker       absl::WrapUnique(webrtc::CreateIceCandidate(
2469*d9f75844SAndroid Build Coastguard Worker           "", 0,
2470*d9f75844SAndroid Build Coastguard Worker           "candidate:2214029314 1 udp 2122260223 127.0.0.1 49152 typ host",
2471*d9f75844SAndroid Build Coastguard Worker           nullptr)),
2472*d9f75844SAndroid Build Coastguard Worker       [&result](RTCError r) { result = r; });
2473*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(result.has_value(), kDefaultTimeout);
2474*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(result.value().ok());
2475*d9f75844SAndroid Build Coastguard Worker 
2476*d9f75844SAndroid Build Coastguard Worker   // Call getStats again, assert there is a remote candidate now.
2477*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2478*d9f75844SAndroid Build Coastguard Worker       caller()->NewGetStats();
2479*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(second_report);
2480*d9f75844SAndroid Build Coastguard Worker   auto second_candidate_stats =
2481*d9f75844SAndroid Build Coastguard Worker       second_report->GetStatsOfType<webrtc::RTCRemoteIceCandidateStats>();
2482*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(second_candidate_stats.size(), 1u);
2483*d9f75844SAndroid Build Coastguard Worker 
2484*d9f75844SAndroid Build Coastguard Worker   // The fake clock ensures that no time has passed so the cache must have been
2485*d9f75844SAndroid Build Coastguard Worker   // explicitly invalidated.
2486*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2487*d9f75844SAndroid Build Coastguard Worker }
2488*d9f75844SAndroid Build Coastguard Worker 
2489*d9f75844SAndroid Build Coastguard Worker #endif  // !defined(THREAD_SANITIZER)
2490*d9f75844SAndroid Build Coastguard Worker 
2491*d9f75844SAndroid Build Coastguard Worker // Verify that a TurnCustomizer passed in through RTCConfiguration
2492*d9f75844SAndroid Build Coastguard Worker // is actually used by the underlying TURN candidate pair.
2493*d9f75844SAndroid Build Coastguard Worker // Note that turnport_unittest.cc contains more detailed, lower-level tests.
TEST_P(PeerConnectionIntegrationTest,TurnCustomizerUsedForTurnConnections)2494*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
2495*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2496*d9f75844SAndroid Build Coastguard Worker                                                                  3478};
2497*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2498*d9f75844SAndroid Build Coastguard Worker                                                                  0};
2499*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2500*d9f75844SAndroid Build Coastguard Worker                                                                  3478};
2501*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2502*d9f75844SAndroid Build Coastguard Worker                                                                  0};
2503*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(turn_server_1_internal_address,
2504*d9f75844SAndroid Build Coastguard Worker                    turn_server_1_external_address);
2505*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(turn_server_2_internal_address,
2506*d9f75844SAndroid Build Coastguard Worker                    turn_server_2_external_address);
2507*d9f75844SAndroid Build Coastguard Worker 
2508*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
2509*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server_1;
2510*d9f75844SAndroid Build Coastguard Worker   ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2511*d9f75844SAndroid Build Coastguard Worker   ice_server_1.username = "test";
2512*d9f75844SAndroid Build Coastguard Worker   ice_server_1.password = "test";
2513*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server_1);
2514*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2515*d9f75844SAndroid Build Coastguard Worker   auto* customizer1 = CreateTurnCustomizer();
2516*d9f75844SAndroid Build Coastguard Worker   client_1_config.turn_customizer = customizer1;
2517*d9f75844SAndroid Build Coastguard Worker 
2518*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
2519*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server_2;
2520*d9f75844SAndroid Build Coastguard Worker   ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2521*d9f75844SAndroid Build Coastguard Worker   ice_server_2.username = "test";
2522*d9f75844SAndroid Build Coastguard Worker   ice_server_2.password = "test";
2523*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server_2);
2524*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2525*d9f75844SAndroid Build Coastguard Worker   auto* customizer2 = CreateTurnCustomizer();
2526*d9f75844SAndroid Build Coastguard Worker   client_2_config.turn_customizer = customizer2;
2527*d9f75844SAndroid Build Coastguard Worker 
2528*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2529*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2530*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2531*d9f75844SAndroid Build Coastguard Worker 
2532*d9f75844SAndroid Build Coastguard Worker   // Set "offer to receive audio/video" without adding any tracks, so we just
2533*d9f75844SAndroid Build Coastguard Worker   // set up ICE/DTLS with no media.
2534*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
2535*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio = 1;
2536*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_video = 1;
2537*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
2538*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2539*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2540*d9f75844SAndroid Build Coastguard Worker 
2541*d9f75844SAndroid Build Coastguard Worker   ExpectTurnCustomizerCountersIncremented(customizer1);
2542*d9f75844SAndroid Build Coastguard Worker   ExpectTurnCustomizerCountersIncremented(customizer2);
2543*d9f75844SAndroid Build Coastguard Worker }
2544*d9f75844SAndroid Build Coastguard Worker 
2545*d9f75844SAndroid Build Coastguard Worker // Verifies that you can use TCP instead of UDP to connect to a TURN server and
2546*d9f75844SAndroid Build Coastguard Worker // send media between the caller and the callee.
TEST_P(PeerConnectionIntegrationTest,TCPUsedForTurnConnections)2547*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2548*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2549*d9f75844SAndroid Build Coastguard Worker                                                                3478};
2550*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2551*d9f75844SAndroid Build Coastguard Worker 
2552*d9f75844SAndroid Build Coastguard Worker   // Enable TCP for the fake turn server.
2553*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2554*d9f75844SAndroid Build Coastguard Worker                    cricket::PROTO_TCP);
2555*d9f75844SAndroid Build Coastguard Worker 
2556*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server;
2557*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2558*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
2559*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
2560*d9f75844SAndroid Build Coastguard Worker 
2561*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
2562*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server);
2563*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2564*d9f75844SAndroid Build Coastguard Worker 
2565*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
2566*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server);
2567*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2568*d9f75844SAndroid Build Coastguard Worker 
2569*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
2570*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2571*d9f75844SAndroid Build Coastguard Worker 
2572*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for ICE to complete.
2573*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2574*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2575*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
2576*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2577*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2578*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2579*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kMaxWaitForFramesMs);
2580*d9f75844SAndroid Build Coastguard Worker 
2581*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2582*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2583*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
2584*d9f75844SAndroid Build Coastguard Worker }
2585*d9f75844SAndroid Build Coastguard Worker 
2586*d9f75844SAndroid Build Coastguard Worker // Verify that a SSLCertificateVerifier passed in through
2587*d9f75844SAndroid Build Coastguard Worker // PeerConnectionDependencies is actually used by the underlying SSL
2588*d9f75844SAndroid Build Coastguard Worker // implementation to determine whether a certificate presented by the TURN
2589*d9f75844SAndroid Build Coastguard Worker // server is accepted by the client. Note that openssladapter_unittest.cc
2590*d9f75844SAndroid Build Coastguard Worker // contains more detailed, lower-level tests.
TEST_P(PeerConnectionIntegrationTest,SSLCertificateVerifierUsedForTurnConnections)2591*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
2592*d9f75844SAndroid Build Coastguard Worker        SSLCertificateVerifierUsedForTurnConnections) {
2593*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2594*d9f75844SAndroid Build Coastguard Worker                                                                3478};
2595*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2596*d9f75844SAndroid Build Coastguard Worker 
2597*d9f75844SAndroid Build Coastguard Worker   // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2598*d9f75844SAndroid Build Coastguard Worker   // that host name verification passes on the fake certificate.
2599*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2600*d9f75844SAndroid Build Coastguard Worker                    cricket::PROTO_TLS, "88.88.88.0");
2601*d9f75844SAndroid Build Coastguard Worker 
2602*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server;
2603*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2604*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
2605*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
2606*d9f75844SAndroid Build Coastguard Worker 
2607*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_1_config;
2608*d9f75844SAndroid Build Coastguard Worker   client_1_config.servers.push_back(ice_server);
2609*d9f75844SAndroid Build Coastguard Worker   client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2610*d9f75844SAndroid Build Coastguard Worker 
2611*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration client_2_config;
2612*d9f75844SAndroid Build Coastguard Worker   client_2_config.servers.push_back(ice_server);
2613*d9f75844SAndroid Build Coastguard Worker   // Setting the type to kRelay forces the connection to go through a TURN
2614*d9f75844SAndroid Build Coastguard Worker   // server.
2615*d9f75844SAndroid Build Coastguard Worker   client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2616*d9f75844SAndroid Build Coastguard Worker 
2617*d9f75844SAndroid Build Coastguard Worker   // Get a copy to the pointer so we can verify calls later.
2618*d9f75844SAndroid Build Coastguard Worker   rtc::TestCertificateVerifier* client_1_cert_verifier =
2619*d9f75844SAndroid Build Coastguard Worker       new rtc::TestCertificateVerifier();
2620*d9f75844SAndroid Build Coastguard Worker   client_1_cert_verifier->verify_certificate_ = true;
2621*d9f75844SAndroid Build Coastguard Worker   rtc::TestCertificateVerifier* client_2_cert_verifier =
2622*d9f75844SAndroid Build Coastguard Worker       new rtc::TestCertificateVerifier();
2623*d9f75844SAndroid Build Coastguard Worker   client_2_cert_verifier->verify_certificate_ = true;
2624*d9f75844SAndroid Build Coastguard Worker 
2625*d9f75844SAndroid Build Coastguard Worker   // Create the dependencies with the test certificate verifier.
2626*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2627*d9f75844SAndroid Build Coastguard Worker   client_1_deps.tls_cert_verifier =
2628*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2629*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2630*d9f75844SAndroid Build Coastguard Worker   client_2_deps.tls_cert_verifier =
2631*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2632*d9f75844SAndroid Build Coastguard Worker 
2633*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2634*d9f75844SAndroid Build Coastguard Worker       client_1_config, std::move(client_1_deps), client_2_config,
2635*d9f75844SAndroid Build Coastguard Worker       std::move(client_2_deps)));
2636*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2637*d9f75844SAndroid Build Coastguard Worker 
2638*d9f75844SAndroid Build Coastguard Worker   // Set "offer to receive audio/video" without adding any tracks, so we just
2639*d9f75844SAndroid Build Coastguard Worker   // set up ICE/DTLS with no media.
2640*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
2641*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio = 1;
2642*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_video = 1;
2643*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
2644*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2645*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2646*d9f75844SAndroid Build Coastguard Worker 
2647*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2648*d9f75844SAndroid Build Coastguard Worker   EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
2649*d9f75844SAndroid Build Coastguard Worker }
2650*d9f75844SAndroid Build Coastguard Worker 
2651*d9f75844SAndroid Build Coastguard Worker // Test that the injected ICE transport factory is used to create ICE transports
2652*d9f75844SAndroid Build Coastguard Worker // for WebRTC connections.
TEST_P(PeerConnectionIntegrationTest,IceTransportFactoryUsedForConnections)2653*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2654*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration default_config;
2655*d9f75844SAndroid Build Coastguard Worker   PeerConnectionDependencies dependencies(nullptr);
2656*d9f75844SAndroid Build Coastguard Worker   auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2657*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2658*d9f75844SAndroid Build Coastguard Worker   dependencies.ice_transport_factory = std::move(ice_transport_factory);
2659*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2660*d9f75844SAndroid Build Coastguard Worker                                              std::move(dependencies), nullptr,
2661*d9f75844SAndroid Build Coastguard Worker                                              /*reset_encoder_factory=*/false,
2662*d9f75844SAndroid Build Coastguard Worker                                              /*reset_decoder_factory=*/false);
2663*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(wrapper);
2664*d9f75844SAndroid Build Coastguard Worker   wrapper->CreateDataChannel();
2665*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
2666*d9f75844SAndroid Build Coastguard Worker   wrapper->pc()->SetLocalDescription(observer.get(),
2667*d9f75844SAndroid Build Coastguard Worker                                      wrapper->CreateOfferAndWait().release());
2668*d9f75844SAndroid Build Coastguard Worker }
2669*d9f75844SAndroid Build Coastguard Worker 
2670*d9f75844SAndroid Build Coastguard Worker // Test that audio and video flow end-to-end when codec names don't use the
2671*d9f75844SAndroid Build Coastguard Worker // expected casing, given that they're supposed to be case insensitive. To test
2672*d9f75844SAndroid Build Coastguard Worker // this, all but one codec is removed from each media description, and its
2673*d9f75844SAndroid Build Coastguard Worker // casing is changed.
2674*d9f75844SAndroid Build Coastguard Worker //
2675*d9f75844SAndroid Build Coastguard Worker // In the past, this has regressed and caused crashes/black video, due to the
2676*d9f75844SAndroid Build Coastguard Worker // fact that code at some layers was doing case-insensitive comparisons and
2677*d9f75844SAndroid Build Coastguard Worker // code at other layers was not.
TEST_P(PeerConnectionIntegrationTest,CodecNamesAreCaseInsensitive)2678*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
2679*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2680*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2681*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2682*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
2683*d9f75844SAndroid Build Coastguard Worker 
2684*d9f75844SAndroid Build Coastguard Worker   // Remove all but one audio/video codec (opus and VP8), and change the
2685*d9f75844SAndroid Build Coastguard Worker   // casing of the caller's generated offer.
2686*d9f75844SAndroid Build Coastguard Worker   caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2687*d9f75844SAndroid Build Coastguard Worker     cricket::AudioContentDescription* audio =
2688*d9f75844SAndroid Build Coastguard Worker         GetFirstAudioContentDescription(description);
2689*d9f75844SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, audio);
2690*d9f75844SAndroid Build Coastguard Worker     auto audio_codecs = audio->codecs();
2691*d9f75844SAndroid Build Coastguard Worker     audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2692*d9f75844SAndroid Build Coastguard Worker                                       [](const cricket::AudioCodec& codec) {
2693*d9f75844SAndroid Build Coastguard Worker                                         return codec.name != "opus";
2694*d9f75844SAndroid Build Coastguard Worker                                       }),
2695*d9f75844SAndroid Build Coastguard Worker                        audio_codecs.end());
2696*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(1u, audio_codecs.size());
2697*d9f75844SAndroid Build Coastguard Worker     audio_codecs[0].name = "OpUs";
2698*d9f75844SAndroid Build Coastguard Worker     audio->set_codecs(audio_codecs);
2699*d9f75844SAndroid Build Coastguard Worker 
2700*d9f75844SAndroid Build Coastguard Worker     cricket::VideoContentDescription* video =
2701*d9f75844SAndroid Build Coastguard Worker         GetFirstVideoContentDescription(description);
2702*d9f75844SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, video);
2703*d9f75844SAndroid Build Coastguard Worker     auto video_codecs = video->codecs();
2704*d9f75844SAndroid Build Coastguard Worker     video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2705*d9f75844SAndroid Build Coastguard Worker                                       [](const cricket::VideoCodec& codec) {
2706*d9f75844SAndroid Build Coastguard Worker                                         return codec.name != "VP8";
2707*d9f75844SAndroid Build Coastguard Worker                                       }),
2708*d9f75844SAndroid Build Coastguard Worker                        video_codecs.end());
2709*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(1u, video_codecs.size());
2710*d9f75844SAndroid Build Coastguard Worker     video_codecs[0].name = "vP8";
2711*d9f75844SAndroid Build Coastguard Worker     video->set_codecs(video_codecs);
2712*d9f75844SAndroid Build Coastguard Worker   });
2713*d9f75844SAndroid Build Coastguard Worker 
2714*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2715*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2716*d9f75844SAndroid Build Coastguard Worker 
2717*d9f75844SAndroid Build Coastguard Worker   // Verify frames are still received end-to-end.
2718*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2719*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2720*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2721*d9f75844SAndroid Build Coastguard Worker }
2722*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,GetSourcesAudio)2723*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
2724*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2725*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2726*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2727*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2728*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2729*d9f75844SAndroid Build Coastguard Worker   // Wait for one audio frame to be received by the callee.
2730*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2731*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio(1);
2732*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2733*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2734*d9f75844SAndroid Build Coastguard Worker   auto receiver = callee()->pc()->GetReceivers()[0];
2735*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
2736*d9f75844SAndroid Build Coastguard Worker   auto sources = receiver->GetSources();
2737*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2738*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2739*d9f75844SAndroid Build Coastguard Worker             sources[0].source_id());
2740*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2741*d9f75844SAndroid Build Coastguard Worker }
2742*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,GetSourcesVideo)2743*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2744*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2745*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2746*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
2747*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2748*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2749*d9f75844SAndroid Build Coastguard Worker   // Wait for one video frame to be received by the callee.
2750*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2751*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeVideo(1);
2752*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2753*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2754*d9f75844SAndroid Build Coastguard Worker   auto receiver = callee()->pc()->GetReceivers()[0];
2755*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2756*d9f75844SAndroid Build Coastguard Worker   auto sources = receiver->GetSources();
2757*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2758*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(sources.size(), 0u);
2759*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2760*d9f75844SAndroid Build Coastguard Worker             sources[0].source_id());
2761*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2762*d9f75844SAndroid Build Coastguard Worker }
2763*d9f75844SAndroid Build Coastguard Worker 
2764*d9f75844SAndroid Build Coastguard Worker // Test that if a track is removed and added again with a different stream ID,
2765*d9f75844SAndroid Build Coastguard Worker // the new stream ID is successfully communicated in SDP and media continues to
2766*d9f75844SAndroid Build Coastguard Worker // flow end-to-end.
2767*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2768*d9f75844SAndroid Build Coastguard Worker // it will not reuse a transceiver that has already been sending. After creating
2769*d9f75844SAndroid Build Coastguard Worker // a new transceiver it tries to create an offer with two senders of the same
2770*d9f75844SAndroid Build Coastguard Worker // track ids and it fails.
TEST_F(PeerConnectionIntegrationTestPlanB,RemoveAndAddTrackWithNewStreamId)2771*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
2772*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2773*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2774*d9f75844SAndroid Build Coastguard Worker 
2775*d9f75844SAndroid Build Coastguard Worker   // Add track using stream 1, do offer/answer.
2776*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2777*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalAudioTrack();
2778*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
2779*d9f75844SAndroid Build Coastguard Worker       caller()->AddTrack(track, {"stream_1"});
2780*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2781*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2782*d9f75844SAndroid Build Coastguard Worker   {
2783*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
2784*d9f75844SAndroid Build Coastguard Worker     media_expectations.CalleeExpectsSomeAudio(1);
2785*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
2786*d9f75844SAndroid Build Coastguard Worker   }
2787*d9f75844SAndroid Build Coastguard Worker   // Remove the sender, and create a new one with the new stream.
2788*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->RemoveTrackOrError(sender);
2789*d9f75844SAndroid Build Coastguard Worker   sender = caller()->AddTrack(track, {"stream_2"});
2790*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2791*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2792*d9f75844SAndroid Build Coastguard Worker   // Wait for additional audio frames to be received by the callee.
2793*d9f75844SAndroid Build Coastguard Worker   {
2794*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
2795*d9f75844SAndroid Build Coastguard Worker     media_expectations.CalleeExpectsSomeAudio();
2796*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
2797*d9f75844SAndroid Build Coastguard Worker   }
2798*d9f75844SAndroid Build Coastguard Worker }
2799*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,RtcEventLogOutputWriteCalled)2800*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
2801*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2802*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2803*d9f75844SAndroid Build Coastguard Worker 
2804*d9f75844SAndroid Build Coastguard Worker   auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
2805*d9f75844SAndroid Build Coastguard Worker   ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2806*d9f75844SAndroid Build Coastguard Worker   ON_CALL(*output, Write(::testing::A<absl::string_view>()))
2807*d9f75844SAndroid Build Coastguard Worker       .WillByDefault(::testing::Return(true));
2808*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*output, Write(::testing::A<absl::string_view>()))
2809*d9f75844SAndroid Build Coastguard Worker       .Times(::testing::AtLeast(1));
2810*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2811*d9f75844SAndroid Build Coastguard Worker       std::move(output), webrtc::RtcEventLog::kImmediateOutput));
2812*d9f75844SAndroid Build Coastguard Worker 
2813*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2814*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2815*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2816*d9f75844SAndroid Build Coastguard Worker }
2817*d9f75844SAndroid Build Coastguard Worker 
2818*d9f75844SAndroid Build Coastguard Worker // Test that if candidates are only signaled by applying full session
2819*d9f75844SAndroid Build Coastguard Worker // descriptions (instead of using AddIceCandidate), the peers can connect to
2820*d9f75844SAndroid Build Coastguard Worker // each other and exchange media.
TEST_P(PeerConnectionIntegrationTest,MediaFlowsWhenCandidatesSetOnlyInSdp)2821*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
2822*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2823*d9f75844SAndroid Build Coastguard Worker   // Each side will signal the session descriptions but not candidates.
2824*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignalingForSdpOnly();
2825*d9f75844SAndroid Build Coastguard Worker 
2826*d9f75844SAndroid Build Coastguard Worker   // Add audio video track and exchange the initial offer/answer with media
2827*d9f75844SAndroid Build Coastguard Worker   // information only. This will start ICE gathering on each side.
2828*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
2829*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
2830*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2831*d9f75844SAndroid Build Coastguard Worker 
2832*d9f75844SAndroid Build Coastguard Worker   // Wait for all candidates to be gathered on both the caller and callee.
2833*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2834*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_gathering_state(), kDefaultTimeout);
2835*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2836*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_gathering_state(), kDefaultTimeout);
2837*d9f75844SAndroid Build Coastguard Worker 
2838*d9f75844SAndroid Build Coastguard Worker   // The candidates will now be included in the session description, so
2839*d9f75844SAndroid Build Coastguard Worker   // signaling them will start the ICE connection.
2840*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2841*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2842*d9f75844SAndroid Build Coastguard Worker 
2843*d9f75844SAndroid Build Coastguard Worker   // Ensure that media flows in both directions.
2844*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2845*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
2846*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2847*d9f75844SAndroid Build Coastguard Worker }
2848*d9f75844SAndroid Build Coastguard Worker 
2849*d9f75844SAndroid Build Coastguard Worker #if !defined(THREAD_SANITIZER)
2850*d9f75844SAndroid Build Coastguard Worker // These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2851*d9f75844SAndroid Build Coastguard Worker 
2852*d9f75844SAndroid Build Coastguard Worker // Test that SetAudioPlayout can be used to disable audio playout from the
2853*d9f75844SAndroid Build Coastguard Worker // start, then later enable it. This may be useful, for example, if the caller
2854*d9f75844SAndroid Build Coastguard Worker // needs to play a local ringtone until some event occurs, after which it
2855*d9f75844SAndroid Build Coastguard Worker // switches to playing the received audio.
TEST_P(PeerConnectionIntegrationTest,DisableAndEnableAudioPlayout)2856*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
2857*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2858*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2859*d9f75844SAndroid Build Coastguard Worker 
2860*d9f75844SAndroid Build Coastguard Worker   // Set up audio-only call where audio playout is disabled on caller's side.
2861*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->SetAudioPlayout(false);
2862*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2863*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
2864*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2865*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2866*d9f75844SAndroid Build Coastguard Worker 
2867*d9f75844SAndroid Build Coastguard Worker   // Pump messages for a second.
2868*d9f75844SAndroid Build Coastguard Worker   WAIT(false, 1000);
2869*d9f75844SAndroid Build Coastguard Worker   // Since audio playout is disabled, the caller shouldn't have received
2870*d9f75844SAndroid Build Coastguard Worker   // anything (at the playout level, at least).
2871*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, caller()->audio_frames_received());
2872*d9f75844SAndroid Build Coastguard Worker   // As a sanity check, make sure the callee (for which playout isn't disabled)
2873*d9f75844SAndroid Build Coastguard Worker   // did still see frames on its audio level.
2874*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(callee()->audio_frames_received(), 0);
2875*d9f75844SAndroid Build Coastguard Worker 
2876*d9f75844SAndroid Build Coastguard Worker   // Enable playout again, and ensure audio starts flowing.
2877*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->SetAudioPlayout(true);
2878*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2879*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudio();
2880*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2881*d9f75844SAndroid Build Coastguard Worker }
2882*d9f75844SAndroid Build Coastguard Worker 
GetAudioEnergyStat(PeerConnectionIntegrationWrapper * pc)2883*d9f75844SAndroid Build Coastguard Worker double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
2884*d9f75844SAndroid Build Coastguard Worker   auto report = pc->NewGetStats();
2885*d9f75844SAndroid Build Coastguard Worker   auto track_stats_list =
2886*d9f75844SAndroid Build Coastguard Worker       report->GetStatsOfType<webrtc::DEPRECATED_RTCMediaStreamTrackStats>();
2887*d9f75844SAndroid Build Coastguard Worker   const webrtc::DEPRECATED_RTCMediaStreamTrackStats* remote_track_stats =
2888*d9f75844SAndroid Build Coastguard Worker       nullptr;
2889*d9f75844SAndroid Build Coastguard Worker   for (const auto* track_stats : track_stats_list) {
2890*d9f75844SAndroid Build Coastguard Worker     if (track_stats->remote_source.is_defined() &&
2891*d9f75844SAndroid Build Coastguard Worker         *track_stats->remote_source) {
2892*d9f75844SAndroid Build Coastguard Worker       remote_track_stats = track_stats;
2893*d9f75844SAndroid Build Coastguard Worker       break;
2894*d9f75844SAndroid Build Coastguard Worker     }
2895*d9f75844SAndroid Build Coastguard Worker   }
2896*d9f75844SAndroid Build Coastguard Worker 
2897*d9f75844SAndroid Build Coastguard Worker   if (!remote_track_stats->total_audio_energy.is_defined()) {
2898*d9f75844SAndroid Build Coastguard Worker     return 0.0;
2899*d9f75844SAndroid Build Coastguard Worker   }
2900*d9f75844SAndroid Build Coastguard Worker   return *remote_track_stats->total_audio_energy;
2901*d9f75844SAndroid Build Coastguard Worker }
2902*d9f75844SAndroid Build Coastguard Worker 
2903*d9f75844SAndroid Build Coastguard Worker // Test that if audio playout is disabled via the SetAudioPlayout() method, then
2904*d9f75844SAndroid Build Coastguard Worker // incoming audio is still processed and statistics are generated.
TEST_P(PeerConnectionIntegrationTest,DisableAudioPlayoutStillGeneratesAudioStats)2905*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
2906*d9f75844SAndroid Build Coastguard Worker        DisableAudioPlayoutStillGeneratesAudioStats) {
2907*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2908*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2909*d9f75844SAndroid Build Coastguard Worker 
2910*d9f75844SAndroid Build Coastguard Worker   // Set up audio-only call where playout is disabled but audio-processing is
2911*d9f75844SAndroid Build Coastguard Worker   // still active.
2912*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2913*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
2914*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->SetAudioPlayout(false);
2915*d9f75844SAndroid Build Coastguard Worker 
2916*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2917*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2918*d9f75844SAndroid Build Coastguard Worker 
2919*d9f75844SAndroid Build Coastguard Worker   // Wait for the callee to receive audio stats.
2920*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2921*d9f75844SAndroid Build Coastguard Worker }
2922*d9f75844SAndroid Build Coastguard Worker 
2923*d9f75844SAndroid Build Coastguard Worker #endif  // !defined(THREAD_SANITIZER)
2924*d9f75844SAndroid Build Coastguard Worker 
2925*d9f75844SAndroid Build Coastguard Worker // Test that SetAudioRecording can be used to disable audio recording from the
2926*d9f75844SAndroid Build Coastguard Worker // start, then later enable it. This may be useful, for example, if the caller
2927*d9f75844SAndroid Build Coastguard Worker // wants to ensure that no audio resources are active before a certain state
2928*d9f75844SAndroid Build Coastguard Worker // is reached.
TEST_P(PeerConnectionIntegrationTest,DisableAndEnableAudioRecording)2929*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
2930*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
2931*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2932*d9f75844SAndroid Build Coastguard Worker 
2933*d9f75844SAndroid Build Coastguard Worker   // Set up audio-only call where audio recording is disabled on caller's side.
2934*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->SetAudioRecording(false);
2935*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
2936*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
2937*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2938*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2939*d9f75844SAndroid Build Coastguard Worker 
2940*d9f75844SAndroid Build Coastguard Worker   // Pump messages for a second.
2941*d9f75844SAndroid Build Coastguard Worker   WAIT(false, 1000);
2942*d9f75844SAndroid Build Coastguard Worker   // Since caller has disabled audio recording, the callee shouldn't have
2943*d9f75844SAndroid Build Coastguard Worker   // received anything.
2944*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, callee()->audio_frames_received());
2945*d9f75844SAndroid Build Coastguard Worker   // As a sanity check, make sure the caller did still see frames on its
2946*d9f75844SAndroid Build Coastguard Worker   // audio level since audio recording is enabled on the calle side.
2947*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(caller()->audio_frames_received(), 0);
2948*d9f75844SAndroid Build Coastguard Worker 
2949*d9f75844SAndroid Build Coastguard Worker   // Enable audio recording again, and ensure audio starts flowing.
2950*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->SetAudioRecording(true);
2951*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
2952*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudio();
2953*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
2954*d9f75844SAndroid Build Coastguard Worker }
2955*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,IceEventsGeneratedAndLoggedInRtcEventLog)2956*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest,
2957*d9f75844SAndroid Build Coastguard Worker        IceEventsGeneratedAndLoggedInRtcEventLog) {
2958*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2959*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
2960*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
2961*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio = 1;
2962*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
2963*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
2964*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2965*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, caller()->event_log_factory());
2966*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee()->event_log_factory());
2967*d9f75844SAndroid Build Coastguard Worker   webrtc::FakeRtcEventLog* caller_event_log =
2968*d9f75844SAndroid Build Coastguard Worker       caller()->event_log_factory()->last_log_created();
2969*d9f75844SAndroid Build Coastguard Worker   webrtc::FakeRtcEventLog* callee_event_log =
2970*d9f75844SAndroid Build Coastguard Worker       callee()->event_log_factory()->last_log_created();
2971*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, caller_event_log);
2972*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(nullptr, callee_event_log);
2973*d9f75844SAndroid Build Coastguard Worker   int caller_ice_config_count = caller_event_log->GetEventCount(
2974*d9f75844SAndroid Build Coastguard Worker       webrtc::RtcEvent::Type::IceCandidatePairConfig);
2975*d9f75844SAndroid Build Coastguard Worker   int caller_ice_event_count = caller_event_log->GetEventCount(
2976*d9f75844SAndroid Build Coastguard Worker       webrtc::RtcEvent::Type::IceCandidatePairEvent);
2977*d9f75844SAndroid Build Coastguard Worker   int callee_ice_config_count = callee_event_log->GetEventCount(
2978*d9f75844SAndroid Build Coastguard Worker       webrtc::RtcEvent::Type::IceCandidatePairConfig);
2979*d9f75844SAndroid Build Coastguard Worker   int callee_ice_event_count = callee_event_log->GetEventCount(
2980*d9f75844SAndroid Build Coastguard Worker       webrtc::RtcEvent::Type::IceCandidatePairEvent);
2981*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(0, caller_ice_config_count);
2982*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(0, caller_ice_event_count);
2983*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(0, callee_ice_config_count);
2984*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(0, callee_ice_event_count);
2985*d9f75844SAndroid Build Coastguard Worker }
2986*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,RegatherAfterChangingIceTransportType)2987*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
2988*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2989*d9f75844SAndroid Build Coastguard Worker                                                                3478};
2990*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2991*d9f75844SAndroid Build Coastguard Worker 
2992*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2993*d9f75844SAndroid Build Coastguard Worker 
2994*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server;
2995*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back("turn:88.88.88.0:3478");
2996*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
2997*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
2998*d9f75844SAndroid Build Coastguard Worker 
2999*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration caller_config;
3000*d9f75844SAndroid Build Coastguard Worker   caller_config.servers.push_back(ice_server);
3001*d9f75844SAndroid Build Coastguard Worker   caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3002*d9f75844SAndroid Build Coastguard Worker   caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3003*d9f75844SAndroid Build Coastguard Worker   caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
3004*d9f75844SAndroid Build Coastguard Worker 
3005*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration callee_config;
3006*d9f75844SAndroid Build Coastguard Worker   callee_config.servers.push_back(ice_server);
3007*d9f75844SAndroid Build Coastguard Worker   callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3008*d9f75844SAndroid Build Coastguard Worker   callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3009*d9f75844SAndroid Build Coastguard Worker   callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
3010*d9f75844SAndroid Build Coastguard Worker 
3011*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
3012*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3013*d9f75844SAndroid Build Coastguard Worker 
3014*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for ICE to complete.
3015*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3016*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
3017*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
3018*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3019*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3020*d9f75844SAndroid Build Coastguard Worker   // Since we are doing continual gathering, the ICE transport does not reach
3021*d9f75844SAndroid Build Coastguard Worker   // kIceGatheringComplete (see
3022*d9f75844SAndroid Build Coastguard Worker   // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3023*d9f75844SAndroid Build Coastguard Worker   // kIceConnectionComplete.
3024*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3025*d9f75844SAndroid Build Coastguard Worker                  caller()->ice_connection_state(), kDefaultTimeout);
3026*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3027*d9f75844SAndroid Build Coastguard Worker                  callee()->ice_connection_state(), kDefaultTimeout);
3028*d9f75844SAndroid Build Coastguard Worker   // Note that we cannot use the metric
3029*d9f75844SAndroid Build Coastguard Worker   // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
3030*d9f75844SAndroid Build Coastguard Worker   // metric is only populated when we reach kIceConnectionComplete in the
3031*d9f75844SAndroid Build Coastguard Worker   // current implementation.
3032*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3033*d9f75844SAndroid Build Coastguard Worker             caller()->last_candidate_gathered().type());
3034*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3035*d9f75844SAndroid Build Coastguard Worker             callee()->last_candidate_gathered().type());
3036*d9f75844SAndroid Build Coastguard Worker 
3037*d9f75844SAndroid Build Coastguard Worker   // Loosen the caller's candidate filter.
3038*d9f75844SAndroid Build Coastguard Worker   caller_config = caller()->pc()->GetConfiguration();
3039*d9f75844SAndroid Build Coastguard Worker   caller_config.type = webrtc::PeerConnectionInterface::kAll;
3040*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->SetConfiguration(caller_config);
3041*d9f75844SAndroid Build Coastguard Worker   // We should have gathered a new host candidate.
3042*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3043*d9f75844SAndroid Build Coastguard Worker                  caller()->last_candidate_gathered().type(), kDefaultTimeout);
3044*d9f75844SAndroid Build Coastguard Worker 
3045*d9f75844SAndroid Build Coastguard Worker   // Loosen the callee's candidate filter.
3046*d9f75844SAndroid Build Coastguard Worker   callee_config = callee()->pc()->GetConfiguration();
3047*d9f75844SAndroid Build Coastguard Worker   callee_config.type = webrtc::PeerConnectionInterface::kAll;
3048*d9f75844SAndroid Build Coastguard Worker   callee()->pc()->SetConfiguration(callee_config);
3049*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3050*d9f75844SAndroid Build Coastguard Worker                  callee()->last_candidate_gathered().type(), kDefaultTimeout);
3051*d9f75844SAndroid Build Coastguard Worker 
3052*d9f75844SAndroid Build Coastguard Worker   // Create an offer and verify that it does not contain an ICE restart (i.e new
3053*d9f75844SAndroid Build Coastguard Worker   // ice credentials).
3054*d9f75844SAndroid Build Coastguard Worker   std::string caller_ufrag_pre_offer = caller()
3055*d9f75844SAndroid Build Coastguard Worker                                            ->pc()
3056*d9f75844SAndroid Build Coastguard Worker                                            ->local_description()
3057*d9f75844SAndroid Build Coastguard Worker                                            ->description()
3058*d9f75844SAndroid Build Coastguard Worker                                            ->transport_infos()[0]
3059*d9f75844SAndroid Build Coastguard Worker                                            .description.ice_ufrag;
3060*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3061*d9f75844SAndroid Build Coastguard Worker   std::string caller_ufrag_post_offer = caller()
3062*d9f75844SAndroid Build Coastguard Worker                                             ->pc()
3063*d9f75844SAndroid Build Coastguard Worker                                             ->local_description()
3064*d9f75844SAndroid Build Coastguard Worker                                             ->description()
3065*d9f75844SAndroid Build Coastguard Worker                                             ->transport_infos()[0]
3066*d9f75844SAndroid Build Coastguard Worker                                             .description.ice_ufrag;
3067*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
3068*d9f75844SAndroid Build Coastguard Worker }
3069*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,OnIceCandidateError)3070*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
3071*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3072*d9f75844SAndroid Build Coastguard Worker                                                                3478};
3073*d9f75844SAndroid Build Coastguard Worker   static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3074*d9f75844SAndroid Build Coastguard Worker 
3075*d9f75844SAndroid Build Coastguard Worker   CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3076*d9f75844SAndroid Build Coastguard Worker 
3077*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server;
3078*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back("turn:88.88.88.0:3478");
3079*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
3080*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "123";
3081*d9f75844SAndroid Build Coastguard Worker 
3082*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration caller_config;
3083*d9f75844SAndroid Build Coastguard Worker   caller_config.servers.push_back(ice_server);
3084*d9f75844SAndroid Build Coastguard Worker   caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3085*d9f75844SAndroid Build Coastguard Worker   caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3086*d9f75844SAndroid Build Coastguard Worker 
3087*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration callee_config;
3088*d9f75844SAndroid Build Coastguard Worker   callee_config.servers.push_back(ice_server);
3089*d9f75844SAndroid Build Coastguard Worker   callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3090*d9f75844SAndroid Build Coastguard Worker   callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3091*d9f75844SAndroid Build Coastguard Worker 
3092*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
3093*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3094*d9f75844SAndroid Build Coastguard Worker 
3095*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for ICE to complete.
3096*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3097*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
3098*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
3099*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3100*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3101*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3102*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3103*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
3104*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(caller()->error_event().address, "");
3105*d9f75844SAndroid Build Coastguard Worker }
3106*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,OnIceCandidateErrorWithEmptyAddress)3107*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3108*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer ice_server;
3109*d9f75844SAndroid Build Coastguard Worker   ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3110*d9f75844SAndroid Build Coastguard Worker   ice_server.username = "test";
3111*d9f75844SAndroid Build Coastguard Worker   ice_server.password = "test";
3112*d9f75844SAndroid Build Coastguard Worker 
3113*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration caller_config;
3114*d9f75844SAndroid Build Coastguard Worker   caller_config.servers.push_back(ice_server);
3115*d9f75844SAndroid Build Coastguard Worker   caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3116*d9f75844SAndroid Build Coastguard Worker   caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3117*d9f75844SAndroid Build Coastguard Worker 
3118*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration callee_config;
3119*d9f75844SAndroid Build Coastguard Worker   callee_config.servers.push_back(ice_server);
3120*d9f75844SAndroid Build Coastguard Worker   callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3121*d9f75844SAndroid Build Coastguard Worker   callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3122*d9f75844SAndroid Build Coastguard Worker 
3123*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
3124*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3125*d9f75844SAndroid Build Coastguard Worker 
3126*d9f75844SAndroid Build Coastguard Worker   // Do normal offer/answer and wait for ICE to complete.
3127*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3128*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
3129*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
3130*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3131*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3132*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3133*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(caller()->error_event().address, "");
3134*d9f75844SAndroid Build Coastguard Worker }
3135*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,AudioKeepsFlowingAfterImplicitRollback)3136*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3137*d9f75844SAndroid Build Coastguard Worker        AudioKeepsFlowingAfterImplicitRollback) {
3138*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
3139*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3140*d9f75844SAndroid Build Coastguard Worker   config.enable_implicit_rollback = true;
3141*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3142*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3143*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
3144*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
3145*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3146*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3147*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3148*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudio();
3149*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3150*d9f75844SAndroid Build Coastguard Worker   SetSignalIceCandidates(false);  // Workaround candidate outrace sdp.
3151*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
3152*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
3153*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
3154*d9f75844SAndroid Build Coastguard Worker   callee()->pc()->SetLocalDescription(observer.get(),
3155*d9f75844SAndroid Build Coastguard Worker                                       callee()->CreateOfferAndWait().release());
3156*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3157*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();  // Implicit rollback.
3158*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3159*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3160*d9f75844SAndroid Build Coastguard Worker }
3161*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,ImplicitRollbackVisitsStableState)3162*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3163*d9f75844SAndroid Build Coastguard Worker        ImplicitRollbackVisitsStableState) {
3164*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
3165*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3166*d9f75844SAndroid Build Coastguard Worker   config.enable_implicit_rollback = true;
3167*d9f75844SAndroid Build Coastguard Worker 
3168*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3169*d9f75844SAndroid Build Coastguard Worker 
3170*d9f75844SAndroid Build Coastguard Worker   auto sld_observer =
3171*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
3172*d9f75844SAndroid Build Coastguard Worker   callee()->pc()->SetLocalDescription(sld_observer.get(),
3173*d9f75844SAndroid Build Coastguard Worker                                       callee()->CreateOfferAndWait().release());
3174*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3175*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sld_observer->error(), "");
3176*d9f75844SAndroid Build Coastguard Worker 
3177*d9f75844SAndroid Build Coastguard Worker   auto srd_observer =
3178*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
3179*d9f75844SAndroid Build Coastguard Worker   callee()->pc()->SetRemoteDescription(
3180*d9f75844SAndroid Build Coastguard Worker       srd_observer.get(), caller()->CreateOfferAndWait().release());
3181*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3182*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(srd_observer->error(), "");
3183*d9f75844SAndroid Build Coastguard Worker 
3184*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3185*d9f75844SAndroid Build Coastguard Worker               ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3186*d9f75844SAndroid Build Coastguard Worker                           PeerConnectionInterface::kStable,
3187*d9f75844SAndroid Build Coastguard Worker                           PeerConnectionInterface::kHaveRemoteOffer));
3188*d9f75844SAndroid Build Coastguard Worker }
3189*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,H264FmtpSpsPpsIdrInKeyframeParameterUsage)3190*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3191*d9f75844SAndroid Build Coastguard Worker        H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3192*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
3193*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3194*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
3195*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
3196*d9f75844SAndroid Build Coastguard Worker   auto munger = [](cricket::SessionDescription* desc) {
3197*d9f75844SAndroid Build Coastguard Worker     cricket::VideoContentDescription* video =
3198*d9f75844SAndroid Build Coastguard Worker         GetFirstVideoContentDescription(desc);
3199*d9f75844SAndroid Build Coastguard Worker     auto codecs = video->codecs();
3200*d9f75844SAndroid Build Coastguard Worker     for (auto&& codec : codecs) {
3201*d9f75844SAndroid Build Coastguard Worker       if (codec.name == "H264") {
3202*d9f75844SAndroid Build Coastguard Worker         std::string value;
3203*d9f75844SAndroid Build Coastguard Worker         // The parameter is not supposed to be present in SDP by default.
3204*d9f75844SAndroid Build Coastguard Worker         EXPECT_FALSE(
3205*d9f75844SAndroid Build Coastguard Worker             codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3206*d9f75844SAndroid Build Coastguard Worker         codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3207*d9f75844SAndroid Build Coastguard Worker                        std::string(""));
3208*d9f75844SAndroid Build Coastguard Worker       }
3209*d9f75844SAndroid Build Coastguard Worker     }
3210*d9f75844SAndroid Build Coastguard Worker     video->set_codecs(codecs);
3211*d9f75844SAndroid Build Coastguard Worker   };
3212*d9f75844SAndroid Build Coastguard Worker   // Munge local offer for SLD.
3213*d9f75844SAndroid Build Coastguard Worker   caller()->SetGeneratedSdpMunger(munger);
3214*d9f75844SAndroid Build Coastguard Worker   // Munge remote answer for SRD.
3215*d9f75844SAndroid Build Coastguard Worker   caller()->SetReceivedSdpMunger(munger);
3216*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3217*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3218*d9f75844SAndroid Build Coastguard Worker   // Observe that after munging the parameter is present in generated SDP.
3219*d9f75844SAndroid Build Coastguard Worker   caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3220*d9f75844SAndroid Build Coastguard Worker     cricket::VideoContentDescription* video =
3221*d9f75844SAndroid Build Coastguard Worker         GetFirstVideoContentDescription(desc);
3222*d9f75844SAndroid Build Coastguard Worker     for (auto&& codec : video->codecs()) {
3223*d9f75844SAndroid Build Coastguard Worker       if (codec.name == "H264") {
3224*d9f75844SAndroid Build Coastguard Worker         std::string value;
3225*d9f75844SAndroid Build Coastguard Worker         EXPECT_TRUE(
3226*d9f75844SAndroid Build Coastguard Worker             codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3227*d9f75844SAndroid Build Coastguard Worker       }
3228*d9f75844SAndroid Build Coastguard Worker     }
3229*d9f75844SAndroid Build Coastguard Worker   });
3230*d9f75844SAndroid Build Coastguard Worker   caller()->CreateOfferAndWait();
3231*d9f75844SAndroid Build Coastguard Worker }
3232*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,RenegotiateManyAudioTransceivers)3233*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3234*d9f75844SAndroid Build Coastguard Worker        RenegotiateManyAudioTransceivers) {
3235*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
3236*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3237*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3238*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3239*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3240*d9f75844SAndroid Build Coastguard Worker 
3241*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3242*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3243*d9f75844SAndroid Build Coastguard Worker   int current_size = caller()->pc()->GetTransceivers().size();
3244*d9f75844SAndroid Build Coastguard Worker   // Add more tracks until we get close to having issues.
3245*d9f75844SAndroid Build Coastguard Worker   // Issues have been seen at:
3246*d9f75844SAndroid Build Coastguard Worker   // - 32 tracks on android_arm64_rel and android_arm_dbg bots
3247*d9f75844SAndroid Build Coastguard Worker   // - 16 tracks on android_arm_dbg (flaky)
3248*d9f75844SAndroid Build Coastguard Worker   while (current_size < 8) {
3249*d9f75844SAndroid Build Coastguard Worker     // Double the number of tracks
3250*d9f75844SAndroid Build Coastguard Worker     for (int i = 0; i < current_size; i++) {
3251*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3252*d9f75844SAndroid Build Coastguard Worker     }
3253*d9f75844SAndroid Build Coastguard Worker     current_size = caller()->pc()->GetTransceivers().size();
3254*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3255*d9f75844SAndroid Build Coastguard Worker     auto start_time_ms = rtc::TimeMillis();
3256*d9f75844SAndroid Build Coastguard Worker     caller()->CreateAndSetAndSignalOffer();
3257*d9f75844SAndroid Build Coastguard Worker     // We want to stop when the time exceeds one second.
3258*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3259*d9f75844SAndroid Build Coastguard Worker     auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3260*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3261*d9f75844SAndroid Build Coastguard Worker     ASSERT_GT(1000, elapsed_time_ms)
3262*d9f75844SAndroid Build Coastguard Worker         << "Audio transceivers: Negotiation took too long after "
3263*d9f75844SAndroid Build Coastguard Worker         << current_size << " tracks added";
3264*d9f75844SAndroid Build Coastguard Worker   }
3265*d9f75844SAndroid Build Coastguard Worker }
3266*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,RenegotiateManyVideoTransceivers)3267*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3268*d9f75844SAndroid Build Coastguard Worker        RenegotiateManyVideoTransceivers) {
3269*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
3270*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3271*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3272*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3273*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3274*d9f75844SAndroid Build Coastguard Worker 
3275*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3276*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3277*d9f75844SAndroid Build Coastguard Worker   int current_size = caller()->pc()->GetTransceivers().size();
3278*d9f75844SAndroid Build Coastguard Worker   // Add more tracks until we get close to having issues.
3279*d9f75844SAndroid Build Coastguard Worker   // Issues have been seen at:
3280*d9f75844SAndroid Build Coastguard Worker   // - 96 on a Linux workstation
3281*d9f75844SAndroid Build Coastguard Worker   // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3282*d9f75844SAndroid Build Coastguard Worker   // - 32 on android_arm64_rel and linux_dbg bots
3283*d9f75844SAndroid Build Coastguard Worker   // - 16 on Android 64 (Nexus 5x)
3284*d9f75844SAndroid Build Coastguard Worker   while (current_size < 8) {
3285*d9f75844SAndroid Build Coastguard Worker     // Double the number of tracks
3286*d9f75844SAndroid Build Coastguard Worker     for (int i = 0; i < current_size; i++) {
3287*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3288*d9f75844SAndroid Build Coastguard Worker     }
3289*d9f75844SAndroid Build Coastguard Worker     current_size = caller()->pc()->GetTransceivers().size();
3290*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3291*d9f75844SAndroid Build Coastguard Worker     auto start_time_ms = rtc::TimeMillis();
3292*d9f75844SAndroid Build Coastguard Worker     caller()->CreateAndSetAndSignalOffer();
3293*d9f75844SAndroid Build Coastguard Worker     // We want to stop when the time exceeds one second.
3294*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3295*d9f75844SAndroid Build Coastguard Worker     auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3296*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3297*d9f75844SAndroid Build Coastguard Worker     ASSERT_GT(1000, elapsed_time_ms)
3298*d9f75844SAndroid Build Coastguard Worker         << "Video transceivers: Negotiation took too long after "
3299*d9f75844SAndroid Build Coastguard Worker         << current_size << " tracks added";
3300*d9f75844SAndroid Build Coastguard Worker   }
3301*d9f75844SAndroid Build Coastguard Worker }
3302*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,RenegotiateManyVideoTransceiversAndWatchAudioDelay)3303*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3304*d9f75844SAndroid Build Coastguard Worker        RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3305*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCConfiguration config;
3306*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3307*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3308*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3309*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
3310*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioTrack();
3311*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3312*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3313*d9f75844SAndroid Build Coastguard Worker   // Wait until we can see the audio flowing.
3314*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3315*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio();
3316*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3317*d9f75844SAndroid Build Coastguard Worker 
3318*d9f75844SAndroid Build Coastguard Worker   // Get the baseline numbers for audio_packets and audio_delay
3319*d9f75844SAndroid Build Coastguard Worker   // in both directions.
3320*d9f75844SAndroid Build Coastguard Worker   caller()->StartWatchingDelayStats();
3321*d9f75844SAndroid Build Coastguard Worker   callee()->StartWatchingDelayStats();
3322*d9f75844SAndroid Build Coastguard Worker 
3323*d9f75844SAndroid Build Coastguard Worker   int current_size = caller()->pc()->GetTransceivers().size();
3324*d9f75844SAndroid Build Coastguard Worker   // Add more tracks until we get close to having issues.
3325*d9f75844SAndroid Build Coastguard Worker   // Making this number very large makes the test very slow.
3326*d9f75844SAndroid Build Coastguard Worker   while (current_size < 16) {
3327*d9f75844SAndroid Build Coastguard Worker     // Double the number of tracks
3328*d9f75844SAndroid Build Coastguard Worker     for (int i = 0; i < current_size; i++) {
3329*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3330*d9f75844SAndroid Build Coastguard Worker     }
3331*d9f75844SAndroid Build Coastguard Worker     current_size = caller()->pc()->GetTransceivers().size();
3332*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3333*d9f75844SAndroid Build Coastguard Worker     auto start_time_ms = rtc::TimeMillis();
3334*d9f75844SAndroid Build Coastguard Worker     caller()->CreateAndSetAndSignalOffer();
3335*d9f75844SAndroid Build Coastguard Worker     // We want to stop when the time exceeds one second.
3336*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3337*d9f75844SAndroid Build Coastguard Worker     auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3338*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3339*d9f75844SAndroid Build Coastguard Worker     // This is a guard against the test using excessive amounts of time.
3340*d9f75844SAndroid Build Coastguard Worker     ASSERT_GT(5000, elapsed_time_ms)
3341*d9f75844SAndroid Build Coastguard Worker         << "Video transceivers: Negotiation took too long after "
3342*d9f75844SAndroid Build Coastguard Worker         << current_size << " tracks added";
3343*d9f75844SAndroid Build Coastguard Worker     caller()->UpdateDelayStats("caller reception", current_size);
3344*d9f75844SAndroid Build Coastguard Worker     callee()->UpdateDelayStats("callee reception", current_size);
3345*d9f75844SAndroid Build Coastguard Worker   }
3346*d9f75844SAndroid Build Coastguard Worker }
3347*d9f75844SAndroid Build Coastguard Worker 
3348*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
3349*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTest,
3350*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTest,
3351*d9f75844SAndroid Build Coastguard Worker     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
3352*d9f75844SAndroid Build Coastguard Worker             Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3353*d9f75844SAndroid Build Coastguard Worker                    "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3354*d9f75844SAndroid Build Coastguard Worker                    "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
3355*d9f75844SAndroid Build Coastguard Worker 
3356*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
3357*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTest,
3358*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTestWithFakeClock,
3359*d9f75844SAndroid Build Coastguard Worker     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
3360*d9f75844SAndroid Build Coastguard Worker             Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3361*d9f75844SAndroid Build Coastguard Worker                    "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3362*d9f75844SAndroid Build Coastguard Worker                    "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
3363*d9f75844SAndroid Build Coastguard Worker 
3364*d9f75844SAndroid Build Coastguard Worker // Tests that verify interoperability between Plan B and Unified Plan
3365*d9f75844SAndroid Build Coastguard Worker // PeerConnections.
3366*d9f75844SAndroid Build Coastguard Worker class PeerConnectionIntegrationInteropTest
3367*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionIntegrationBaseTest,
3368*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<
3369*d9f75844SAndroid Build Coastguard Worker           std::tuple<SdpSemantics, SdpSemantics>> {
3370*d9f75844SAndroid Build Coastguard Worker  protected:
3371*d9f75844SAndroid Build Coastguard Worker   // Setting the SdpSemantics for the base test to kDefault does not matter
3372*d9f75844SAndroid Build Coastguard Worker   // because we specify not to use the test semantics when creating
3373*d9f75844SAndroid Build Coastguard Worker   // PeerConnectionIntegrationWrappers.
PeerConnectionIntegrationInteropTest()3374*d9f75844SAndroid Build Coastguard Worker   PeerConnectionIntegrationInteropTest()
3375*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
3376*d9f75844SAndroid Build Coastguard Worker         caller_semantics_(std::get<0>(GetParam())),
3377*d9f75844SAndroid Build Coastguard Worker         callee_semantics_(std::get<1>(GetParam())) {}
3378*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionWrappersWithSemantics()3379*d9f75844SAndroid Build Coastguard Worker   bool CreatePeerConnectionWrappersWithSemantics() {
3380*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3381*d9f75844SAndroid Build Coastguard Worker                                                         callee_semantics_);
3382*d9f75844SAndroid Build Coastguard Worker   }
3383*d9f75844SAndroid Build Coastguard Worker 
3384*d9f75844SAndroid Build Coastguard Worker   const SdpSemantics caller_semantics_;
3385*d9f75844SAndroid Build Coastguard Worker   const SdpSemantics callee_semantics_;
3386*d9f75844SAndroid Build Coastguard Worker };
3387*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationInteropTest,NoMediaLocalToNoMediaRemote)3388*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3389*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3390*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3391*d9f75844SAndroid Build Coastguard Worker 
3392*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3393*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3394*d9f75844SAndroid Build Coastguard Worker }
3395*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationInteropTest,OneAudioLocalToNoMediaRemote)3396*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3397*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3398*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3399*d9f75844SAndroid Build Coastguard Worker   auto audio_sender = caller()->AddAudioTrack();
3400*d9f75844SAndroid Build Coastguard Worker 
3401*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3402*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3403*d9f75844SAndroid Build Coastguard Worker 
3404*d9f75844SAndroid Build Coastguard Worker   // Verify that one audio receiver has been created on the remote and that it
3405*d9f75844SAndroid Build Coastguard Worker   // has the same track ID as the sending track.
3406*d9f75844SAndroid Build Coastguard Worker   auto receivers = callee()->pc()->GetReceivers();
3407*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, receivers.size());
3408*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3409*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3410*d9f75844SAndroid Build Coastguard Worker 
3411*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3412*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio();
3413*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3414*d9f75844SAndroid Build Coastguard Worker }
3415*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationInteropTest,OneAudioOneVideoToNoMediaRemote)3416*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3417*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3418*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3419*d9f75844SAndroid Build Coastguard Worker   auto video_sender = caller()->AddVideoTrack();
3420*d9f75844SAndroid Build Coastguard Worker   auto audio_sender = caller()->AddAudioTrack();
3421*d9f75844SAndroid Build Coastguard Worker 
3422*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3423*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3424*d9f75844SAndroid Build Coastguard Worker 
3425*d9f75844SAndroid Build Coastguard Worker   // Verify that one audio and one video receiver have been created on the
3426*d9f75844SAndroid Build Coastguard Worker   // remote and that they have the same track IDs as the sending tracks.
3427*d9f75844SAndroid Build Coastguard Worker   auto audio_receivers =
3428*d9f75844SAndroid Build Coastguard Worker       callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3429*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, audio_receivers.size());
3430*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3431*d9f75844SAndroid Build Coastguard Worker   auto video_receivers =
3432*d9f75844SAndroid Build Coastguard Worker       callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3433*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, video_receivers.size());
3434*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3435*d9f75844SAndroid Build Coastguard Worker 
3436*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3437*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudioAndVideo();
3438*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3439*d9f75844SAndroid Build Coastguard Worker }
3440*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationInteropTest,OneAudioOneVideoLocalToOneAudioOneVideoRemote)3441*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationInteropTest,
3442*d9f75844SAndroid Build Coastguard Worker        OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3443*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3444*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3445*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
3446*d9f75844SAndroid Build Coastguard Worker   callee()->AddAudioVideoTracks();
3447*d9f75844SAndroid Build Coastguard Worker 
3448*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3449*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3450*d9f75844SAndroid Build Coastguard Worker 
3451*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3452*d9f75844SAndroid Build Coastguard Worker   media_expectations.ExpectBidirectionalAudioAndVideo();
3453*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3454*d9f75844SAndroid Build Coastguard Worker }
3455*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationInteropTest,ReverseRolesOneAudioLocalToOneVideoRemote)3456*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationInteropTest,
3457*d9f75844SAndroid Build Coastguard Worker        ReverseRolesOneAudioLocalToOneVideoRemote) {
3458*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3459*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3460*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
3461*d9f75844SAndroid Build Coastguard Worker   callee()->AddVideoTrack();
3462*d9f75844SAndroid Build Coastguard Worker 
3463*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3464*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3465*d9f75844SAndroid Build Coastguard Worker 
3466*d9f75844SAndroid Build Coastguard Worker   // Verify that only the audio track has been negotiated.
3467*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3468*d9f75844SAndroid Build Coastguard Worker   // Might also check that the callee's NegotiationNeeded flag is set.
3469*d9f75844SAndroid Build Coastguard Worker 
3470*d9f75844SAndroid Build Coastguard Worker   // Reverse roles.
3471*d9f75844SAndroid Build Coastguard Worker   callee()->CreateAndSetAndSignalOffer();
3472*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3473*d9f75844SAndroid Build Coastguard Worker 
3474*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3475*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsSomeVideo();
3476*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeAudio();
3477*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3478*d9f75844SAndroid Build Coastguard Worker }
3479*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,NewTracksDoNotCauseNewCandidates)3480*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3481*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappers());
3482*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3483*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioVideoTracks();
3484*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3485*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3486*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3487*d9f75844SAndroid Build Coastguard Worker   caller()->ExpectCandidates(0);
3488*d9f75844SAndroid Build Coastguard Worker   callee()->ExpectCandidates(0);
3489*d9f75844SAndroid Build Coastguard Worker   caller()->AddAudioTrack();
3490*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3491*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3492*d9f75844SAndroid Build Coastguard Worker }
3493*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,MediaCallWithoutMediaEngineFails)3494*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3495*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3496*d9f75844SAndroid Build Coastguard Worker   // AddTrack should fail.
3497*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(
3498*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3499*d9f75844SAndroid Build Coastguard Worker }
3500*d9f75844SAndroid Build Coastguard Worker 
3501*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
3502*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationTest,
3503*d9f75844SAndroid Build Coastguard Worker     PeerConnectionIntegrationInteropTest,
3504*d9f75844SAndroid Build Coastguard Worker     Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3505*d9f75844SAndroid Build Coastguard Worker                            SdpSemantics::kUnifiedPlan),
3506*d9f75844SAndroid Build Coastguard Worker            std::make_tuple(SdpSemantics::kUnifiedPlan,
3507*d9f75844SAndroid Build Coastguard Worker                            SdpSemantics::kPlanB_DEPRECATED)));
3508*d9f75844SAndroid Build Coastguard Worker 
3509*d9f75844SAndroid Build Coastguard Worker // Test that if the Unified Plan side offers two video tracks then the Plan B
3510*d9f75844SAndroid Build Coastguard Worker // side will only see the first one and ignore the second.
TEST_F(PeerConnectionIntegrationTestPlanB,TwoVideoUnifiedPlanToNoMediaPlanB)3511*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
3512*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
3513*d9f75844SAndroid Build Coastguard Worker       SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
3514*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3515*d9f75844SAndroid Build Coastguard Worker   auto first_sender = caller()->AddVideoTrack();
3516*d9f75844SAndroid Build Coastguard Worker   caller()->AddVideoTrack();
3517*d9f75844SAndroid Build Coastguard Worker 
3518*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3519*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3520*d9f75844SAndroid Build Coastguard Worker 
3521*d9f75844SAndroid Build Coastguard Worker   // Verify that there is only one receiver and it corresponds to the first
3522*d9f75844SAndroid Build Coastguard Worker   // added track.
3523*d9f75844SAndroid Build Coastguard Worker   auto receivers = callee()->pc()->GetReceivers();
3524*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(1u, receivers.size());
3525*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(receivers[0]->track()->enabled());
3526*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3527*d9f75844SAndroid Build Coastguard Worker 
3528*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3529*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeVideo();
3530*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ExpectNewFrames(media_expectations));
3531*d9f75844SAndroid Build Coastguard Worker }
3532*d9f75844SAndroid Build Coastguard Worker 
3533*d9f75844SAndroid Build Coastguard Worker // Test that if the initial offer tagged BUNDLE section is rejected due to its
3534*d9f75844SAndroid Build Coastguard Worker // associated RtpTransceiver being stopped and another transceiver is added,
3535*d9f75844SAndroid Build Coastguard Worker // then renegotiation causes the callee to receive the new video track without
3536*d9f75844SAndroid Build Coastguard Worker // error.
3537*d9f75844SAndroid Build Coastguard Worker // This is a regression test for bugs.webrtc.org/9954
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,ReOfferWithStoppedBundleTaggedTransceiver)3538*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3539*d9f75844SAndroid Build Coastguard Worker        ReOfferWithStoppedBundleTaggedTransceiver) {
3540*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
3541*d9f75844SAndroid Build Coastguard Worker   config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3542*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3543*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3544*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver_or_error =
3545*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3546*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_transceiver_or_error.ok());
3547*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3548*d9f75844SAndroid Build Coastguard Worker 
3549*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3550*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3551*d9f75844SAndroid Build Coastguard Worker   {
3552*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
3553*d9f75844SAndroid Build Coastguard Worker     media_expectations.CalleeExpectsSomeAudio();
3554*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
3555*d9f75844SAndroid Build Coastguard Worker   }
3556*d9f75844SAndroid Build Coastguard Worker 
3557*d9f75844SAndroid Build Coastguard Worker   audio_transceiver->StopInternal();
3558*d9f75844SAndroid Build Coastguard Worker   caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3559*d9f75844SAndroid Build Coastguard Worker 
3560*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3561*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3562*d9f75844SAndroid Build Coastguard Worker   {
3563*d9f75844SAndroid Build Coastguard Worker     MediaExpectations media_expectations;
3564*d9f75844SAndroid Build Coastguard Worker     media_expectations.CalleeExpectsSomeVideo();
3565*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectNewFrames(media_expectations));
3566*d9f75844SAndroid Build Coastguard Worker   }
3567*d9f75844SAndroid Build Coastguard Worker }
3568*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,StopTransceiverRemovesDtlsTransports)3569*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3570*d9f75844SAndroid Build Coastguard Worker        StopTransceiverRemovesDtlsTransports) {
3571*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
3572*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3573*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3574*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver_or_error =
3575*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3576*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_transceiver_or_error.ok());
3577*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3578*d9f75844SAndroid Build Coastguard Worker 
3579*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3580*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3581*d9f75844SAndroid Build Coastguard Worker 
3582*d9f75844SAndroid Build Coastguard Worker   audio_transceiver->StopStandard();
3583*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3584*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3585*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3586*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3587*d9f75844SAndroid Build Coastguard Worker             caller()->pc()->ice_gathering_state());
3588*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(caller()->ice_gathering_state_history(),
3589*d9f75844SAndroid Build Coastguard Worker               ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3590*d9f75844SAndroid Build Coastguard Worker                           PeerConnectionInterface::kIceGatheringComplete,
3591*d9f75844SAndroid Build Coastguard Worker                           PeerConnectionInterface::kIceGatheringNew));
3592*d9f75844SAndroid Build Coastguard Worker }
3593*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,StopTransceiverStopsAndRemovesTransceivers)3594*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3595*d9f75844SAndroid Build Coastguard Worker        StopTransceiverStopsAndRemovesTransceivers) {
3596*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
3597*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3598*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3599*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver_or_error =
3600*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3601*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_transceiver_or_error.ok());
3602*d9f75844SAndroid Build Coastguard Worker   auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3603*d9f75844SAndroid Build Coastguard Worker 
3604*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3605*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3606*d9f75844SAndroid Build Coastguard Worker   caller_transceiver->StopStandard();
3607*d9f75844SAndroid Build Coastguard Worker 
3608*d9f75844SAndroid Build Coastguard Worker   auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3609*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3610*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3611*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3612*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3613*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3614*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3615*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3616*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3617*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller_transceiver->stopped());
3618*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_transceiver->stopped());
3619*d9f75844SAndroid Build Coastguard Worker }
3620*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,StopTransceiverEndsIncomingAudioTrack)3621*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3622*d9f75844SAndroid Build Coastguard Worker        StopTransceiverEndsIncomingAudioTrack) {
3623*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
3624*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3625*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3626*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver_or_error =
3627*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3628*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_transceiver_or_error.ok());
3629*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3630*d9f75844SAndroid Build Coastguard Worker 
3631*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3632*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3633*d9f75844SAndroid Build Coastguard Worker   auto caller_track = audio_transceiver->receiver()->track();
3634*d9f75844SAndroid Build Coastguard Worker   auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3635*d9f75844SAndroid Build Coastguard Worker   audio_transceiver->StopStandard();
3636*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3637*d9f75844SAndroid Build Coastguard Worker             caller_track->state());
3638*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3639*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3640*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3641*d9f75844SAndroid Build Coastguard Worker             callee_track->state());
3642*d9f75844SAndroid Build Coastguard Worker }
3643*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionIntegrationTestUnifiedPlan,StopTransceiverEndsIncomingVideoTrack)3644*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3645*d9f75844SAndroid Build Coastguard Worker        StopTransceiverEndsIncomingVideoTrack) {
3646*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
3647*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3648*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3649*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver_or_error =
3650*d9f75844SAndroid Build Coastguard Worker       caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3651*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_transceiver_or_error.ok());
3652*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3653*d9f75844SAndroid Build Coastguard Worker 
3654*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3655*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3656*d9f75844SAndroid Build Coastguard Worker   auto caller_track = audio_transceiver->receiver()->track();
3657*d9f75844SAndroid Build Coastguard Worker   auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3658*d9f75844SAndroid Build Coastguard Worker   audio_transceiver->StopStandard();
3659*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3660*d9f75844SAndroid Build Coastguard Worker             caller_track->state());
3661*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3662*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3663*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3664*d9f75844SAndroid Build Coastguard Worker             callee_track->state());
3665*d9f75844SAndroid Build Coastguard Worker }
3666*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionIntegrationTest,EndToEndRtpSenderVideoEncoderSelector)3667*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionIntegrationTest, EndToEndRtpSenderVideoEncoderSelector) {
3668*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
3669*d9f75844SAndroid Build Coastguard Worker       CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
3670*d9f75844SAndroid Build Coastguard Worker   ConnectFakeSignaling();
3671*d9f75844SAndroid Build Coastguard Worker   // Add one-directional video, from caller to callee.
3672*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
3673*d9f75844SAndroid Build Coastguard Worker       caller()->CreateLocalVideoTrack();
3674*d9f75844SAndroid Build Coastguard Worker   auto sender = caller()->AddTrack(caller_track);
3675*d9f75844SAndroid Build Coastguard Worker   PeerConnectionInterface::RTCOfferAnswerOptions options;
3676*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_video = 0;
3677*d9f75844SAndroid Build Coastguard Worker   caller()->SetOfferAnswerOptions(options);
3678*d9f75844SAndroid Build Coastguard Worker   caller()->CreateAndSetAndSignalOffer();
3679*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3680*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
3681*d9f75844SAndroid Build Coastguard Worker 
3682*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<MockEncoderSelector> encoder_selector =
3683*d9f75844SAndroid Build Coastguard Worker       std::make_unique<MockEncoderSelector>();
3684*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(*encoder_selector, OnCurrentEncoder);
3685*d9f75844SAndroid Build Coastguard Worker 
3686*d9f75844SAndroid Build Coastguard Worker   sender->SetEncoderSelector(std::move(encoder_selector));
3687*d9f75844SAndroid Build Coastguard Worker 
3688*d9f75844SAndroid Build Coastguard Worker   // Expect video to be received in one direction.
3689*d9f75844SAndroid Build Coastguard Worker   MediaExpectations media_expectations;
3690*d9f75844SAndroid Build Coastguard Worker   media_expectations.CallerExpectsNoVideo();
3691*d9f75844SAndroid Build Coastguard Worker   media_expectations.CalleeExpectsSomeVideo();
3692*d9f75844SAndroid Build Coastguard Worker 
3693*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ExpectNewFrames(media_expectations));
3694*d9f75844SAndroid Build Coastguard Worker }
3695*d9f75844SAndroid Build Coastguard Worker 
3696*d9f75844SAndroid Build Coastguard Worker }  // namespace
3697*d9f75844SAndroid Build Coastguard Worker 
3698*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
3699