xref: /aosp_15_r20/external/webrtc/pc/peer_connection_signaling_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2017 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 // This file contains tests that check the PeerConnection's signaling state
12*d9f75844SAndroid Build Coastguard Worker // machine, as well as tests that check basic, media-agnostic aspects of SDP.
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
15*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
16*d9f75844SAndroid Build Coastguard Worker #include <functional>
17*d9f75844SAndroid Build Coastguard Worker #include <map>
18*d9f75844SAndroid Build Coastguard Worker #include <memory>
19*d9f75844SAndroid Build Coastguard Worker #include <set>
20*d9f75844SAndroid Build Coastguard Worker #include <string>
21*d9f75844SAndroid Build Coastguard Worker #include <tuple>
22*d9f75844SAndroid Build Coastguard Worker #include <type_traits>
23*d9f75844SAndroid Build Coastguard Worker #include <utility>
24*d9f75844SAndroid Build Coastguard Worker #include <vector>
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_mixer.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/create_peerconnection_factory.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/dtls_transport_interface.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/jsep.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/media_types.h"
34*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
35*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h"
36*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_receiver_interface.h"
37*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_sender_interface.h"
38*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_transceiver_interface.h"
39*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
40*d9f75844SAndroid Build Coastguard Worker #include "api/set_local_description_observer_interface.h"
41*d9f75844SAndroid Build Coastguard Worker #include "api/set_remote_description_observer_interface.h"
42*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_decoder_factory.h"
43*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_encoder_factory.h"
44*d9f75844SAndroid Build Coastguard Worker #include "media/base/codec.h"
45*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/audio_device.h"
46*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
47*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
48*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection.h"
49*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_proxy.h"
50*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_wrapper.h"
51*d9f75844SAndroid Build Coastguard Worker #include "pc/sdp_utils.h"
52*d9f75844SAndroid Build Coastguard Worker #include "pc/session_description.h"
53*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_peer_connection_observers.h"
54*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
55*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate.h"
56*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate_generator.h"
57*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/string_encode.h"
58*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
59*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
60*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
61*d9f75844SAndroid Build Coastguard Worker #include "pc/test/android_test_initializer.h"
62*d9f75844SAndroid Build Coastguard Worker #endif
63*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_audio_capture_module.h"
64*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_rtc_certificate_generator.h"
65*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
66*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/virtual_socket_server.h"
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
69*d9f75844SAndroid Build Coastguard Worker 
70*d9f75844SAndroid Build Coastguard Worker using SignalingState = PeerConnectionInterface::SignalingState;
71*d9f75844SAndroid Build Coastguard Worker using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
72*d9f75844SAndroid Build Coastguard Worker using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
73*d9f75844SAndroid Build Coastguard Worker using ::testing::Bool;
74*d9f75844SAndroid Build Coastguard Worker using ::testing::Combine;
75*d9f75844SAndroid Build Coastguard Worker using ::testing::Values;
76*d9f75844SAndroid Build Coastguard Worker 
77*d9f75844SAndroid Build Coastguard Worker namespace {
78*d9f75844SAndroid Build Coastguard Worker const int64_t kWaitTimeout = 10000;
79*d9f75844SAndroid Build Coastguard Worker }  // namespace
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
82*d9f75844SAndroid Build Coastguard Worker  public:
83*d9f75844SAndroid Build Coastguard Worker   using PeerConnectionWrapper::PeerConnectionWrapper;
84*d9f75844SAndroid Build Coastguard Worker 
initial_offerer()85*d9f75844SAndroid Build Coastguard Worker   bool initial_offerer() {
86*d9f75844SAndroid Build Coastguard Worker     return GetInternalPeerConnection()->initial_offerer();
87*d9f75844SAndroid Build Coastguard Worker   }
88*d9f75844SAndroid Build Coastguard Worker 
GetInternalPeerConnection()89*d9f75844SAndroid Build Coastguard Worker   PeerConnection* GetInternalPeerConnection() {
90*d9f75844SAndroid Build Coastguard Worker     auto* pci =
91*d9f75844SAndroid Build Coastguard Worker         static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
92*d9f75844SAndroid Build Coastguard Worker             pc());
93*d9f75844SAndroid Build Coastguard Worker     return static_cast<PeerConnection*>(pci->internal());
94*d9f75844SAndroid Build Coastguard Worker   }
95*d9f75844SAndroid Build Coastguard Worker };
96*d9f75844SAndroid Build Coastguard Worker 
97*d9f75844SAndroid Build Coastguard Worker class ExecuteFunctionOnCreateSessionDescriptionObserver
98*d9f75844SAndroid Build Coastguard Worker     : public CreateSessionDescriptionObserver {
99*d9f75844SAndroid Build Coastguard Worker  public:
ExecuteFunctionOnCreateSessionDescriptionObserver(std::function<void (SessionDescriptionInterface *)> function)100*d9f75844SAndroid Build Coastguard Worker   ExecuteFunctionOnCreateSessionDescriptionObserver(
101*d9f75844SAndroid Build Coastguard Worker       std::function<void(SessionDescriptionInterface*)> function)
102*d9f75844SAndroid Build Coastguard Worker       : function_(std::move(function)) {}
~ExecuteFunctionOnCreateSessionDescriptionObserver()103*d9f75844SAndroid Build Coastguard Worker   ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
104*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(was_called_);
105*d9f75844SAndroid Build Coastguard Worker   }
106*d9f75844SAndroid Build Coastguard Worker 
was_called() const107*d9f75844SAndroid Build Coastguard Worker   bool was_called() const { return was_called_; }
108*d9f75844SAndroid Build Coastguard Worker 
OnSuccess(SessionDescriptionInterface * desc)109*d9f75844SAndroid Build Coastguard Worker   void OnSuccess(SessionDescriptionInterface* desc) override {
110*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(!was_called_);
111*d9f75844SAndroid Build Coastguard Worker     was_called_ = true;
112*d9f75844SAndroid Build Coastguard Worker     function_(desc);
113*d9f75844SAndroid Build Coastguard Worker   }
114*d9f75844SAndroid Build Coastguard Worker 
OnFailure(RTCError error)115*d9f75844SAndroid Build Coastguard Worker   void OnFailure(RTCError error) override { RTC_DCHECK_NOTREACHED(); }
116*d9f75844SAndroid Build Coastguard Worker 
117*d9f75844SAndroid Build Coastguard Worker  private:
118*d9f75844SAndroid Build Coastguard Worker   bool was_called_ = false;
119*d9f75844SAndroid Build Coastguard Worker   std::function<void(SessionDescriptionInterface*)> function_;
120*d9f75844SAndroid Build Coastguard Worker };
121*d9f75844SAndroid Build Coastguard Worker 
122*d9f75844SAndroid Build Coastguard Worker class PeerConnectionSignalingBaseTest : public ::testing::Test {
123*d9f75844SAndroid Build Coastguard Worker  protected:
124*d9f75844SAndroid Build Coastguard Worker   typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
125*d9f75844SAndroid Build Coastguard Worker 
PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)126*d9f75844SAndroid Build Coastguard Worker   explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
127*d9f75844SAndroid Build Coastguard Worker       : vss_(new rtc::VirtualSocketServer()),
128*d9f75844SAndroid Build Coastguard Worker         main_(vss_.get()),
129*d9f75844SAndroid Build Coastguard Worker         sdp_semantics_(sdp_semantics) {
130*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
131*d9f75844SAndroid Build Coastguard Worker     InitializeAndroidObjects();
132*d9f75844SAndroid Build Coastguard Worker #endif
133*d9f75844SAndroid Build Coastguard Worker     pc_factory_ = CreatePeerConnectionFactory(
134*d9f75844SAndroid Build Coastguard Worker         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
135*d9f75844SAndroid Build Coastguard Worker         rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
136*d9f75844SAndroid Build Coastguard Worker         CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
137*d9f75844SAndroid Build Coastguard Worker         CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
138*d9f75844SAndroid Build Coastguard Worker         nullptr /* audio_mixer */, nullptr /* audio_processing */);
139*d9f75844SAndroid Build Coastguard Worker   }
140*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection()141*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnection() {
142*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnection(RTCConfiguration());
143*d9f75844SAndroid Build Coastguard Worker   }
144*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection(const RTCConfiguration & config)145*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
146*d9f75844SAndroid Build Coastguard Worker     auto observer = std::make_unique<MockPeerConnectionObserver>();
147*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration modified_config = config;
148*d9f75844SAndroid Build Coastguard Worker     modified_config.sdp_semantics = sdp_semantics_;
149*d9f75844SAndroid Build Coastguard Worker     auto result = pc_factory_->CreatePeerConnectionOrError(
150*d9f75844SAndroid Build Coastguard Worker         modified_config, PeerConnectionDependencies(observer.get()));
151*d9f75844SAndroid Build Coastguard Worker     if (!result.ok()) {
152*d9f75844SAndroid Build Coastguard Worker       return nullptr;
153*d9f75844SAndroid Build Coastguard Worker     }
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker     observer->SetPeerConnectionInterface(result.value().get());
156*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<PeerConnectionWrapperForSignalingTest>(
157*d9f75844SAndroid Build Coastguard Worker         pc_factory_, result.MoveValue(), std::move(observer));
158*d9f75844SAndroid Build Coastguard Worker   }
159*d9f75844SAndroid Build Coastguard Worker 
160*d9f75844SAndroid Build Coastguard Worker   // Accepts the same arguments as CreatePeerConnection and adds default audio
161*d9f75844SAndroid Build Coastguard Worker   // and video tracks.
162*d9f75844SAndroid Build Coastguard Worker   template <typename... Args>
CreatePeerConnectionWithAudioVideo(Args &&...args)163*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
164*d9f75844SAndroid Build Coastguard Worker     auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
165*d9f75844SAndroid Build Coastguard Worker     if (!wrapper) {
166*d9f75844SAndroid Build Coastguard Worker       return nullptr;
167*d9f75844SAndroid Build Coastguard Worker     }
168*d9f75844SAndroid Build Coastguard Worker     wrapper->AddAudioTrack("a");
169*d9f75844SAndroid Build Coastguard Worker     wrapper->AddVideoTrack("v");
170*d9f75844SAndroid Build Coastguard Worker     return wrapper;
171*d9f75844SAndroid Build Coastguard Worker   }
172*d9f75844SAndroid Build Coastguard Worker 
NumberOfDtlsTransports(const WrapperPtr & pc_wrapper)173*d9f75844SAndroid Build Coastguard Worker   int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
174*d9f75844SAndroid Build Coastguard Worker     std::set<DtlsTransportInterface*> transports;
175*d9f75844SAndroid Build Coastguard Worker     auto transceivers = pc_wrapper->pc()->GetTransceivers();
176*d9f75844SAndroid Build Coastguard Worker 
177*d9f75844SAndroid Build Coastguard Worker     for (auto& transceiver : transceivers) {
178*d9f75844SAndroid Build Coastguard Worker       if (transceiver->sender()->dtls_transport()) {
179*d9f75844SAndroid Build Coastguard Worker         EXPECT_TRUE(transceiver->receiver()->dtls_transport());
180*d9f75844SAndroid Build Coastguard Worker         EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
181*d9f75844SAndroid Build Coastguard Worker                   transceiver->receiver()->dtls_transport().get());
182*d9f75844SAndroid Build Coastguard Worker         transports.insert(transceiver->sender()->dtls_transport().get());
183*d9f75844SAndroid Build Coastguard Worker       } else {
184*d9f75844SAndroid Build Coastguard Worker         // If one transceiver is missing, they all should be.
185*d9f75844SAndroid Build Coastguard Worker         EXPECT_EQ(0UL, transports.size());
186*d9f75844SAndroid Build Coastguard Worker       }
187*d9f75844SAndroid Build Coastguard Worker     }
188*d9f75844SAndroid Build Coastguard Worker     return transports.size();
189*d9f75844SAndroid Build Coastguard Worker   }
190*d9f75844SAndroid Build Coastguard Worker 
HasDtlsTransport(const WrapperPtr & pc_wrapper)191*d9f75844SAndroid Build Coastguard Worker   bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
192*d9f75844SAndroid Build Coastguard Worker     return NumberOfDtlsTransports(pc_wrapper) > 0;
193*d9f75844SAndroid Build Coastguard Worker   }
194*d9f75844SAndroid Build Coastguard Worker 
195*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::VirtualSocketServer> vss_;
196*d9f75844SAndroid Build Coastguard Worker   rtc::AutoSocketServerThread main_;
197*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
198*d9f75844SAndroid Build Coastguard Worker   const SdpSemantics sdp_semantics_;
199*d9f75844SAndroid Build Coastguard Worker };
200*d9f75844SAndroid Build Coastguard Worker 
201*d9f75844SAndroid Build Coastguard Worker class PeerConnectionSignalingTest
202*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionSignalingBaseTest,
203*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<SdpSemantics> {
204*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionSignalingTest()205*d9f75844SAndroid Build Coastguard Worker   PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
206*d9f75844SAndroid Build Coastguard Worker };
207*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,SetLocalOfferTwiceWorks)208*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
209*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
210*d9f75844SAndroid Build Coastguard Worker 
211*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
212*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
213*d9f75844SAndroid Build Coastguard Worker }
214*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,SetRemoteOfferTwiceWorks)215*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
216*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
217*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
218*d9f75844SAndroid Build Coastguard Worker 
219*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
220*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
221*d9f75844SAndroid Build Coastguard Worker }
222*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,FailToSetNullLocalDescription)223*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
224*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
225*d9f75844SAndroid Build Coastguard Worker   std::string error;
226*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
227*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("SessionDescription is NULL.", error);
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,FailToSetNullRemoteDescription)230*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
231*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
232*d9f75844SAndroid Build Coastguard Worker   std::string error;
233*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
234*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("SessionDescription is NULL.", error);
235*d9f75844SAndroid Build Coastguard Worker }
236*d9f75844SAndroid Build Coastguard Worker 
237*d9f75844SAndroid Build Coastguard Worker // The following parameterized test verifies that calls to various signaling
238*d9f75844SAndroid Build Coastguard Worker // methods on PeerConnection will succeed/fail depending on what is the
239*d9f75844SAndroid Build Coastguard Worker // PeerConnection's signaling state. Note that the test tries many different
240*d9f75844SAndroid Build Coastguard Worker // forms of SignalingState::kClosed by arriving at a valid state then calling
241*d9f75844SAndroid Build Coastguard Worker // `Close()`. This is intended to catch cases where the PeerConnection signaling
242*d9f75844SAndroid Build Coastguard Worker // method ignores the closed flag but may work/not work because of the single
243*d9f75844SAndroid Build Coastguard Worker // state the PeerConnection was created in before it was closed.
244*d9f75844SAndroid Build Coastguard Worker 
245*d9f75844SAndroid Build Coastguard Worker class PeerConnectionSignalingStateTest
246*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionSignalingBaseTest,
247*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<
248*d9f75844SAndroid Build Coastguard Worker           std::tuple<SdpSemantics, SignalingState, bool>> {
249*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionSignalingStateTest()250*d9f75844SAndroid Build Coastguard Worker   PeerConnectionSignalingStateTest()
251*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
252*d9f75844SAndroid Build Coastguard Worker         state_under_test_(std::make_tuple(std::get<1>(GetParam()),
253*d9f75844SAndroid Build Coastguard Worker                                           std::get<2>(GetParam()))) {}
254*d9f75844SAndroid Build Coastguard Worker 
GetConfig()255*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration GetConfig() {
256*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration config;
257*d9f75844SAndroid Build Coastguard Worker     config.certificates.push_back(
258*d9f75844SAndroid Build Coastguard Worker         FakeRTCCertificateGenerator::GenerateCertificate());
259*d9f75844SAndroid Build Coastguard Worker     return config;
260*d9f75844SAndroid Build Coastguard Worker   }
261*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionUnderTest()262*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnectionUnderTest() {
263*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnectionInState(state_under_test_);
264*d9f75844SAndroid Build Coastguard Worker   }
265*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionInState(SignalingState state)266*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnectionInState(SignalingState state) {
267*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnectionInState(std::make_tuple(state, false));
268*d9f75844SAndroid Build Coastguard Worker   }
269*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnectionInState(std::tuple<SignalingState,bool> state_tuple)270*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnectionInState(
271*d9f75844SAndroid Build Coastguard Worker       std::tuple<SignalingState, bool> state_tuple) {
272*d9f75844SAndroid Build Coastguard Worker     SignalingState state = std::get<0>(state_tuple);
273*d9f75844SAndroid Build Coastguard Worker     bool closed = std::get<1>(state_tuple);
274*d9f75844SAndroid Build Coastguard Worker 
275*d9f75844SAndroid Build Coastguard Worker     auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
276*d9f75844SAndroid Build Coastguard Worker     switch (state) {
277*d9f75844SAndroid Build Coastguard Worker       case SignalingState::kStable: {
278*d9f75844SAndroid Build Coastguard Worker         break;
279*d9f75844SAndroid Build Coastguard Worker       }
280*d9f75844SAndroid Build Coastguard Worker       case SignalingState::kHaveLocalOffer: {
281*d9f75844SAndroid Build Coastguard Worker         wrapper->SetLocalDescription(wrapper->CreateOffer());
282*d9f75844SAndroid Build Coastguard Worker         break;
283*d9f75844SAndroid Build Coastguard Worker       }
284*d9f75844SAndroid Build Coastguard Worker       case SignalingState::kHaveLocalPrAnswer: {
285*d9f75844SAndroid Build Coastguard Worker         auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
286*d9f75844SAndroid Build Coastguard Worker         wrapper->SetRemoteDescription(caller->CreateOffer());
287*d9f75844SAndroid Build Coastguard Worker         auto answer = wrapper->CreateAnswer();
288*d9f75844SAndroid Build Coastguard Worker         wrapper->SetLocalDescription(
289*d9f75844SAndroid Build Coastguard Worker             CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
290*d9f75844SAndroid Build Coastguard Worker         break;
291*d9f75844SAndroid Build Coastguard Worker       }
292*d9f75844SAndroid Build Coastguard Worker       case SignalingState::kHaveRemoteOffer: {
293*d9f75844SAndroid Build Coastguard Worker         auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
294*d9f75844SAndroid Build Coastguard Worker         wrapper->SetRemoteDescription(caller->CreateOffer());
295*d9f75844SAndroid Build Coastguard Worker         break;
296*d9f75844SAndroid Build Coastguard Worker       }
297*d9f75844SAndroid Build Coastguard Worker       case SignalingState::kHaveRemotePrAnswer: {
298*d9f75844SAndroid Build Coastguard Worker         auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
299*d9f75844SAndroid Build Coastguard Worker         callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
300*d9f75844SAndroid Build Coastguard Worker         auto answer = callee->CreateAnswer();
301*d9f75844SAndroid Build Coastguard Worker         wrapper->SetRemoteDescription(
302*d9f75844SAndroid Build Coastguard Worker             CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
303*d9f75844SAndroid Build Coastguard Worker         break;
304*d9f75844SAndroid Build Coastguard Worker       }
305*d9f75844SAndroid Build Coastguard Worker       case SignalingState::kClosed: {
306*d9f75844SAndroid Build Coastguard Worker         RTC_DCHECK_NOTREACHED()
307*d9f75844SAndroid Build Coastguard Worker             << "Set the second member of the tuple to true to "
308*d9f75844SAndroid Build Coastguard Worker                "achieve a closed state from an existing, valid "
309*d9f75844SAndroid Build Coastguard Worker                "state.";
310*d9f75844SAndroid Build Coastguard Worker       }
311*d9f75844SAndroid Build Coastguard Worker     }
312*d9f75844SAndroid Build Coastguard Worker 
313*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
314*d9f75844SAndroid Build Coastguard Worker 
315*d9f75844SAndroid Build Coastguard Worker     if (closed) {
316*d9f75844SAndroid Build Coastguard Worker       wrapper->pc()->Close();
317*d9f75844SAndroid Build Coastguard Worker       RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
318*d9f75844SAndroid Build Coastguard Worker     }
319*d9f75844SAndroid Build Coastguard Worker 
320*d9f75844SAndroid Build Coastguard Worker     return wrapper;
321*d9f75844SAndroid Build Coastguard Worker   }
322*d9f75844SAndroid Build Coastguard Worker 
323*d9f75844SAndroid Build Coastguard Worker   std::tuple<SignalingState, bool> state_under_test_;
324*d9f75844SAndroid Build Coastguard Worker };
325*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,CreateOffer)326*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
327*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
328*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() != SignalingState::kClosed) {
329*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->CreateOffer());
330*d9f75844SAndroid Build Coastguard Worker   } else {
331*d9f75844SAndroid Build Coastguard Worker     std::string error;
332*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
333*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(AssertStartsWith, error,
334*d9f75844SAndroid Build Coastguard Worker                         "CreateOffer called when PeerConnection is closed.");
335*d9f75844SAndroid Build Coastguard Worker   }
336*d9f75844SAndroid Build Coastguard Worker }
337*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,CreateAnswer)338*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
339*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
340*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
341*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
342*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->CreateAnswer());
343*d9f75844SAndroid Build Coastguard Worker   } else {
344*d9f75844SAndroid Build Coastguard Worker     std::string error;
345*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
346*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(error,
347*d9f75844SAndroid Build Coastguard Worker               "PeerConnection cannot create an answer in a state other than "
348*d9f75844SAndroid Build Coastguard Worker               "have-remote-offer or have-local-pranswer.");
349*d9f75844SAndroid Build Coastguard Worker   }
350*d9f75844SAndroid Build Coastguard Worker }
351*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,SetLocalOffer)352*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
353*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
354*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kStable ||
355*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
356*d9f75844SAndroid Build Coastguard Worker     // Need to call CreateOffer on the PeerConnection under test, otherwise when
357*d9f75844SAndroid Build Coastguard Worker     // setting the local offer it will want to verify the DTLS fingerprint
358*d9f75844SAndroid Build Coastguard Worker     // against the locally generated certificate, but without a call to
359*d9f75844SAndroid Build Coastguard Worker     // CreateOffer the certificate will never be generated.
360*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
361*d9f75844SAndroid Build Coastguard Worker   } else {
362*d9f75844SAndroid Build Coastguard Worker     auto wrapper_for_offer =
363*d9f75844SAndroid Build Coastguard Worker         CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
364*d9f75844SAndroid Build Coastguard Worker     auto offer =
365*d9f75844SAndroid Build Coastguard Worker         CloneSessionDescription(wrapper_for_offer->pc()->local_description());
366*d9f75844SAndroid Build Coastguard Worker 
367*d9f75844SAndroid Build Coastguard Worker     std::string error;
368*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
369*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(
370*d9f75844SAndroid Build Coastguard Worker         AssertStartsWith, error,
371*d9f75844SAndroid Build Coastguard Worker         "Failed to set local offer sdp: Called in wrong state:");
372*d9f75844SAndroid Build Coastguard Worker   }
373*d9f75844SAndroid Build Coastguard Worker }
374*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,SetLocalPrAnswer)375*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
376*d9f75844SAndroid Build Coastguard Worker   auto wrapper_for_pranswer =
377*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
378*d9f75844SAndroid Build Coastguard Worker   auto pranswer =
379*d9f75844SAndroid Build Coastguard Worker       CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
380*d9f75844SAndroid Build Coastguard Worker 
381*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
382*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
383*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
384*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
385*d9f75844SAndroid Build Coastguard Worker   } else {
386*d9f75844SAndroid Build Coastguard Worker     std::string error;
387*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
388*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(
389*d9f75844SAndroid Build Coastguard Worker         AssertStartsWith, error,
390*d9f75844SAndroid Build Coastguard Worker         "Failed to set local pranswer sdp: Called in wrong state:");
391*d9f75844SAndroid Build Coastguard Worker   }
392*d9f75844SAndroid Build Coastguard Worker }
393*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,SetLocalAnswer)394*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
395*d9f75844SAndroid Build Coastguard Worker   auto wrapper_for_answer =
396*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
397*d9f75844SAndroid Build Coastguard Worker   auto answer = wrapper_for_answer->CreateAnswer();
398*d9f75844SAndroid Build Coastguard Worker 
399*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
400*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
401*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
402*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
403*d9f75844SAndroid Build Coastguard Worker   } else {
404*d9f75844SAndroid Build Coastguard Worker     std::string error;
405*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
406*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(
407*d9f75844SAndroid Build Coastguard Worker         AssertStartsWith, error,
408*d9f75844SAndroid Build Coastguard Worker         "Failed to set local answer sdp: Called in wrong state:");
409*d9f75844SAndroid Build Coastguard Worker   }
410*d9f75844SAndroid Build Coastguard Worker }
411*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,SetRemoteOffer)412*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
413*d9f75844SAndroid Build Coastguard Worker   auto wrapper_for_offer =
414*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
415*d9f75844SAndroid Build Coastguard Worker   auto offer =
416*d9f75844SAndroid Build Coastguard Worker       CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
417*d9f75844SAndroid Build Coastguard Worker 
418*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
419*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kStable ||
420*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
421*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
422*d9f75844SAndroid Build Coastguard Worker   } else {
423*d9f75844SAndroid Build Coastguard Worker     std::string error;
424*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
425*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(
426*d9f75844SAndroid Build Coastguard Worker         AssertStartsWith, error,
427*d9f75844SAndroid Build Coastguard Worker         "Failed to set remote offer sdp: Called in wrong state:");
428*d9f75844SAndroid Build Coastguard Worker   }
429*d9f75844SAndroid Build Coastguard Worker }
430*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,SetRemotePrAnswer)431*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
432*d9f75844SAndroid Build Coastguard Worker   auto wrapper_for_pranswer =
433*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
434*d9f75844SAndroid Build Coastguard Worker   auto pranswer =
435*d9f75844SAndroid Build Coastguard Worker       CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
436*d9f75844SAndroid Build Coastguard Worker 
437*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
438*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
439*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
440*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
441*d9f75844SAndroid Build Coastguard Worker   } else {
442*d9f75844SAndroid Build Coastguard Worker     std::string error;
443*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
444*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(
445*d9f75844SAndroid Build Coastguard Worker         AssertStartsWith, error,
446*d9f75844SAndroid Build Coastguard Worker         "Failed to set remote pranswer sdp: Called in wrong state:");
447*d9f75844SAndroid Build Coastguard Worker   }
448*d9f75844SAndroid Build Coastguard Worker }
449*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingStateTest,SetRemoteAnswer)450*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
451*d9f75844SAndroid Build Coastguard Worker   auto wrapper_for_answer =
452*d9f75844SAndroid Build Coastguard Worker       CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
453*d9f75844SAndroid Build Coastguard Worker   auto answer = wrapper_for_answer->CreateAnswer();
454*d9f75844SAndroid Build Coastguard Worker 
455*d9f75844SAndroid Build Coastguard Worker   auto wrapper = CreatePeerConnectionUnderTest();
456*d9f75844SAndroid Build Coastguard Worker   if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
457*d9f75844SAndroid Build Coastguard Worker       wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
458*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
459*d9f75844SAndroid Build Coastguard Worker   } else {
460*d9f75844SAndroid Build Coastguard Worker     std::string error;
461*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
462*d9f75844SAndroid Build Coastguard Worker     EXPECT_PRED_FORMAT2(
463*d9f75844SAndroid Build Coastguard Worker         AssertStartsWith, error,
464*d9f75844SAndroid Build Coastguard Worker         "Failed to set remote answer sdp: Called in wrong state:");
465*d9f75844SAndroid Build Coastguard Worker   }
466*d9f75844SAndroid Build Coastguard Worker }
467*d9f75844SAndroid Build Coastguard Worker 
468*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
469*d9f75844SAndroid Build Coastguard Worker                          PeerConnectionSignalingStateTest,
470*d9f75844SAndroid Build Coastguard Worker                          Combine(Values(SdpSemantics::kPlanB_DEPRECATED,
471*d9f75844SAndroid Build Coastguard Worker                                         SdpSemantics::kUnifiedPlan),
472*d9f75844SAndroid Build Coastguard Worker                                  Values(SignalingState::kStable,
473*d9f75844SAndroid Build Coastguard Worker                                         SignalingState::kHaveLocalOffer,
474*d9f75844SAndroid Build Coastguard Worker                                         SignalingState::kHaveLocalPrAnswer,
475*d9f75844SAndroid Build Coastguard Worker                                         SignalingState::kHaveRemoteOffer,
476*d9f75844SAndroid Build Coastguard Worker                                         SignalingState::kHaveRemotePrAnswer),
477*d9f75844SAndroid Build Coastguard Worker                                  Bool()));
478*d9f75844SAndroid Build Coastguard Worker 
479*d9f75844SAndroid Build Coastguard Worker // Test that CreateAnswer fails if a round of offer/answer has been done and
480*d9f75844SAndroid Build Coastguard Worker // the PeerConnection is in the stable state.
TEST_P(PeerConnectionSignalingTest,CreateAnswerFailsIfStable)481*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
482*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
483*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
484*d9f75844SAndroid Build Coastguard Worker 
485*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
486*d9f75844SAndroid Build Coastguard Worker 
487*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
488*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->CreateAnswer());
489*d9f75844SAndroid Build Coastguard Worker 
490*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
491*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->CreateAnswer());
492*d9f75844SAndroid Build Coastguard Worker }
493*d9f75844SAndroid Build Coastguard Worker 
494*d9f75844SAndroid Build Coastguard Worker // According to https://tools.ietf.org/html/rfc3264#section-8, the session id
495*d9f75844SAndroid Build Coastguard Worker // stays the same but the version must be incremented if a later, different
496*d9f75844SAndroid Build Coastguard Worker // session description is generated. These two tests verify that is the case for
497*d9f75844SAndroid Build Coastguard Worker // both offers and answers.
TEST_P(PeerConnectionSignalingTest,SessionVersionIncrementedInSubsequentDifferentOffer)498*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
499*d9f75844SAndroid Build Coastguard Worker        SessionVersionIncrementedInSubsequentDifferentOffer) {
500*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
501*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
502*d9f75844SAndroid Build Coastguard Worker 
503*d9f75844SAndroid Build Coastguard Worker   auto original_offer = caller->CreateOfferAndSetAsLocal();
504*d9f75844SAndroid Build Coastguard Worker   const std::string original_id = original_offer->session_id();
505*d9f75844SAndroid Build Coastguard Worker   const std::string original_version = original_offer->session_version();
506*d9f75844SAndroid Build Coastguard Worker 
507*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
508*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
509*d9f75844SAndroid Build Coastguard Worker 
510*d9f75844SAndroid Build Coastguard Worker   // Add track to get a different offer.
511*d9f75844SAndroid Build Coastguard Worker   caller->AddAudioTrack("a");
512*d9f75844SAndroid Build Coastguard Worker 
513*d9f75844SAndroid Build Coastguard Worker   auto later_offer = caller->CreateOffer();
514*d9f75844SAndroid Build Coastguard Worker 
515*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(original_id, later_offer->session_id());
516*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(rtc::FromString<uint64_t>(original_version),
517*d9f75844SAndroid Build Coastguard Worker             rtc::FromString<uint64_t>(later_offer->session_version()));
518*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionSignalingTest,SessionVersionIncrementedInSubsequentDifferentAnswer)519*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
520*d9f75844SAndroid Build Coastguard Worker        SessionVersionIncrementedInSubsequentDifferentAnswer) {
521*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
522*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
523*d9f75844SAndroid Build Coastguard Worker 
524*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
525*d9f75844SAndroid Build Coastguard Worker 
526*d9f75844SAndroid Build Coastguard Worker   auto original_answer = callee->CreateAnswer();
527*d9f75844SAndroid Build Coastguard Worker   const std::string original_id = original_answer->session_id();
528*d9f75844SAndroid Build Coastguard Worker   const std::string original_version = original_answer->session_version();
529*d9f75844SAndroid Build Coastguard Worker 
530*d9f75844SAndroid Build Coastguard Worker   // Add track to get a different answer.
531*d9f75844SAndroid Build Coastguard Worker   callee->AddAudioTrack("a");
532*d9f75844SAndroid Build Coastguard Worker 
533*d9f75844SAndroid Build Coastguard Worker   auto later_answer = callee->CreateAnswer();
534*d9f75844SAndroid Build Coastguard Worker 
535*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(original_id, later_answer->session_id());
536*d9f75844SAndroid Build Coastguard Worker   EXPECT_LT(rtc::FromString<uint64_t>(original_version),
537*d9f75844SAndroid Build Coastguard Worker             rtc::FromString<uint64_t>(later_answer->session_version()));
538*d9f75844SAndroid Build Coastguard Worker }
539*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,InitiatorFlagSetOnCallerAndNotOnCallee)540*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
541*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
542*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo();
543*d9f75844SAndroid Build Coastguard Worker 
544*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->initial_offerer());
545*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->initial_offerer());
546*d9f75844SAndroid Build Coastguard Worker 
547*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
548*d9f75844SAndroid Build Coastguard Worker 
549*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->initial_offerer());
550*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->initial_offerer());
551*d9f75844SAndroid Build Coastguard Worker 
552*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
553*d9f75844SAndroid Build Coastguard Worker       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
554*d9f75844SAndroid Build Coastguard Worker 
555*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->initial_offerer());
556*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->initial_offerer());
557*d9f75844SAndroid Build Coastguard Worker }
558*d9f75844SAndroid Build Coastguard Worker 
559*d9f75844SAndroid Build Coastguard Worker // Test creating a PeerConnection, request multiple offers, destroy the
560*d9f75844SAndroid Build Coastguard Worker // PeerConnection and make sure we get success/failure callbacks for all of the
561*d9f75844SAndroid Build Coastguard Worker // requests.
562*d9f75844SAndroid Build Coastguard Worker // Background: crbug.com/507307
TEST_P(PeerConnectionSignalingTest,CreateOffersAndShutdown)563*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
564*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
565*d9f75844SAndroid Build Coastguard Worker 
566*d9f75844SAndroid Build Coastguard Worker   RTCOfferAnswerOptions options;
567*d9f75844SAndroid Build Coastguard Worker   options.offer_to_receive_audio =
568*d9f75844SAndroid Build Coastguard Worker       RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
569*d9f75844SAndroid Build Coastguard Worker 
570*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
571*d9f75844SAndroid Build Coastguard Worker   for (auto& observer : observers) {
572*d9f75844SAndroid Build Coastguard Worker     observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
573*d9f75844SAndroid Build Coastguard Worker     caller->pc()->CreateOffer(observer.get(), options);
574*d9f75844SAndroid Build Coastguard Worker   }
575*d9f75844SAndroid Build Coastguard Worker 
576*d9f75844SAndroid Build Coastguard Worker   // Destroy the PeerConnection.
577*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
578*d9f75844SAndroid Build Coastguard Worker 
579*d9f75844SAndroid Build Coastguard Worker   for (auto& observer : observers) {
580*d9f75844SAndroid Build Coastguard Worker     // We expect to have received a notification now even if the PeerConnection
581*d9f75844SAndroid Build Coastguard Worker     // was terminated. The offer creation may or may not have succeeded, but we
582*d9f75844SAndroid Build Coastguard Worker     // must have received a notification.
583*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
584*d9f75844SAndroid Build Coastguard Worker   }
585*d9f75844SAndroid Build Coastguard Worker }
586*d9f75844SAndroid Build Coastguard Worker 
587*d9f75844SAndroid Build Coastguard Worker // Similar to the above test, but by closing the PC first the CreateOffer() will
588*d9f75844SAndroid Build Coastguard Worker // fail "early", which triggers a codepath where the PeerConnection is
589*d9f75844SAndroid Build Coastguard Worker // reponsible for invoking the observer, instead of the normal codepath where
590*d9f75844SAndroid Build Coastguard Worker // the WebRtcSessionDescriptionFactory is responsible for it.
TEST_P(PeerConnectionSignalingTest,CloseCreateOfferAndShutdown)591*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, CloseCreateOfferAndShutdown) {
592*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
593*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
594*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
595*d9f75844SAndroid Build Coastguard Worker   caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
596*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
597*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
598*d9f75844SAndroid Build Coastguard Worker }
599*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ImplicitCreateOfferAndShutdownWithOldObserver)600*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
601*d9f75844SAndroid Build Coastguard Worker        ImplicitCreateOfferAndShutdownWithOldObserver) {
602*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
603*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
604*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get());
605*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
606*d9f75844SAndroid Build Coastguard Worker   // The old observer does not get invoked because posted messages are lost.
607*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
608*d9f75844SAndroid Build Coastguard Worker }
609*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ImplicitCreateOfferAndShutdown)610*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
611*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
612*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
613*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer);
614*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
615*d9f75844SAndroid Build Coastguard Worker   // The new observer gets invoked because it is called immediately.
616*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->called());
617*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->error().ok());
618*d9f75844SAndroid Build Coastguard Worker }
619*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver)620*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
621*d9f75844SAndroid Build Coastguard Worker        CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver) {
622*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
623*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
624*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
625*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get());
626*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
627*d9f75844SAndroid Build Coastguard Worker   // The old observer does not get invoked because posted messages are lost.
628*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
629*d9f75844SAndroid Build Coastguard Worker }
630*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,CloseBeforeImplicitCreateOfferAndShutdown)631*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
632*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
633*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
634*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
635*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer);
636*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
637*d9f75844SAndroid Build Coastguard Worker   // The new observer gets invoked because it is called immediately.
638*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->called());
639*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->error().ok());
640*d9f75844SAndroid Build Coastguard Worker }
641*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,CloseAfterImplicitCreateOfferAndShutdownWithOldObserver)642*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
643*d9f75844SAndroid Build Coastguard Worker        CloseAfterImplicitCreateOfferAndShutdownWithOldObserver) {
644*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
645*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
646*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get());
647*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
648*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
649*d9f75844SAndroid Build Coastguard Worker   // The old observer does not get invoked because posted messages are lost.
650*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
651*d9f75844SAndroid Build Coastguard Worker }
652*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,CloseAfterImplicitCreateOfferAndShutdown)653*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
654*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
655*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
656*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer);
657*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
658*d9f75844SAndroid Build Coastguard Worker   caller.reset(nullptr);
659*d9f75844SAndroid Build Coastguard Worker   // The new observer gets invoked because it is called immediately.
660*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->called());
661*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->error().ok());
662*d9f75844SAndroid Build Coastguard Worker }
663*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,SetLocalDescriptionNewObserverIsInvokedImmediately)664*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
665*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionNewObserverIsInvokedImmediately) {
666*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
667*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
668*d9f75844SAndroid Build Coastguard Worker 
669*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
670*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(std::move(offer), observer);
671*d9f75844SAndroid Build Coastguard Worker   // The new observer is invoked immediately.
672*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->called());
673*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->error().ok());
674*d9f75844SAndroid Build Coastguard Worker }
675*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,SetLocalDescriptionOldObserverIsInvokedInAPostedMessage)676*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
677*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionOldObserverIsInvokedInAPostedMessage) {
678*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
679*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
680*d9f75844SAndroid Build Coastguard Worker 
681*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
682*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get(), offer.release());
683*d9f75844SAndroid Build Coastguard Worker   // The old observer is not invoked immediately.
684*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
685*d9f75844SAndroid Build Coastguard Worker   // Process all currently pending messages by waiting for a posted task to run.
686*d9f75844SAndroid Build Coastguard Worker   bool checkpoint_reached = false;
687*d9f75844SAndroid Build Coastguard Worker   rtc::Thread::Current()->PostTask(
688*d9f75844SAndroid Build Coastguard Worker       [&checkpoint_reached] { checkpoint_reached = true; });
689*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(checkpoint_reached, kWaitTimeout);
690*d9f75844SAndroid Build Coastguard Worker   // If resolving the observer was pending, it must now have been called.
691*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->called());
692*d9f75844SAndroid Build Coastguard Worker }
693*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,SetRemoteDescriptionExecutesImmediately)694*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
695*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
696*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
697*d9f75844SAndroid Build Coastguard Worker 
698*d9f75844SAndroid Build Coastguard Worker   // This offer will cause receivers to be created.
699*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
700*d9f75844SAndroid Build Coastguard Worker 
701*d9f75844SAndroid Build Coastguard Worker   // By not waiting for the observer's callback we can verify that the operation
702*d9f75844SAndroid Build Coastguard Worker   // executed immediately.
703*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetRemoteDescription(
704*d9f75844SAndroid Build Coastguard Worker       std::move(offer),
705*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
706*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
707*d9f75844SAndroid Build Coastguard Worker }
708*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,CreateOfferBlocksSetRemoteDescription)709*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
710*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
711*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
712*d9f75844SAndroid Build Coastguard Worker 
713*d9f75844SAndroid Build Coastguard Worker   // This offer will cause receivers to be created.
714*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
715*d9f75844SAndroid Build Coastguard Worker 
716*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
717*d9f75844SAndroid Build Coastguard Worker   auto offer_observer =
718*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
719*d9f75844SAndroid Build Coastguard Worker   // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
720*d9f75844SAndroid Build Coastguard Worker   // SetRemoteDescription() operation should be chained to be executed
721*d9f75844SAndroid Build Coastguard Worker   // asynchronously, when CreateOffer() completes.
722*d9f75844SAndroid Build Coastguard Worker   callee->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
723*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetRemoteDescription(
724*d9f75844SAndroid Build Coastguard Worker       std::move(offer),
725*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
726*d9f75844SAndroid Build Coastguard Worker   // CreateOffer() is asynchronous; without message processing this operation
727*d9f75844SAndroid Build Coastguard Worker   // should not have completed.
728*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(offer_observer->called());
729*d9f75844SAndroid Build Coastguard Worker   // Due to chaining, the receivers should not have been created by the offer
730*d9f75844SAndroid Build Coastguard Worker   // yet.
731*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
732*d9f75844SAndroid Build Coastguard Worker   // EXPECT_TRUE_WAIT causes messages to be processed...
733*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
734*d9f75844SAndroid Build Coastguard Worker   // Now that the offer has been completed, SetRemoteDescription() will have
735*d9f75844SAndroid Build Coastguard Worker   // been executed next in the chain.
736*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
737*d9f75844SAndroid Build Coastguard Worker }
738*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCreatesOffer)739*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
740*d9f75844SAndroid Build Coastguard Worker        ParameterlessSetLocalDescriptionCreatesOffer) {
741*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
742*d9f75844SAndroid Build Coastguard Worker 
743*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
744*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get());
745*d9f75844SAndroid Build Coastguard Worker 
746*d9f75844SAndroid Build Coastguard Worker   // The offer is created asynchronously; message processing is needed for it to
747*d9f75844SAndroid Build Coastguard Worker   // complete.
748*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
749*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->pc()->pending_local_description());
750*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
751*d9f75844SAndroid Build Coastguard Worker 
752*d9f75844SAndroid Build Coastguard Worker   // Wait for messages to be processed.
753*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
754*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->result());
755*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->pending_local_description());
756*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(SdpType::kOffer,
757*d9f75844SAndroid Build Coastguard Worker             caller->pc()->pending_local_description()->GetType());
758*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
759*d9f75844SAndroid Build Coastguard Worker }
760*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCreatesAnswer)761*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
762*d9f75844SAndroid Build Coastguard Worker        ParameterlessSetLocalDescriptionCreatesAnswer) {
763*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
764*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo();
765*d9f75844SAndroid Build Coastguard Worker 
766*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOffer());
767*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());
768*d9f75844SAndroid Build Coastguard Worker 
769*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
770*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetLocalDescription(observer.get());
771*d9f75844SAndroid Build Coastguard Worker 
772*d9f75844SAndroid Build Coastguard Worker   // The answer is created asynchronously; message processing is needed for it
773*d9f75844SAndroid Build Coastguard Worker   // to complete.
774*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
775*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->pc()->current_local_description());
776*d9f75844SAndroid Build Coastguard Worker 
777*d9f75844SAndroid Build Coastguard Worker   // Wait for messages to be processed.
778*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
779*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(observer->result());
780*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->pc()->current_local_description());
781*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(SdpType::kAnswer,
782*d9f75844SAndroid Build Coastguard Worker             callee->pc()->current_local_description()->GetType());
783*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
784*d9f75844SAndroid Build Coastguard Worker }
785*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionFullExchange)786*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
787*d9f75844SAndroid Build Coastguard Worker        ParameterlessSetLocalDescriptionFullExchange) {
788*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
789*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo();
790*d9f75844SAndroid Build Coastguard Worker 
791*d9f75844SAndroid Build Coastguard Worker   // SetLocalDescription(), implicitly creating an offer.
792*d9f75844SAndroid Build Coastguard Worker   auto caller_set_local_description_observer =
793*d9f75844SAndroid Build Coastguard Worker       MockSetSessionDescriptionObserver::Create();
794*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(
795*d9f75844SAndroid Build Coastguard Worker       caller_set_local_description_observer.get());
796*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
797*d9f75844SAndroid Build Coastguard Worker                    kWaitTimeout);
798*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->pc()->pending_local_description());
799*d9f75844SAndroid Build Coastguard Worker 
800*d9f75844SAndroid Build Coastguard Worker   // SetRemoteDescription(offer)
801*d9f75844SAndroid Build Coastguard Worker   auto callee_set_remote_description_observer =
802*d9f75844SAndroid Build Coastguard Worker       MockSetSessionDescriptionObserver::Create();
803*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetRemoteDescription(
804*d9f75844SAndroid Build Coastguard Worker       callee_set_remote_description_observer.get(),
805*d9f75844SAndroid Build Coastguard Worker       CloneSessionDescription(caller->pc()->pending_local_description())
806*d9f75844SAndroid Build Coastguard Worker           .release());
807*d9f75844SAndroid Build Coastguard Worker 
808*d9f75844SAndroid Build Coastguard Worker   // SetLocalDescription(), implicitly creating an answer.
809*d9f75844SAndroid Build Coastguard Worker   auto callee_set_local_description_observer =
810*d9f75844SAndroid Build Coastguard Worker       MockSetSessionDescriptionObserver::Create();
811*d9f75844SAndroid Build Coastguard Worker   callee->pc()->SetLocalDescription(
812*d9f75844SAndroid Build Coastguard Worker       callee_set_local_description_observer.get());
813*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
814*d9f75844SAndroid Build Coastguard Worker                    kWaitTimeout);
815*d9f75844SAndroid Build Coastguard Worker   // Chaining guarantees SetRemoteDescription() happened before
816*d9f75844SAndroid Build Coastguard Worker   // SetLocalDescription().
817*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee_set_remote_description_observer->called());
818*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->pc()->current_local_description());
819*d9f75844SAndroid Build Coastguard Worker 
820*d9f75844SAndroid Build Coastguard Worker   // SetRemoteDescription(answer)
821*d9f75844SAndroid Build Coastguard Worker   auto caller_set_remote_description_observer =
822*d9f75844SAndroid Build Coastguard Worker       MockSetSessionDescriptionObserver::Create();
823*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetRemoteDescription(
824*d9f75844SAndroid Build Coastguard Worker       caller_set_remote_description_observer.get(),
825*d9f75844SAndroid Build Coastguard Worker       CloneSessionDescription(callee->pc()->current_local_description())
826*d9f75844SAndroid Build Coastguard Worker           .release());
827*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
828*d9f75844SAndroid Build Coastguard Worker                    kWaitTimeout);
829*d9f75844SAndroid Build Coastguard Worker 
830*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
831*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
832*d9f75844SAndroid Build Coastguard Worker }
833*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer)834*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
835*d9f75844SAndroid Build Coastguard Worker        ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
836*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
837*d9f75844SAndroid Build Coastguard Worker 
838*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
839*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
840*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get());
841*d9f75844SAndroid Build Coastguard Worker 
842*d9f75844SAndroid Build Coastguard Worker   // The operation should fail asynchronously.
843*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
844*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
845*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->result());
846*d9f75844SAndroid Build Coastguard Worker   // This did not affect the signaling state.
847*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
848*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
849*d9f75844SAndroid Build Coastguard Worker       "SetLocalDescription failed to create session description - "
850*d9f75844SAndroid Build Coastguard Worker       "SetLocalDescription called when PeerConnection is closed.",
851*d9f75844SAndroid Build Coastguard Worker       observer->error());
852*d9f75844SAndroid Build Coastguard Worker }
853*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCloseWhileCreatingOffer)854*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest,
855*d9f75844SAndroid Build Coastguard Worker        ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
856*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
857*d9f75844SAndroid Build Coastguard Worker 
858*d9f75844SAndroid Build Coastguard Worker   auto observer = MockSetSessionDescriptionObserver::Create();
859*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(observer.get());
860*d9f75844SAndroid Build Coastguard Worker   caller->pc()->Close();
861*d9f75844SAndroid Build Coastguard Worker 
862*d9f75844SAndroid Build Coastguard Worker   // The operation should fail asynchronously.
863*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
864*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
865*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->result());
866*d9f75844SAndroid Build Coastguard Worker   // This did not affect the signaling state.
867*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
868*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
869*d9f75844SAndroid Build Coastguard Worker       "SetLocalDescription failed to create session description - "
870*d9f75844SAndroid Build Coastguard Worker       "CreateOffer failed because the session was shut down",
871*d9f75844SAndroid Build Coastguard Worker       observer->error());
872*d9f75844SAndroid Build Coastguard Worker }
873*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,UnsupportedContentType)874*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, UnsupportedContentType) {
875*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
876*d9f75844SAndroid Build Coastguard Worker 
877*d9f75844SAndroid Build Coastguard Worker   // Call setRemoteDescription with a m= line we don't understand.
878*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
879*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
880*d9f75844SAndroid Build Coastguard Worker       "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
881*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
882*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
883*d9f75844SAndroid Build Coastguard Worker       "m=bogus 9 FOO 0 8\r\n"
884*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
885*d9f75844SAndroid Build Coastguard Worker       "a=mid:bogusmid\r\n";
886*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
887*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
888*d9f75844SAndroid Build Coastguard Worker 
889*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
890*d9f75844SAndroid Build Coastguard Worker 
891*d9f75844SAndroid Build Coastguard Worker   // Assert we respond back with something meaningful.
892*d9f75844SAndroid Build Coastguard Worker   auto answer = caller->CreateAnswer();
893*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(answer->description()->contents().size(), 1u);
894*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(answer->description()
895*d9f75844SAndroid Build Coastguard Worker                 ->contents()[0]
896*d9f75844SAndroid Build Coastguard Worker                 .media_description()
897*d9f75844SAndroid Build Coastguard Worker                 ->as_unsupported(),
898*d9f75844SAndroid Build Coastguard Worker             nullptr);
899*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(answer->description()
900*d9f75844SAndroid Build Coastguard Worker                 ->contents()[0]
901*d9f75844SAndroid Build Coastguard Worker                 .media_description()
902*d9f75844SAndroid Build Coastguard Worker                 ->as_unsupported()
903*d9f75844SAndroid Build Coastguard Worker                 ->media_type(),
904*d9f75844SAndroid Build Coastguard Worker             "bogus");
905*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(answer->description()->contents()[0].rejected);
906*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(answer->description()->contents()[0].mid(), "bogusmid");
907*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(
908*d9f75844SAndroid Build Coastguard Worker       answer->description()->contents()[0].media_description()->protocol(),
909*d9f75844SAndroid Build Coastguard Worker       "FOO");
910*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(
911*d9f75844SAndroid Build Coastguard Worker       answer->description()->contents()[0].media_description()->has_codecs());
912*d9f75844SAndroid Build Coastguard Worker 
913*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
914*d9f75844SAndroid Build Coastguard Worker 
915*d9f75844SAndroid Build Coastguard Worker   // Assert we keep this in susequent offers.
916*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
917*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(offer->description()
918*d9f75844SAndroid Build Coastguard Worker                 ->contents()[0]
919*d9f75844SAndroid Build Coastguard Worker                 .media_description()
920*d9f75844SAndroid Build Coastguard Worker                 ->as_unsupported()
921*d9f75844SAndroid Build Coastguard Worker                 ->media_type(),
922*d9f75844SAndroid Build Coastguard Worker             "bogus");
923*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(offer->description()->contents()[0].rejected);
924*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(offer->description()->contents()[0].media_description()->protocol(),
925*d9f75844SAndroid Build Coastguard Worker             "FOO");
926*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(offer->description()->contents()[0].mid(), "bogusmid");
927*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(
928*d9f75844SAndroid Build Coastguard Worker       offer->description()->contents()[0].media_description()->has_codecs());
929*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
930*d9f75844SAndroid Build Coastguard Worker }
931*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ReceiveFlexFec)932*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, ReceiveFlexFec) {
933*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
934*d9f75844SAndroid Build Coastguard Worker 
935*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
936*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
937*d9f75844SAndroid Build Coastguard Worker       "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
938*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
939*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
940*d9f75844SAndroid Build Coastguard Worker       "a=group:BUNDLE 0\r\n"
941*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 102 122\r\n"
942*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
943*d9f75844SAndroid Build Coastguard Worker       "a=rtcp:9 IN IP4 0.0.0.0\r\n"
944*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:IZeV\r\n"
945*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
946*d9f75844SAndroid Build Coastguard Worker       "a=ice-options:trickle\r\n"
947*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-256 "
948*d9f75844SAndroid Build Coastguard Worker       "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
949*d9f75844SAndroid Build Coastguard Worker       "1C:2C:74:01:8D:50:67:23\r\n"
950*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
951*d9f75844SAndroid Build Coastguard Worker       "a=mid:0\r\n"
952*d9f75844SAndroid Build Coastguard Worker       "a=sendrecv\r\n"
953*d9f75844SAndroid Build Coastguard Worker       "a=msid:stream track\r\n"
954*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
955*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-rsize\r\n"
956*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:102 VP8/90000\r\n"
957*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 goog-remb\r\n"
958*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 transport-cc\r\n"
959*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 ccm fir\r\n"
960*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack\r\n"
961*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack pli\r\n"
962*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:122 flexfec-03/90000\r\n"
963*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:122 repair-window=10000000\r\n"
964*d9f75844SAndroid Build Coastguard Worker       "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
965*d9f75844SAndroid Build Coastguard Worker       "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
966*d9f75844SAndroid Build Coastguard Worker       "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
967*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
968*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
969*d9f75844SAndroid Build Coastguard Worker 
970*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
971*d9f75844SAndroid Build Coastguard Worker 
972*d9f75844SAndroid Build Coastguard Worker   auto answer = caller->CreateAnswer();
973*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(answer->description()->contents().size(), 1u);
974*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(
975*d9f75844SAndroid Build Coastguard Worker       answer->description()->contents()[0].media_description()->as_video(),
976*d9f75844SAndroid Build Coastguard Worker       nullptr);
977*d9f75844SAndroid Build Coastguard Worker   auto codecs = answer->description()
978*d9f75844SAndroid Build Coastguard Worker                     ->contents()[0]
979*d9f75844SAndroid Build Coastguard Worker                     .media_description()
980*d9f75844SAndroid Build Coastguard Worker                     ->as_video()
981*d9f75844SAndroid Build Coastguard Worker                     ->codecs();
982*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(codecs.size(), 2u);
983*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(codecs[1].name, "flexfec-03");
984*d9f75844SAndroid Build Coastguard Worker 
985*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
986*d9f75844SAndroid Build Coastguard Worker }
987*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,ReceiveFlexFecReoffer)988*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, ReceiveFlexFecReoffer) {
989*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
990*d9f75844SAndroid Build Coastguard Worker 
991*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
992*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
993*d9f75844SAndroid Build Coastguard Worker       "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
994*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
995*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
996*d9f75844SAndroid Build Coastguard Worker       "a=group:BUNDLE 0\r\n"
997*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 102 35\r\n"
998*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
999*d9f75844SAndroid Build Coastguard Worker       "a=rtcp:9 IN IP4 0.0.0.0\r\n"
1000*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:IZeV\r\n"
1001*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
1002*d9f75844SAndroid Build Coastguard Worker       "a=ice-options:trickle\r\n"
1003*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-256 "
1004*d9f75844SAndroid Build Coastguard Worker       "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
1005*d9f75844SAndroid Build Coastguard Worker       "1C:2C:74:01:8D:50:67:23\r\n"
1006*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
1007*d9f75844SAndroid Build Coastguard Worker       "a=mid:0\r\n"
1008*d9f75844SAndroid Build Coastguard Worker       "a=sendrecv\r\n"
1009*d9f75844SAndroid Build Coastguard Worker       "a=msid:stream track\r\n"
1010*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
1011*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-rsize\r\n"
1012*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:102 VP8/90000\r\n"
1013*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 goog-remb\r\n"
1014*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 transport-cc\r\n"
1015*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 ccm fir\r\n"
1016*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack\r\n"
1017*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack pli\r\n"
1018*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:35 flexfec-03/90000\r\n"
1019*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:35 repair-window=10000000\r\n"
1020*d9f75844SAndroid Build Coastguard Worker       "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
1021*d9f75844SAndroid Build Coastguard Worker       "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
1022*d9f75844SAndroid Build Coastguard Worker       "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
1023*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
1024*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
1025*d9f75844SAndroid Build Coastguard Worker 
1026*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
1027*d9f75844SAndroid Build Coastguard Worker 
1028*d9f75844SAndroid Build Coastguard Worker   auto answer = caller->CreateAnswer();
1029*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(answer->description()->contents().size(), 1u);
1030*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(
1031*d9f75844SAndroid Build Coastguard Worker       answer->description()->contents()[0].media_description()->as_video(),
1032*d9f75844SAndroid Build Coastguard Worker       nullptr);
1033*d9f75844SAndroid Build Coastguard Worker   auto codecs = answer->description()
1034*d9f75844SAndroid Build Coastguard Worker                     ->contents()[0]
1035*d9f75844SAndroid Build Coastguard Worker                     .media_description()
1036*d9f75844SAndroid Build Coastguard Worker                     ->as_video()
1037*d9f75844SAndroid Build Coastguard Worker                     ->codecs();
1038*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(codecs.size(), 2u);
1039*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(codecs[1].name, "flexfec-03");
1040*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(codecs[1].id, 35);
1041*d9f75844SAndroid Build Coastguard Worker 
1042*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
1043*d9f75844SAndroid Build Coastguard Worker 
1044*d9f75844SAndroid Build Coastguard Worker   // This generates a collision for AV1 which needs to be remapped.
1045*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1046*d9f75844SAndroid Build Coastguard Worker   auto offer_codecs = offer->description()
1047*d9f75844SAndroid Build Coastguard Worker                           ->contents()[0]
1048*d9f75844SAndroid Build Coastguard Worker                           .media_description()
1049*d9f75844SAndroid Build Coastguard Worker                           ->as_video()
1050*d9f75844SAndroid Build Coastguard Worker                           ->codecs();
1051*d9f75844SAndroid Build Coastguard Worker   auto flexfec_it = std::find_if(
1052*d9f75844SAndroid Build Coastguard Worker       offer_codecs.begin(), offer_codecs.end(),
1053*d9f75844SAndroid Build Coastguard Worker       [](const cricket::Codec& codec) { return codec.name == "flexfec-03"; });
1054*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(flexfec_it->id, 35);
1055*d9f75844SAndroid Build Coastguard Worker   auto av1_it = std::find_if(
1056*d9f75844SAndroid Build Coastguard Worker       offer_codecs.begin(), offer_codecs.end(),
1057*d9f75844SAndroid Build Coastguard Worker       [](const cricket::Codec& codec) { return codec.name == "AV1"; });
1058*d9f75844SAndroid Build Coastguard Worker   if (av1_it != offer_codecs.end()) {
1059*d9f75844SAndroid Build Coastguard Worker     ASSERT_NE(av1_it->id, 35);
1060*d9f75844SAndroid Build Coastguard Worker   }
1061*d9f75844SAndroid Build Coastguard Worker }
1062*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionSignalingTest,MidAttributeMaxLength)1063*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionSignalingTest, MidAttributeMaxLength) {
1064*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1065*d9f75844SAndroid Build Coastguard Worker 
1066*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
1067*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
1068*d9f75844SAndroid Build Coastguard Worker       "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
1069*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
1070*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
1071*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
1072*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
1073*d9f75844SAndroid Build Coastguard Worker       "a=rtcp:9 IN IP4 0.0.0.0\r\n"
1074*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:IZeV\r\n"
1075*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
1076*d9f75844SAndroid Build Coastguard Worker       "a=ice-options:trickle\r\n"
1077*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-256 "
1078*d9f75844SAndroid Build Coastguard Worker       "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
1079*d9f75844SAndroid Build Coastguard Worker       "1C:2C:74:01:8D:50:67:23\r\n"
1080*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
1081*d9f75844SAndroid Build Coastguard Worker       // Too long mid attribute.
1082*d9f75844SAndroid Build Coastguard Worker       "a=mid:0123456789012345678901234567890123\r\n"
1083*d9f75844SAndroid Build Coastguard Worker       "a=sendrecv\r\n"
1084*d9f75844SAndroid Build Coastguard Worker       "a=msid:stream track\r\n"
1085*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
1086*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-rsize\r\n"
1087*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:102 VP8/90000\r\n"
1088*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 goog-remb\r\n"
1089*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 transport-cc\r\n"
1090*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 ccm fir\r\n"
1091*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack\r\n"
1092*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack pli\r\n"
1093*d9f75844SAndroid Build Coastguard Worker       "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
1094*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
1095*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
1096*d9f75844SAndroid Build Coastguard Worker 
1097*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->SetRemoteDescription(std::move(remote_description)));
1098*d9f75844SAndroid Build Coastguard Worker }
1099*d9f75844SAndroid Build Coastguard Worker 
1100*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
1101*d9f75844SAndroid Build Coastguard Worker                          PeerConnectionSignalingTest,
1102*d9f75844SAndroid Build Coastguard Worker                          Values(SdpSemantics::kPlanB_DEPRECATED,
1103*d9f75844SAndroid Build Coastguard Worker                                 SdpSemantics::kUnifiedPlan));
1104*d9f75844SAndroid Build Coastguard Worker 
1105*d9f75844SAndroid Build Coastguard Worker class PeerConnectionSignalingUnifiedPlanTest
1106*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionSignalingBaseTest {
1107*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionSignalingUnifiedPlanTest()1108*d9f75844SAndroid Build Coastguard Worker   PeerConnectionSignalingUnifiedPlanTest()
1109*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
1110*d9f75844SAndroid Build Coastguard Worker };
1111*d9f75844SAndroid Build Coastguard Worker 
1112*d9f75844SAndroid Build Coastguard Worker // We verify that SetLocalDescription() executed immediately by verifying that
1113*d9f75844SAndroid Build Coastguard Worker // the transceiver mid values got assigned. SLD executing immeditately is not
1114*d9f75844SAndroid Build Coastguard Worker // unique to Unified Plan, but the transceivers used to verify this are only
1115*d9f75844SAndroid Build Coastguard Worker // available in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyUsingOldObserver)1116*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1117*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionExecutesImmediatelyUsingOldObserver) {
1118*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
1119*d9f75844SAndroid Build Coastguard Worker 
1120*d9f75844SAndroid Build Coastguard Worker   // This offer will cause transceiver mids to get assigned.
1121*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1122*d9f75844SAndroid Build Coastguard Worker 
1123*d9f75844SAndroid Build Coastguard Worker   // By not waiting for the observer's callback we can verify that the operation
1124*d9f75844SAndroid Build Coastguard Worker   // executed immediately. The old observer is invoked in a posted message, so
1125*d9f75844SAndroid Build Coastguard Worker   // waiting for it would not ensure synchronicity.
1126*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
1127*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(
1128*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<MockSetSessionDescriptionObserver>().get(),
1129*d9f75844SAndroid Build Coastguard Worker       offer.release());
1130*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
1131*d9f75844SAndroid Build Coastguard Worker }
1132*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyUsingNewObserver)1133*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1134*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionExecutesImmediatelyUsingNewObserver) {
1135*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
1136*d9f75844SAndroid Build Coastguard Worker 
1137*d9f75844SAndroid Build Coastguard Worker   // This offer will cause transceiver mids to get assigned.
1138*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1139*d9f75844SAndroid Build Coastguard Worker 
1140*d9f75844SAndroid Build Coastguard Worker   // Verify that mids were assigned without waiting for the observer. (However,
1141*d9f75844SAndroid Build Coastguard Worker   // the new observer should also be invoked synchronously - as is ensured by
1142*d9f75844SAndroid Build Coastguard Worker   // other tests.)
1143*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
1144*d9f75844SAndroid Build Coastguard Worker   caller->pc()->SetLocalDescription(
1145*d9f75844SAndroid Build Coastguard Worker       std::move(offer),
1146*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<FakeSetLocalDescriptionObserver>());
1147*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
1148*d9f75844SAndroid Build Coastguard Worker }
1149*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback)1150*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1151*d9f75844SAndroid Build Coastguard Worker        SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
1152*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
1153*d9f75844SAndroid Build Coastguard Worker 
1154*d9f75844SAndroid Build Coastguard Worker   // This offer will cause transceiver mids to get assigned.
1155*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1156*d9f75844SAndroid Build Coastguard Worker 
1157*d9f75844SAndroid Build Coastguard Worker   auto offer_observer =
1158*d9f75844SAndroid Build Coastguard Worker       rtc::make_ref_counted<ExecuteFunctionOnCreateSessionDescriptionObserver>(
1159*d9f75844SAndroid Build Coastguard Worker           [pc = caller->pc()](SessionDescriptionInterface* desc) {
1160*d9f75844SAndroid Build Coastguard Worker             // By not waiting for the observer's callback we can verify that the
1161*d9f75844SAndroid Build Coastguard Worker             // operation executed immediately.
1162*d9f75844SAndroid Build Coastguard Worker             RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
1163*d9f75844SAndroid Build Coastguard Worker             pc->SetLocalDescription(
1164*d9f75844SAndroid Build Coastguard Worker                 rtc::make_ref_counted<MockSetSessionDescriptionObserver>()
1165*d9f75844SAndroid Build Coastguard Worker                     .get(),
1166*d9f75844SAndroid Build Coastguard Worker                 desc);
1167*d9f75844SAndroid Build Coastguard Worker             EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
1168*d9f75844SAndroid Build Coastguard Worker           });
1169*d9f75844SAndroid Build Coastguard Worker   caller->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
1170*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
1171*d9f75844SAndroid Build Coastguard Worker }
1172*d9f75844SAndroid Build Coastguard Worker 
1173*d9f75844SAndroid Build Coastguard Worker // Test that transports are shown in the sender/receiver API after offer/answer.
1174*d9f75844SAndroid Build Coastguard Worker // This only works in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsInstantiateInOfferAnswer)1175*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1176*d9f75844SAndroid Build Coastguard Worker        DtlsTransportsInstantiateInOfferAnswer) {
1177*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
1178*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1179*d9f75844SAndroid Build Coastguard Worker 
1180*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(caller));
1181*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(callee));
1182*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1183*d9f75844SAndroid Build Coastguard Worker   caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1184*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(HasDtlsTransport(caller));
1185*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(std::move(offer));
1186*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(callee));
1187*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1188*d9f75844SAndroid Build Coastguard Worker   callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1189*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(HasDtlsTransport(callee));
1190*d9f75844SAndroid Build Coastguard Worker   caller->SetRemoteDescription(std::move(answer));
1191*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(HasDtlsTransport(caller));
1192*d9f75844SAndroid Build Coastguard Worker 
1193*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1194*d9f75844SAndroid Build Coastguard Worker }
1195*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsMergeWhenBundled)1196*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
1197*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
1198*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1199*d9f75844SAndroid Build Coastguard Worker 
1200*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(caller));
1201*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(callee));
1202*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1203*d9f75844SAndroid Build Coastguard Worker   caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1204*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1205*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(std::move(offer));
1206*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1207*d9f75844SAndroid Build Coastguard Worker   callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1208*d9f75844SAndroid Build Coastguard Worker   caller->SetRemoteDescription(std::move(answer));
1209*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, NumberOfDtlsTransports(caller));
1210*d9f75844SAndroid Build Coastguard Worker 
1211*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1212*d9f75844SAndroid Build Coastguard Worker }
1213*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsAreSeparateeWhenUnbundled)1214*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1215*d9f75844SAndroid Build Coastguard Worker        DtlsTransportsAreSeparateeWhenUnbundled) {
1216*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
1217*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1218*d9f75844SAndroid Build Coastguard Worker 
1219*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(caller));
1220*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(HasDtlsTransport(callee));
1221*d9f75844SAndroid Build Coastguard Worker   RTCOfferAnswerOptions unbundle_options;
1222*d9f75844SAndroid Build Coastguard Worker   unbundle_options.use_rtp_mux = false;
1223*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(unbundle_options);
1224*d9f75844SAndroid Build Coastguard Worker   caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1225*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1226*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(std::move(offer));
1227*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1228*d9f75844SAndroid Build Coastguard Worker   callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1229*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, NumberOfDtlsTransports(callee));
1230*d9f75844SAndroid Build Coastguard Worker   caller->SetRemoteDescription(std::move(answer));
1231*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1232*d9f75844SAndroid Build Coastguard Worker 
1233*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1234*d9f75844SAndroid Build Coastguard Worker }
1235*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,ShouldFireNegotiationNeededWhenNoChangesArePending)1236*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1237*d9f75844SAndroid Build Coastguard Worker        ShouldFireNegotiationNeededWhenNoChangesArePending) {
1238*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1239*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1240*d9f75844SAndroid Build Coastguard Worker   auto transceiver =
1241*d9f75844SAndroid Build Coastguard Worker       caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1242*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1243*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1244*d9f75844SAndroid Build Coastguard Worker       caller->observer()->latest_negotiation_needed_event()));
1245*d9f75844SAndroid Build Coastguard Worker }
1246*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SuppressNegotiationNeededWhenOperationChainIsNotEmpty)1247*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1248*d9f75844SAndroid Build Coastguard Worker        SuppressNegotiationNeededWhenOperationChainIsNotEmpty) {
1249*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1250*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1251*d9f75844SAndroid Build Coastguard Worker   auto transceiver =
1252*d9f75844SAndroid Build Coastguard Worker       caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1253*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1254*d9f75844SAndroid Build Coastguard Worker 
1255*d9f75844SAndroid Build Coastguard Worker   auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
1256*d9f75844SAndroid Build Coastguard Worker   caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
1257*d9f75844SAndroid Build Coastguard Worker   // For this test to work, the operation has to be pending, i.e. the observer
1258*d9f75844SAndroid Build Coastguard Worker   // has not yet been invoked.
1259*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(observer->called());
1260*d9f75844SAndroid Build Coastguard Worker   // Because the Operations Chain is not empty, the event is now suppressed.
1261*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->pc()->ShouldFireNegotiationNeededEvent(
1262*d9f75844SAndroid Build Coastguard Worker       caller->observer()->latest_negotiation_needed_event()));
1263*d9f75844SAndroid Build Coastguard Worker   caller->observer()->clear_latest_negotiation_needed_event();
1264*d9f75844SAndroid Build Coastguard Worker 
1265*d9f75844SAndroid Build Coastguard Worker   // When the Operations Chain becomes empty again, a new negotiation needed
1266*d9f75844SAndroid Build Coastguard Worker   // event will be generated that is not suppressed.
1267*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
1268*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1269*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1270*d9f75844SAndroid Build Coastguard Worker       caller->observer()->latest_negotiation_needed_event()));
1271*d9f75844SAndroid Build Coastguard Worker }
1272*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SuppressNegotiationNeededWhenSignalingStateIsNotStable)1273*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1274*d9f75844SAndroid Build Coastguard Worker        SuppressNegotiationNeededWhenSignalingStateIsNotStable) {
1275*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
1276*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1277*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1278*d9f75844SAndroid Build Coastguard Worker 
1279*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1280*d9f75844SAndroid Build Coastguard Worker   auto transceiver =
1281*d9f75844SAndroid Build Coastguard Worker       callee->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1282*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1283*d9f75844SAndroid Build Coastguard Worker 
1284*d9f75844SAndroid Build Coastguard Worker   // Change signaling state (to "have-remote-offer") by setting a remote offer.
1285*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(std::move(offer));
1286*d9f75844SAndroid Build Coastguard Worker   // Because the signaling state is not "stable", the event is now suppressed.
1287*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->pc()->ShouldFireNegotiationNeededEvent(
1288*d9f75844SAndroid Build Coastguard Worker       callee->observer()->latest_negotiation_needed_event()));
1289*d9f75844SAndroid Build Coastguard Worker   callee->observer()->clear_latest_negotiation_needed_event();
1290*d9f75844SAndroid Build Coastguard Worker 
1291*d9f75844SAndroid Build Coastguard Worker   // Upon rolling back to "stable", a new negotiation needed event will be
1292*d9f75844SAndroid Build Coastguard Worker   // generated that is not suppressed.
1293*d9f75844SAndroid Build Coastguard Worker   callee->SetLocalDescription(CreateSessionDescription(SdpType::kRollback, ""));
1294*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1295*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->pc()->ShouldFireNegotiationNeededEvent(
1296*d9f75844SAndroid Build Coastguard Worker       callee->observer()->latest_negotiation_needed_event()));
1297*d9f75844SAndroid Build Coastguard Worker }
1298*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,RtxReofferApt)1299*d9f75844SAndroid Build Coastguard Worker TEST_F(PeerConnectionSignalingUnifiedPlanTest, RtxReofferApt) {
1300*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
1301*d9f75844SAndroid Build Coastguard Worker 
1302*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
1303*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
1304*d9f75844SAndroid Build Coastguard Worker       "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
1305*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
1306*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
1307*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
1308*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
1309*d9f75844SAndroid Build Coastguard Worker       "a=rtcp:9 IN IP4 0.0.0.0\r\n"
1310*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:IZeV\r\n"
1311*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
1312*d9f75844SAndroid Build Coastguard Worker       "a=ice-options:trickle\r\n"
1313*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-256 "
1314*d9f75844SAndroid Build Coastguard Worker       "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
1315*d9f75844SAndroid Build Coastguard Worker       "1C:2C:74:01:8D:50:67:23\r\n"
1316*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
1317*d9f75844SAndroid Build Coastguard Worker       "a=mid:0\r\n"
1318*d9f75844SAndroid Build Coastguard Worker       "a=sendrecv\r\n"
1319*d9f75844SAndroid Build Coastguard Worker       "a=msid:stream track\r\n"
1320*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
1321*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-rsize\r\n"
1322*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:102 VP8/90000\r\n"
1323*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 goog-remb\r\n"
1324*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 transport-cc\r\n"
1325*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 ccm fir\r\n"
1326*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack\r\n"
1327*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-fb:102 nack pli\r\n"
1328*d9f75844SAndroid Build Coastguard Worker       "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
1329*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
1330*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
1331*d9f75844SAndroid Build Coastguard Worker 
1332*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(callee->SetRemoteDescription(std::move(remote_description)));
1333*d9f75844SAndroid Build Coastguard Worker 
1334*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1335*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
1336*d9f75844SAndroid Build Coastguard Worker       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
1337*d9f75844SAndroid Build Coastguard Worker 
1338*d9f75844SAndroid Build Coastguard Worker   callee->pc()->GetTransceivers()[0]->StopStandard();
1339*d9f75844SAndroid Build Coastguard Worker   auto reoffer = callee->CreateOffer(RTCOfferAnswerOptions());
1340*d9f75844SAndroid Build Coastguard Worker   auto codecs = reoffer->description()
1341*d9f75844SAndroid Build Coastguard Worker                     ->contents()[0]
1342*d9f75844SAndroid Build Coastguard Worker                     .media_description()
1343*d9f75844SAndroid Build Coastguard Worker                     ->as_video()
1344*d9f75844SAndroid Build Coastguard Worker                     ->codecs();
1345*d9f75844SAndroid Build Coastguard Worker   ASSERT_GT(codecs.size(), 2u);
1346*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(codecs[0].name, "VP8");
1347*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(codecs[1].name, "rtx");
1348*d9f75844SAndroid Build Coastguard Worker   auto apt_it = codecs[1].params.find("apt");
1349*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(apt_it, codecs[1].params.end());
1350*d9f75844SAndroid Build Coastguard Worker   // The apt should match the id from the remote offer.
1351*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(apt_it->second, rtc::ToString(codecs[0].id));
1352*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(apt_it->second, "102");
1353*d9f75844SAndroid Build Coastguard Worker }
1354*d9f75844SAndroid Build Coastguard Worker 
1355*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
1356