xref: /aosp_15_r20/external/webrtc/pc/sdp_offer_answer_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 #include <memory>
12*d9f75844SAndroid Build Coastguard Worker #include <utility>
13*d9f75844SAndroid Build Coastguard Worker #include <vector>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_mixer.h"
16*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
18*d9f75844SAndroid Build Coastguard Worker #include "api/create_peerconnection_factory.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/media_types.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_transceiver_interface.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_decoder_factory.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_encoder_factory.h"
25*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/audio_device.h"
26*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
27*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
28*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_wrapper.h"
29*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_audio_capture_module.h"
30*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_peer_connection_observers.h"
31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate_generator.h"
32*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
33*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/metrics.h"
34*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker // This file contains unit tests that relate to the behavior of the
37*d9f75844SAndroid Build Coastguard Worker // SdpOfferAnswer module.
38*d9f75844SAndroid Build Coastguard Worker // Tests are writen as integration tests with PeerConnection, since the
39*d9f75844SAndroid Build Coastguard Worker // behaviors are still linked so closely that it is hard to test them in
40*d9f75844SAndroid Build Coastguard Worker // isolation.
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
43*d9f75844SAndroid Build Coastguard Worker 
44*d9f75844SAndroid Build Coastguard Worker using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
45*d9f75844SAndroid Build Coastguard Worker 
46*d9f75844SAndroid Build Coastguard Worker namespace {
47*d9f75844SAndroid Build Coastguard Worker 
CreateAndStartThread()48*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::Thread> CreateAndStartThread() {
49*d9f75844SAndroid Build Coastguard Worker   auto thread = rtc::Thread::Create();
50*d9f75844SAndroid Build Coastguard Worker   thread->Start();
51*d9f75844SAndroid Build Coastguard Worker   return thread;
52*d9f75844SAndroid Build Coastguard Worker }
53*d9f75844SAndroid Build Coastguard Worker 
54*d9f75844SAndroid Build Coastguard Worker }  // namespace
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker class SdpOfferAnswerTest : public ::testing::Test {
57*d9f75844SAndroid Build Coastguard Worker  public:
SdpOfferAnswerTest()58*d9f75844SAndroid Build Coastguard Worker   SdpOfferAnswerTest()
59*d9f75844SAndroid Build Coastguard Worker       // Note: We use a PeerConnectionFactory with a distinct
60*d9f75844SAndroid Build Coastguard Worker       // signaling thread, so that thread handling can be tested.
61*d9f75844SAndroid Build Coastguard Worker       : signaling_thread_(CreateAndStartThread()),
62*d9f75844SAndroid Build Coastguard Worker         pc_factory_(
63*d9f75844SAndroid Build Coastguard Worker             CreatePeerConnectionFactory(nullptr,
64*d9f75844SAndroid Build Coastguard Worker                                         nullptr,
65*d9f75844SAndroid Build Coastguard Worker                                         signaling_thread_.get(),
66*d9f75844SAndroid Build Coastguard Worker                                         FakeAudioCaptureModule::Create(),
67*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinAudioEncoderFactory(),
68*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinAudioDecoderFactory(),
69*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinVideoEncoderFactory(),
70*d9f75844SAndroid Build Coastguard Worker                                         CreateBuiltinVideoDecoderFactory(),
71*d9f75844SAndroid Build Coastguard Worker                                         nullptr /* audio_mixer */,
72*d9f75844SAndroid Build Coastguard Worker                                         nullptr /* audio_processing */)) {
73*d9f75844SAndroid Build Coastguard Worker     webrtc::metrics::Reset();
74*d9f75844SAndroid Build Coastguard Worker   }
75*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection()76*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection() {
77*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration config;
78*d9f75844SAndroid Build Coastguard Worker     config.sdp_semantics = SdpSemantics::kUnifiedPlan;
79*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnection(config);
80*d9f75844SAndroid Build Coastguard Worker   }
81*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection(const RTCConfiguration & config)82*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
83*d9f75844SAndroid Build Coastguard Worker       const RTCConfiguration& config) {
84*d9f75844SAndroid Build Coastguard Worker     auto observer = std::make_unique<MockPeerConnectionObserver>();
85*d9f75844SAndroid Build Coastguard Worker     auto result = pc_factory_->CreatePeerConnectionOrError(
86*d9f75844SAndroid Build Coastguard Worker         config, PeerConnectionDependencies(observer.get()));
87*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(result.ok());
88*d9f75844SAndroid Build Coastguard Worker     observer->SetPeerConnectionInterface(result.value().get());
89*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<PeerConnectionWrapper>(
90*d9f75844SAndroid Build Coastguard Worker         pc_factory_, result.MoveValue(), std::move(observer));
91*d9f75844SAndroid Build Coastguard Worker   }
92*d9f75844SAndroid Build Coastguard Worker 
93*d9f75844SAndroid Build Coastguard Worker  protected:
94*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> signaling_thread_;
95*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
96*d9f75844SAndroid Build Coastguard Worker 
97*d9f75844SAndroid Build Coastguard Worker  private:
98*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread_;
99*d9f75844SAndroid Build Coastguard Worker };
100*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SdpOfferAnswerTest,OnTrackReturnsProxiedObject)101*d9f75844SAndroid Build Coastguard Worker TEST_F(SdpOfferAnswerTest, OnTrackReturnsProxiedObject) {
102*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnection();
103*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnection();
104*d9f75844SAndroid Build Coastguard Worker 
105*d9f75844SAndroid Build Coastguard Worker   auto audio_transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
106*d9f75844SAndroid Build Coastguard Worker 
107*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
108*d9f75844SAndroid Build Coastguard Worker   // Verify that caller->observer->OnTrack() has been called with a
109*d9f75844SAndroid Build Coastguard Worker   // proxied transceiver object.
110*d9f75844SAndroid Build Coastguard Worker   ASSERT_EQ(callee->observer()->on_track_transceivers_.size(), 1u);
111*d9f75844SAndroid Build Coastguard Worker   auto transceiver = callee->observer()->on_track_transceivers_[0];
112*d9f75844SAndroid Build Coastguard Worker   // Since the signaling thread is not the current thread,
113*d9f75844SAndroid Build Coastguard Worker   // this will DCHECK if the transceiver is not proxied.
114*d9f75844SAndroid Build Coastguard Worker   transceiver->stopped();
115*d9f75844SAndroid Build Coastguard Worker }
116*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SdpOfferAnswerTest,BundleRejectsCodecCollisionsAudioVideo)117*d9f75844SAndroid Build Coastguard Worker TEST_F(SdpOfferAnswerTest, BundleRejectsCodecCollisionsAudioVideo) {
118*d9f75844SAndroid Build Coastguard Worker   auto pc = CreatePeerConnection();
119*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
120*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
121*d9f75844SAndroid Build Coastguard Worker       "o=- 0 3 IN IP4 127.0.0.1\r\n"
122*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
123*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
124*d9f75844SAndroid Build Coastguard Worker       "a=group:BUNDLE 0 1\r\n"
125*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-1 "
126*d9f75844SAndroid Build Coastguard Worker       "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
127*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
128*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:ETEn\r\n"
129*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n"
130*d9f75844SAndroid Build Coastguard Worker       "m=audio 9 UDP/TLS/RTP/SAVPF 111\r\n"
131*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
132*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
133*d9f75844SAndroid Build Coastguard Worker       "a=sendonly\r\n"
134*d9f75844SAndroid Build Coastguard Worker       "a=mid:0\r\n"
135*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:111 opus/48000/2\r\n"
136*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 111\r\n"
137*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
138*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
139*d9f75844SAndroid Build Coastguard Worker       "a=sendonly\r\n"
140*d9f75844SAndroid Build Coastguard Worker       "a=mid:1\r\n"
141*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:111 H264/90000\r\n"
142*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:111 "
143*d9f75844SAndroid Build Coastguard Worker       "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id="
144*d9f75844SAndroid Build Coastguard Worker       "42e01f\r\n";
145*d9f75844SAndroid Build Coastguard Worker 
146*d9f75844SAndroid Build Coastguard Worker   auto desc = CreateSessionDescription(SdpType::kOffer, sdp);
147*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(desc, nullptr);
148*d9f75844SAndroid Build Coastguard Worker   RTCError error;
149*d9f75844SAndroid Build Coastguard Worker   pc->SetRemoteDescription(std::move(desc), &error);
150*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(error.ok());
151*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(
152*d9f75844SAndroid Build Coastguard Worker       1, webrtc::metrics::NumEvents(
153*d9f75844SAndroid Build Coastguard Worker              "WebRTC.PeerConnection.ValidBundledPayloadTypes", false));
154*d9f75844SAndroid Build Coastguard Worker }
155*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SdpOfferAnswerTest,BundleRejectsCodecCollisionsVideoFmtp)156*d9f75844SAndroid Build Coastguard Worker TEST_F(SdpOfferAnswerTest, BundleRejectsCodecCollisionsVideoFmtp) {
157*d9f75844SAndroid Build Coastguard Worker   auto pc = CreatePeerConnection();
158*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
159*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
160*d9f75844SAndroid Build Coastguard Worker       "o=- 0 3 IN IP4 127.0.0.1\r\n"
161*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
162*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
163*d9f75844SAndroid Build Coastguard Worker       "a=group:BUNDLE 0 1\r\n"
164*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-1 "
165*d9f75844SAndroid Build Coastguard Worker       "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
166*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
167*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:ETEn\r\n"
168*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n"
169*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 111\r\n"
170*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
171*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
172*d9f75844SAndroid Build Coastguard Worker       "a=sendonly\r\n"
173*d9f75844SAndroid Build Coastguard Worker       "a=mid:0\r\n"
174*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:111 H264/90000\r\n"
175*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:111 "
176*d9f75844SAndroid Build Coastguard Worker       "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id="
177*d9f75844SAndroid Build Coastguard Worker       "42e01f\r\n"
178*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 111\r\n"
179*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
180*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
181*d9f75844SAndroid Build Coastguard Worker       "a=sendonly\r\n"
182*d9f75844SAndroid Build Coastguard Worker       "a=mid:1\r\n"
183*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:111 H264/90000\r\n"
184*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:111 "
185*d9f75844SAndroid Build Coastguard Worker       "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="
186*d9f75844SAndroid Build Coastguard Worker       "42e01f\r\n";
187*d9f75844SAndroid Build Coastguard Worker 
188*d9f75844SAndroid Build Coastguard Worker   auto desc = CreateSessionDescription(SdpType::kOffer, sdp);
189*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(desc, nullptr);
190*d9f75844SAndroid Build Coastguard Worker   RTCError error;
191*d9f75844SAndroid Build Coastguard Worker   pc->SetRemoteDescription(std::move(desc), &error);
192*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(error.ok());
193*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(
194*d9f75844SAndroid Build Coastguard Worker       1, webrtc::metrics::NumEvents(
195*d9f75844SAndroid Build Coastguard Worker              "WebRTC.PeerConnection.ValidBundledPayloadTypes", false));
196*d9f75844SAndroid Build Coastguard Worker }
197*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SdpOfferAnswerTest,BundleCodecCollisionInDifferentBundlesAllowed)198*d9f75844SAndroid Build Coastguard Worker TEST_F(SdpOfferAnswerTest, BundleCodecCollisionInDifferentBundlesAllowed) {
199*d9f75844SAndroid Build Coastguard Worker   auto pc = CreatePeerConnection();
200*d9f75844SAndroid Build Coastguard Worker   std::string sdp =
201*d9f75844SAndroid Build Coastguard Worker       "v=0\r\n"
202*d9f75844SAndroid Build Coastguard Worker       "o=- 0 3 IN IP4 127.0.0.1\r\n"
203*d9f75844SAndroid Build Coastguard Worker       "s=-\r\n"
204*d9f75844SAndroid Build Coastguard Worker       "t=0 0\r\n"
205*d9f75844SAndroid Build Coastguard Worker       "a=group:BUNDLE 0\r\n"
206*d9f75844SAndroid Build Coastguard Worker       "a=group:BUNDLE 1\r\n"
207*d9f75844SAndroid Build Coastguard Worker       "a=fingerprint:sha-1 "
208*d9f75844SAndroid Build Coastguard Worker       "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
209*d9f75844SAndroid Build Coastguard Worker       "a=setup:actpass\r\n"
210*d9f75844SAndroid Build Coastguard Worker       "a=ice-ufrag:ETEn\r\n"
211*d9f75844SAndroid Build Coastguard Worker       "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n"
212*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 111\r\n"
213*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
214*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
215*d9f75844SAndroid Build Coastguard Worker       "a=sendonly\r\n"
216*d9f75844SAndroid Build Coastguard Worker       "a=mid:0\r\n"
217*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:111 H264/90000\r\n"
218*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:111 "
219*d9f75844SAndroid Build Coastguard Worker       "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id="
220*d9f75844SAndroid Build Coastguard Worker       "42e01f\r\n"
221*d9f75844SAndroid Build Coastguard Worker       "m=video 9 UDP/TLS/RTP/SAVPF 111\r\n"
222*d9f75844SAndroid Build Coastguard Worker       "c=IN IP4 0.0.0.0\r\n"
223*d9f75844SAndroid Build Coastguard Worker       "a=rtcp-mux\r\n"
224*d9f75844SAndroid Build Coastguard Worker       "a=sendonly\r\n"
225*d9f75844SAndroid Build Coastguard Worker       "a=mid:1\r\n"
226*d9f75844SAndroid Build Coastguard Worker       "a=rtpmap:111 H264/90000\r\n"
227*d9f75844SAndroid Build Coastguard Worker       "a=fmtp:111 "
228*d9f75844SAndroid Build Coastguard Worker       "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="
229*d9f75844SAndroid Build Coastguard Worker       "42e01f\r\n";
230*d9f75844SAndroid Build Coastguard Worker 
231*d9f75844SAndroid Build Coastguard Worker   auto desc = CreateSessionDescription(SdpType::kOffer, sdp);
232*d9f75844SAndroid Build Coastguard Worker   ASSERT_NE(desc, nullptr);
233*d9f75844SAndroid Build Coastguard Worker   RTCError error;
234*d9f75844SAndroid Build Coastguard Worker   pc->SetRemoteDescription(std::move(desc), &error);
235*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(error.ok());
236*d9f75844SAndroid Build Coastguard Worker   EXPECT_METRIC_EQ(
237*d9f75844SAndroid Build Coastguard Worker       0, webrtc::metrics::NumEvents(
238*d9f75844SAndroid Build Coastguard Worker              "WebRTC.PeerConnection.ValidBundledPayloadTypes", false));
239*d9f75844SAndroid Build Coastguard Worker }
240*d9f75844SAndroid Build Coastguard Worker 
241*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
242