xref: /aosp_15_r20/external/webrtc/sdk/objc/api/peerconnection/RTCPeerConnection.mm (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker/*
2*d9f75844SAndroid Build Coastguard Worker *  Copyright 2015 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#import "RTCPeerConnection+Private.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker#import "RTCConfiguration+Private.h"
14*d9f75844SAndroid Build Coastguard Worker#import "RTCDataChannel+Private.h"
15*d9f75844SAndroid Build Coastguard Worker#import "RTCIceCandidate+Private.h"
16*d9f75844SAndroid Build Coastguard Worker#import "RTCIceCandidateErrorEvent+Private.h"
17*d9f75844SAndroid Build Coastguard Worker#import "RTCLegacyStatsReport+Private.h"
18*d9f75844SAndroid Build Coastguard Worker#import "RTCMediaConstraints+Private.h"
19*d9f75844SAndroid Build Coastguard Worker#import "RTCMediaStream+Private.h"
20*d9f75844SAndroid Build Coastguard Worker#import "RTCMediaStreamTrack+Private.h"
21*d9f75844SAndroid Build Coastguard Worker#import "RTCPeerConnectionFactory+Private.h"
22*d9f75844SAndroid Build Coastguard Worker#import "RTCRtpReceiver+Private.h"
23*d9f75844SAndroid Build Coastguard Worker#import "RTCRtpSender+Private.h"
24*d9f75844SAndroid Build Coastguard Worker#import "RTCRtpTransceiver+Private.h"
25*d9f75844SAndroid Build Coastguard Worker#import "RTCSessionDescription+Private.h"
26*d9f75844SAndroid Build Coastguard Worker#import "base/RTCLogging.h"
27*d9f75844SAndroid Build Coastguard Worker#import "helpers/NSString+StdString.h"
28*d9f75844SAndroid Build Coastguard Worker
29*d9f75844SAndroid Build Coastguard Worker#include <memory>
30*d9f75844SAndroid Build Coastguard Worker
31*d9f75844SAndroid Build Coastguard Worker#include "api/jsep_ice_candidate.h"
32*d9f75844SAndroid Build Coastguard Worker#include "api/rtc_event_log_output_file.h"
33*d9f75844SAndroid Build Coastguard Worker#include "api/set_local_description_observer_interface.h"
34*d9f75844SAndroid Build Coastguard Worker#include "api/set_remote_description_observer_interface.h"
35*d9f75844SAndroid Build Coastguard Worker#include "rtc_base/checks.h"
36*d9f75844SAndroid Build Coastguard Worker#include "rtc_base/numerics/safe_conversions.h"
37*d9f75844SAndroid Build Coastguard Worker#include "sdk/objc/native/api/ssl_certificate_verifier.h"
38*d9f75844SAndroid Build Coastguard Worker
39*d9f75844SAndroid Build Coastguard WorkerNSString *const kRTCPeerConnectionErrorDomain = @"org.webrtc.RTC_OBJC_TYPE(RTCPeerConnection)";
40*d9f75844SAndroid Build Coastguard Workerint const kRTCPeerConnnectionSessionDescriptionError = -1;
41*d9f75844SAndroid Build Coastguard Worker
42*d9f75844SAndroid Build Coastguard Workernamespace {
43*d9f75844SAndroid Build Coastguard Worker
44*d9f75844SAndroid Build Coastguard Workerclass SetSessionDescriptionObserver : public webrtc::SetLocalDescriptionObserverInterface,
45*d9f75844SAndroid Build Coastguard Worker                                      public webrtc::SetRemoteDescriptionObserverInterface {
46*d9f75844SAndroid Build Coastguard Worker public:
47*d9f75844SAndroid Build Coastguard Worker  SetSessionDescriptionObserver(RTCSetSessionDescriptionCompletionHandler completionHandler) {
48*d9f75844SAndroid Build Coastguard Worker    completion_handler_ = completionHandler;
49*d9f75844SAndroid Build Coastguard Worker  }
50*d9f75844SAndroid Build Coastguard Worker
51*d9f75844SAndroid Build Coastguard Worker  virtual void OnSetLocalDescriptionComplete(webrtc::RTCError error) override {
52*d9f75844SAndroid Build Coastguard Worker    OnCompelete(error);
53*d9f75844SAndroid Build Coastguard Worker  }
54*d9f75844SAndroid Build Coastguard Worker
55*d9f75844SAndroid Build Coastguard Worker  virtual void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
56*d9f75844SAndroid Build Coastguard Worker    OnCompelete(error);
57*d9f75844SAndroid Build Coastguard Worker  }
58*d9f75844SAndroid Build Coastguard Worker
59*d9f75844SAndroid Build Coastguard Worker private:
60*d9f75844SAndroid Build Coastguard Worker  void OnCompelete(webrtc::RTCError error) {
61*d9f75844SAndroid Build Coastguard Worker    RTC_DCHECK(completion_handler_ != nil);
62*d9f75844SAndroid Build Coastguard Worker    if (error.ok()) {
63*d9f75844SAndroid Build Coastguard Worker      completion_handler_(nil);
64*d9f75844SAndroid Build Coastguard Worker    } else {
65*d9f75844SAndroid Build Coastguard Worker      // TODO(hta): Add handling of error.type()
66*d9f75844SAndroid Build Coastguard Worker      NSString *str = [NSString stringForStdString:error.message()];
67*d9f75844SAndroid Build Coastguard Worker      NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
68*d9f75844SAndroid Build Coastguard Worker                                         code:kRTCPeerConnnectionSessionDescriptionError
69*d9f75844SAndroid Build Coastguard Worker                                     userInfo:@{NSLocalizedDescriptionKey : str}];
70*d9f75844SAndroid Build Coastguard Worker      completion_handler_(err);
71*d9f75844SAndroid Build Coastguard Worker    }
72*d9f75844SAndroid Build Coastguard Worker    completion_handler_ = nil;
73*d9f75844SAndroid Build Coastguard Worker  }
74*d9f75844SAndroid Build Coastguard Worker  RTCSetSessionDescriptionCompletionHandler completion_handler_;
75*d9f75844SAndroid Build Coastguard Worker};
76*d9f75844SAndroid Build Coastguard Worker
77*d9f75844SAndroid Build Coastguard Worker}  // anonymous namespace
78*d9f75844SAndroid Build Coastguard Worker
79*d9f75844SAndroid Build Coastguard Workernamespace webrtc {
80*d9f75844SAndroid Build Coastguard Worker
81*d9f75844SAndroid Build Coastguard Workerclass CreateSessionDescriptionObserverAdapter
82*d9f75844SAndroid Build Coastguard Worker    : public CreateSessionDescriptionObserver {
83*d9f75844SAndroid Build Coastguard Worker public:
84*d9f75844SAndroid Build Coastguard Worker  CreateSessionDescriptionObserverAdapter(void (^completionHandler)(
85*d9f75844SAndroid Build Coastguard Worker      RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription, NSError *error)) {
86*d9f75844SAndroid Build Coastguard Worker    completion_handler_ = completionHandler;
87*d9f75844SAndroid Build Coastguard Worker  }
88*d9f75844SAndroid Build Coastguard Worker
89*d9f75844SAndroid Build Coastguard Worker  ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
90*d9f75844SAndroid Build Coastguard Worker
91*d9f75844SAndroid Build Coastguard Worker  void OnSuccess(SessionDescriptionInterface *desc) override {
92*d9f75844SAndroid Build Coastguard Worker    RTC_DCHECK(completion_handler_);
93*d9f75844SAndroid Build Coastguard Worker    std::unique_ptr<webrtc::SessionDescriptionInterface> description =
94*d9f75844SAndroid Build Coastguard Worker        std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
95*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCSessionDescription) *session =
96*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description.get()];
97*d9f75844SAndroid Build Coastguard Worker    completion_handler_(session, nil);
98*d9f75844SAndroid Build Coastguard Worker    completion_handler_ = nil;
99*d9f75844SAndroid Build Coastguard Worker  }
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard Worker  void OnFailure(RTCError error) override {
102*d9f75844SAndroid Build Coastguard Worker    RTC_DCHECK(completion_handler_);
103*d9f75844SAndroid Build Coastguard Worker    // TODO(hta): Add handling of error.type()
104*d9f75844SAndroid Build Coastguard Worker    NSString *str = [NSString stringForStdString:error.message()];
105*d9f75844SAndroid Build Coastguard Worker    NSError* err =
106*d9f75844SAndroid Build Coastguard Worker        [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
107*d9f75844SAndroid Build Coastguard Worker                            code:kRTCPeerConnnectionSessionDescriptionError
108*d9f75844SAndroid Build Coastguard Worker                        userInfo:@{ NSLocalizedDescriptionKey : str }];
109*d9f75844SAndroid Build Coastguard Worker    completion_handler_(nil, err);
110*d9f75844SAndroid Build Coastguard Worker    completion_handler_ = nil;
111*d9f75844SAndroid Build Coastguard Worker  }
112*d9f75844SAndroid Build Coastguard Worker
113*d9f75844SAndroid Build Coastguard Worker private:
114*d9f75844SAndroid Build Coastguard Worker  void (^completion_handler_)(RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription,
115*d9f75844SAndroid Build Coastguard Worker                              NSError *error);
116*d9f75844SAndroid Build Coastguard Worker};
117*d9f75844SAndroid Build Coastguard Worker
118*d9f75844SAndroid Build Coastguard WorkerPeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(RTC_OBJC_TYPE(RTCPeerConnection) *
119*d9f75844SAndroid Build Coastguard Worker                                                             peerConnection) {
120*d9f75844SAndroid Build Coastguard Worker  peer_connection_ = peerConnection;
121*d9f75844SAndroid Build Coastguard Worker}
122*d9f75844SAndroid Build Coastguard Worker
123*d9f75844SAndroid Build Coastguard WorkerPeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
124*d9f75844SAndroid Build Coastguard Worker  peer_connection_ = nil;
125*d9f75844SAndroid Build Coastguard Worker}
126*d9f75844SAndroid Build Coastguard Worker
127*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnSignalingChange(
128*d9f75844SAndroid Build Coastguard Worker    PeerConnectionInterface::SignalingState new_state) {
129*d9f75844SAndroid Build Coastguard Worker  RTCSignalingState state =
130*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCPeerConnection) class] signalingStateForNativeState:new_state];
131*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
132*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
133*d9f75844SAndroid Build Coastguard Worker                   didChangeSignalingState:state];
134*d9f75844SAndroid Build Coastguard Worker}
135*d9f75844SAndroid Build Coastguard Worker
136*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnAddStream(
137*d9f75844SAndroid Build Coastguard Worker    rtc::scoped_refptr<MediaStreamInterface> stream) {
138*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
139*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
140*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
141*d9f75844SAndroid Build Coastguard Worker                                           nativeMediaStream:stream];
142*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
143*d9f75844SAndroid Build Coastguard Worker                              didAddStream:mediaStream];
144*d9f75844SAndroid Build Coastguard Worker}
145*d9f75844SAndroid Build Coastguard Worker
146*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnRemoveStream(
147*d9f75844SAndroid Build Coastguard Worker    rtc::scoped_refptr<MediaStreamInterface> stream) {
148*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
149*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
150*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
151*d9f75844SAndroid Build Coastguard Worker                                           nativeMediaStream:stream];
152*d9f75844SAndroid Build Coastguard Worker
153*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
154*d9f75844SAndroid Build Coastguard Worker                           didRemoveStream:mediaStream];
155*d9f75844SAndroid Build Coastguard Worker}
156*d9f75844SAndroid Build Coastguard Worker
157*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnTrack(
158*d9f75844SAndroid Build Coastguard Worker    rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
159*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
160*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
161*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:peer_connection.factory
162*d9f75844SAndroid Build Coastguard Worker                                           nativeRtpTransceiver:nativeTransceiver];
163*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection.delegate
164*d9f75844SAndroid Build Coastguard Worker          respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
165*d9f75844SAndroid Build Coastguard Worker    [peer_connection.delegate peerConnection:peer_connection
166*d9f75844SAndroid Build Coastguard Worker              didStartReceivingOnTransceiver:transceiver];
167*d9f75844SAndroid Build Coastguard Worker  }
168*d9f75844SAndroid Build Coastguard Worker}
169*d9f75844SAndroid Build Coastguard Worker
170*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnDataChannel(
171*d9f75844SAndroid Build Coastguard Worker    rtc::scoped_refptr<DataChannelInterface> data_channel) {
172*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
173*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCDataChannel) *dataChannel =
174*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCDataChannel) alloc] initWithFactory:peer_connection.factory
175*d9f75844SAndroid Build Coastguard Worker                                           nativeDataChannel:data_channel];
176*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
177*d9f75844SAndroid Build Coastguard Worker                        didOpenDataChannel:dataChannel];
178*d9f75844SAndroid Build Coastguard Worker}
179*d9f75844SAndroid Build Coastguard Worker
180*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
181*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
182*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
183*d9f75844SAndroid Build Coastguard Worker}
184*d9f75844SAndroid Build Coastguard Worker
185*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnIceConnectionChange(
186*d9f75844SAndroid Build Coastguard Worker    PeerConnectionInterface::IceConnectionState new_state) {
187*d9f75844SAndroid Build Coastguard Worker  RTCIceConnectionState state =
188*d9f75844SAndroid Build Coastguard Worker      [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
189*d9f75844SAndroid Build Coastguard Worker  [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state];
190*d9f75844SAndroid Build Coastguard Worker}
191*d9f75844SAndroid Build Coastguard Worker
192*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange(
193*d9f75844SAndroid Build Coastguard Worker    PeerConnectionInterface::IceConnectionState new_state) {
194*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection_.delegate
195*d9f75844SAndroid Build Coastguard Worker          respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) {
196*d9f75844SAndroid Build Coastguard Worker    RTCIceConnectionState state =
197*d9f75844SAndroid Build Coastguard Worker        [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
198*d9f75844SAndroid Build Coastguard Worker    [peer_connection_.delegate peerConnection:peer_connection_
199*d9f75844SAndroid Build Coastguard Worker        didChangeStandardizedIceConnectionState:state];
200*d9f75844SAndroid Build Coastguard Worker  }
201*d9f75844SAndroid Build Coastguard Worker}
202*d9f75844SAndroid Build Coastguard Worker
203*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnConnectionChange(
204*d9f75844SAndroid Build Coastguard Worker    PeerConnectionInterface::PeerConnectionState new_state) {
205*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection_.delegate
206*d9f75844SAndroid Build Coastguard Worker          respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) {
207*d9f75844SAndroid Build Coastguard Worker    RTCPeerConnectionState state =
208*d9f75844SAndroid Build Coastguard Worker        [RTC_OBJC_TYPE(RTCPeerConnection) connectionStateForNativeState:new_state];
209*d9f75844SAndroid Build Coastguard Worker    [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state];
210*d9f75844SAndroid Build Coastguard Worker  }
211*d9f75844SAndroid Build Coastguard Worker}
212*d9f75844SAndroid Build Coastguard Worker
213*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnIceGatheringChange(
214*d9f75844SAndroid Build Coastguard Worker    PeerConnectionInterface::IceGatheringState new_state) {
215*d9f75844SAndroid Build Coastguard Worker  RTCIceGatheringState state =
216*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCPeerConnection) class] iceGatheringStateForNativeState:new_state];
217*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
218*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
219*d9f75844SAndroid Build Coastguard Worker                didChangeIceGatheringState:state];
220*d9f75844SAndroid Build Coastguard Worker}
221*d9f75844SAndroid Build Coastguard Worker
222*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnIceCandidate(
223*d9f75844SAndroid Build Coastguard Worker    const IceCandidateInterface *candidate) {
224*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate =
225*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate];
226*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
227*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
228*d9f75844SAndroid Build Coastguard Worker                   didGenerateIceCandidate:iceCandidate];
229*d9f75844SAndroid Build Coastguard Worker}
230*d9f75844SAndroid Build Coastguard Worker
231*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnIceCandidateError(const std::string &address,
232*d9f75844SAndroid Build Coastguard Worker                                                        int port,
233*d9f75844SAndroid Build Coastguard Worker                                                        const std::string &url,
234*d9f75844SAndroid Build Coastguard Worker                                                        int error_code,
235*d9f75844SAndroid Build Coastguard Worker                                                        const std::string &error_text) {
236*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
237*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *event =
238*d9f75844SAndroid Build Coastguard Worker      [[RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) alloc] initWithAddress:address
239*d9f75844SAndroid Build Coastguard Worker                                                                   port:port
240*d9f75844SAndroid Build Coastguard Worker                                                                    url:url
241*d9f75844SAndroid Build Coastguard Worker                                                              errorCode:error_code
242*d9f75844SAndroid Build Coastguard Worker                                                              errorText:error_text];
243*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
244*d9f75844SAndroid Build Coastguard Worker                                                             didFailToGatherIceCandidate:)]) {
245*d9f75844SAndroid Build Coastguard Worker    [peer_connection.delegate peerConnection:peer_connection didFailToGatherIceCandidate:event];
246*d9f75844SAndroid Build Coastguard Worker  }
247*d9f75844SAndroid Build Coastguard Worker}
248*d9f75844SAndroid Build Coastguard Worker
249*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
250*d9f75844SAndroid Build Coastguard Worker    const std::vector<cricket::Candidate>& candidates) {
251*d9f75844SAndroid Build Coastguard Worker  NSMutableArray* ice_candidates =
252*d9f75844SAndroid Build Coastguard Worker      [NSMutableArray arrayWithCapacity:candidates.size()];
253*d9f75844SAndroid Build Coastguard Worker  for (const auto& candidate : candidates) {
254*d9f75844SAndroid Build Coastguard Worker    std::unique_ptr<JsepIceCandidate> candidate_wrapper(
255*d9f75844SAndroid Build Coastguard Worker        new JsepIceCandidate(candidate.transport_name(), -1, candidate));
256*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCIceCandidate) *ice_candidate =
257*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate_wrapper.get()];
258*d9f75844SAndroid Build Coastguard Worker    [ice_candidates addObject:ice_candidate];
259*d9f75844SAndroid Build Coastguard Worker  }
260*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
261*d9f75844SAndroid Build Coastguard Worker  [peer_connection.delegate peerConnection:peer_connection
262*d9f75844SAndroid Build Coastguard Worker                    didRemoveIceCandidates:ice_candidates];
263*d9f75844SAndroid Build Coastguard Worker}
264*d9f75844SAndroid Build Coastguard Worker
265*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
266*d9f75844SAndroid Build Coastguard Worker    const cricket::CandidatePairChangeEvent &event) {
267*d9f75844SAndroid Build Coastguard Worker  const auto &selected_pair = event.selected_candidate_pair;
268*d9f75844SAndroid Build Coastguard Worker  auto local_candidate_wrapper = std::make_unique<JsepIceCandidate>(
269*d9f75844SAndroid Build Coastguard Worker      selected_pair.local_candidate().transport_name(), -1, selected_pair.local_candidate());
270*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCIceCandidate) *local_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
271*d9f75844SAndroid Build Coastguard Worker      initWithNativeCandidate:local_candidate_wrapper.release()];
272*d9f75844SAndroid Build Coastguard Worker  auto remote_candidate_wrapper = std::make_unique<JsepIceCandidate>(
273*d9f75844SAndroid Build Coastguard Worker      selected_pair.remote_candidate().transport_name(), -1, selected_pair.remote_candidate());
274*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
275*d9f75844SAndroid Build Coastguard Worker      initWithNativeCandidate:remote_candidate_wrapper.release()];
276*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
277*d9f75844SAndroid Build Coastguard Worker  NSString *nsstr_reason = [NSString stringForStdString:event.reason];
278*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection.delegate
279*d9f75844SAndroid Build Coastguard Worker          respondsToSelector:@selector
280*d9f75844SAndroid Build Coastguard Worker          (peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) {
281*d9f75844SAndroid Build Coastguard Worker    [peer_connection.delegate peerConnection:peer_connection
282*d9f75844SAndroid Build Coastguard Worker                     didChangeLocalCandidate:local_candidate
283*d9f75844SAndroid Build Coastguard Worker                             remoteCandidate:remote_candidate
284*d9f75844SAndroid Build Coastguard Worker                              lastReceivedMs:event.last_data_received_ms
285*d9f75844SAndroid Build Coastguard Worker                                changeReason:nsstr_reason];
286*d9f75844SAndroid Build Coastguard Worker  }
287*d9f75844SAndroid Build Coastguard Worker}
288*d9f75844SAndroid Build Coastguard Worker
289*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnAddTrack(
290*d9f75844SAndroid Build Coastguard Worker    rtc::scoped_refptr<RtpReceiverInterface> receiver,
291*d9f75844SAndroid Build Coastguard Worker    const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) {
292*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
293*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
294*d9f75844SAndroid Build Coastguard Worker                                                             didAddReceiver:streams:)]) {
295*d9f75844SAndroid Build Coastguard Worker    NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
296*d9f75844SAndroid Build Coastguard Worker    for (const auto &nativeStream : streams) {
297*d9f75844SAndroid Build Coastguard Worker      RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
298*d9f75844SAndroid Build Coastguard Worker          [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
299*d9f75844SAndroid Build Coastguard Worker                                               nativeMediaStream:nativeStream];
300*d9f75844SAndroid Build Coastguard Worker      [mediaStreams addObject:mediaStream];
301*d9f75844SAndroid Build Coastguard Worker    }
302*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
303*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
304*d9f75844SAndroid Build Coastguard Worker                                             nativeRtpReceiver:receiver];
305*d9f75844SAndroid Build Coastguard Worker
306*d9f75844SAndroid Build Coastguard Worker    [peer_connection.delegate peerConnection:peer_connection
307*d9f75844SAndroid Build Coastguard Worker                              didAddReceiver:rtpReceiver
308*d9f75844SAndroid Build Coastguard Worker                                     streams:mediaStreams];
309*d9f75844SAndroid Build Coastguard Worker  }
310*d9f75844SAndroid Build Coastguard Worker}
311*d9f75844SAndroid Build Coastguard Worker
312*d9f75844SAndroid Build Coastguard Workervoid PeerConnectionDelegateAdapter::OnRemoveTrack(
313*d9f75844SAndroid Build Coastguard Worker    rtc::scoped_refptr<RtpReceiverInterface> receiver) {
314*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
315*d9f75844SAndroid Build Coastguard Worker  if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
316*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
317*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
318*d9f75844SAndroid Build Coastguard Worker                                             nativeRtpReceiver:receiver];
319*d9f75844SAndroid Build Coastguard Worker    [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
320*d9f75844SAndroid Build Coastguard Worker  }
321*d9f75844SAndroid Build Coastguard Worker}
322*d9f75844SAndroid Build Coastguard Worker
323*d9f75844SAndroid Build Coastguard Worker}  // namespace webrtc
324*d9f75844SAndroid Build Coastguard Worker
325*d9f75844SAndroid Build Coastguard Worker@implementation RTC_OBJC_TYPE (RTCPeerConnection) {
326*d9f75844SAndroid Build Coastguard Worker  RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
327*d9f75844SAndroid Build Coastguard Worker  NSMutableArray<RTC_OBJC_TYPE(RTCMediaStream) *> *_localStreams;
328*d9f75844SAndroid Build Coastguard Worker  std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
329*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
330*d9f75844SAndroid Build Coastguard Worker  std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
331*d9f75844SAndroid Build Coastguard Worker  BOOL _hasStartedRtcEventLog;
332*d9f75844SAndroid Build Coastguard Worker}
333*d9f75844SAndroid Build Coastguard Worker
334*d9f75844SAndroid Build Coastguard Worker@synthesize delegate = _delegate;
335*d9f75844SAndroid Build Coastguard Worker@synthesize factory = _factory;
336*d9f75844SAndroid Build Coastguard Worker
337*d9f75844SAndroid Build Coastguard Worker- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
338*d9f75844SAndroid Build Coastguard Worker                           configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
339*d9f75844SAndroid Build Coastguard Worker                             constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
340*d9f75844SAndroid Build Coastguard Worker                     certificateVerifier:
341*d9f75844SAndroid Build Coastguard Worker                         (nullable id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier
342*d9f75844SAndroid Build Coastguard Worker                                delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
343*d9f75844SAndroid Build Coastguard Worker  NSParameterAssert(factory);
344*d9f75844SAndroid Build Coastguard Worker  std::unique_ptr<webrtc::PeerConnectionDependencies> dependencies =
345*d9f75844SAndroid Build Coastguard Worker      std::make_unique<webrtc::PeerConnectionDependencies>(nullptr);
346*d9f75844SAndroid Build Coastguard Worker  if (certificateVerifier != nil) {
347*d9f75844SAndroid Build Coastguard Worker    dependencies->tls_cert_verifier = webrtc::ObjCToNativeCertificateVerifier(certificateVerifier);
348*d9f75844SAndroid Build Coastguard Worker  }
349*d9f75844SAndroid Build Coastguard Worker  return [self initWithDependencies:factory
350*d9f75844SAndroid Build Coastguard Worker                      configuration:configuration
351*d9f75844SAndroid Build Coastguard Worker                        constraints:constraints
352*d9f75844SAndroid Build Coastguard Worker                       dependencies:std::move(dependencies)
353*d9f75844SAndroid Build Coastguard Worker                           delegate:delegate];
354*d9f75844SAndroid Build Coastguard Worker}
355*d9f75844SAndroid Build Coastguard Worker
356*d9f75844SAndroid Build Coastguard Worker- (nullable instancetype)
357*d9f75844SAndroid Build Coastguard Worker    initWithDependencies:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
358*d9f75844SAndroid Build Coastguard Worker           configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
359*d9f75844SAndroid Build Coastguard Worker             constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
360*d9f75844SAndroid Build Coastguard Worker            dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies
361*d9f75844SAndroid Build Coastguard Worker                delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
362*d9f75844SAndroid Build Coastguard Worker  NSParameterAssert(factory);
363*d9f75844SAndroid Build Coastguard Worker  NSParameterAssert(dependencies.get());
364*d9f75844SAndroid Build Coastguard Worker  std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
365*d9f75844SAndroid Build Coastguard Worker      [configuration createNativeConfiguration]);
366*d9f75844SAndroid Build Coastguard Worker  if (!config) {
367*d9f75844SAndroid Build Coastguard Worker    return nil;
368*d9f75844SAndroid Build Coastguard Worker  }
369*d9f75844SAndroid Build Coastguard Worker  if (self = [super init]) {
370*d9f75844SAndroid Build Coastguard Worker    _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
371*d9f75844SAndroid Build Coastguard Worker    _nativeConstraints = constraints.nativeConstraints;
372*d9f75844SAndroid Build Coastguard Worker    CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), config.get());
373*d9f75844SAndroid Build Coastguard Worker
374*d9f75844SAndroid Build Coastguard Worker    webrtc::PeerConnectionDependencies deps = std::move(*dependencies.release());
375*d9f75844SAndroid Build Coastguard Worker    deps.observer = _observer.get();
376*d9f75844SAndroid Build Coastguard Worker    auto result = factory.nativeFactory->CreatePeerConnectionOrError(*config, std::move(deps));
377*d9f75844SAndroid Build Coastguard Worker
378*d9f75844SAndroid Build Coastguard Worker    if (!result.ok()) {
379*d9f75844SAndroid Build Coastguard Worker      return nil;
380*d9f75844SAndroid Build Coastguard Worker    }
381*d9f75844SAndroid Build Coastguard Worker    _peerConnection = result.MoveValue();
382*d9f75844SAndroid Build Coastguard Worker    _factory = factory;
383*d9f75844SAndroid Build Coastguard Worker    _localStreams = [[NSMutableArray alloc] init];
384*d9f75844SAndroid Build Coastguard Worker    _delegate = delegate;
385*d9f75844SAndroid Build Coastguard Worker  }
386*d9f75844SAndroid Build Coastguard Worker  return self;
387*d9f75844SAndroid Build Coastguard Worker}
388*d9f75844SAndroid Build Coastguard Worker
389*d9f75844SAndroid Build Coastguard Worker- (NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)localStreams {
390*d9f75844SAndroid Build Coastguard Worker  return [_localStreams copy];
391*d9f75844SAndroid Build Coastguard Worker}
392*d9f75844SAndroid Build Coastguard Worker
393*d9f75844SAndroid Build Coastguard Worker- (RTC_OBJC_TYPE(RTCSessionDescription) *)localDescription {
394*d9f75844SAndroid Build Coastguard Worker  // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
395*d9f75844SAndroid Build Coastguard Worker  return _peerConnection->signaling_thread()->BlockingCall([self] {
396*d9f75844SAndroid Build Coastguard Worker    const webrtc::SessionDescriptionInterface *description = _peerConnection->local_description();
397*d9f75844SAndroid Build Coastguard Worker    return description ?
398*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
399*d9f75844SAndroid Build Coastguard Worker        nil;
400*d9f75844SAndroid Build Coastguard Worker  });
401*d9f75844SAndroid Build Coastguard Worker}
402*d9f75844SAndroid Build Coastguard Worker
403*d9f75844SAndroid Build Coastguard Worker- (RTC_OBJC_TYPE(RTCSessionDescription) *)remoteDescription {
404*d9f75844SAndroid Build Coastguard Worker  // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
405*d9f75844SAndroid Build Coastguard Worker  return _peerConnection->signaling_thread()->BlockingCall([self] {
406*d9f75844SAndroid Build Coastguard Worker    const webrtc::SessionDescriptionInterface *description = _peerConnection->remote_description();
407*d9f75844SAndroid Build Coastguard Worker    return description ?
408*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
409*d9f75844SAndroid Build Coastguard Worker        nil;
410*d9f75844SAndroid Build Coastguard Worker  });
411*d9f75844SAndroid Build Coastguard Worker}
412*d9f75844SAndroid Build Coastguard Worker
413*d9f75844SAndroid Build Coastguard Worker- (RTCSignalingState)signalingState {
414*d9f75844SAndroid Build Coastguard Worker  return [[self class]
415*d9f75844SAndroid Build Coastguard Worker      signalingStateForNativeState:_peerConnection->signaling_state()];
416*d9f75844SAndroid Build Coastguard Worker}
417*d9f75844SAndroid Build Coastguard Worker
418*d9f75844SAndroid Build Coastguard Worker- (RTCIceConnectionState)iceConnectionState {
419*d9f75844SAndroid Build Coastguard Worker  return [[self class] iceConnectionStateForNativeState:
420*d9f75844SAndroid Build Coastguard Worker      _peerConnection->ice_connection_state()];
421*d9f75844SAndroid Build Coastguard Worker}
422*d9f75844SAndroid Build Coastguard Worker
423*d9f75844SAndroid Build Coastguard Worker- (RTCPeerConnectionState)connectionState {
424*d9f75844SAndroid Build Coastguard Worker  return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
425*d9f75844SAndroid Build Coastguard Worker}
426*d9f75844SAndroid Build Coastguard Worker
427*d9f75844SAndroid Build Coastguard Worker- (RTCIceGatheringState)iceGatheringState {
428*d9f75844SAndroid Build Coastguard Worker  return [[self class] iceGatheringStateForNativeState:
429*d9f75844SAndroid Build Coastguard Worker      _peerConnection->ice_gathering_state()];
430*d9f75844SAndroid Build Coastguard Worker}
431*d9f75844SAndroid Build Coastguard Worker
432*d9f75844SAndroid Build Coastguard Worker- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
433*d9f75844SAndroid Build Coastguard Worker  std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
434*d9f75844SAndroid Build Coastguard Worker      [configuration createNativeConfiguration]);
435*d9f75844SAndroid Build Coastguard Worker  if (!config) {
436*d9f75844SAndroid Build Coastguard Worker    return NO;
437*d9f75844SAndroid Build Coastguard Worker  }
438*d9f75844SAndroid Build Coastguard Worker  CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
439*d9f75844SAndroid Build Coastguard Worker                                      config.get());
440*d9f75844SAndroid Build Coastguard Worker  return _peerConnection->SetConfiguration(*config).ok();
441*d9f75844SAndroid Build Coastguard Worker}
442*d9f75844SAndroid Build Coastguard Worker
443*d9f75844SAndroid Build Coastguard Worker- (RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
444*d9f75844SAndroid Build Coastguard Worker  webrtc::PeerConnectionInterface::RTCConfiguration config =
445*d9f75844SAndroid Build Coastguard Worker    _peerConnection->GetConfiguration();
446*d9f75844SAndroid Build Coastguard Worker  return [[RTC_OBJC_TYPE(RTCConfiguration) alloc] initWithNativeConfiguration:config];
447*d9f75844SAndroid Build Coastguard Worker}
448*d9f75844SAndroid Build Coastguard Worker
449*d9f75844SAndroid Build Coastguard Worker- (void)close {
450*d9f75844SAndroid Build Coastguard Worker  _peerConnection->Close();
451*d9f75844SAndroid Build Coastguard Worker}
452*d9f75844SAndroid Build Coastguard Worker
453*d9f75844SAndroid Build Coastguard Worker- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate {
454*d9f75844SAndroid Build Coastguard Worker  std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
455*d9f75844SAndroid Build Coastguard Worker      candidate.nativeCandidate);
456*d9f75844SAndroid Build Coastguard Worker  _peerConnection->AddIceCandidate(iceCandidate.get());
457*d9f75844SAndroid Build Coastguard Worker}
458*d9f75844SAndroid Build Coastguard Worker- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
459*d9f75844SAndroid Build Coastguard Worker      completionHandler:(void (^)(NSError *_Nullable error))completionHandler {
460*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(completionHandler != nil);
461*d9f75844SAndroid Build Coastguard Worker  _peerConnection->AddIceCandidate(
462*d9f75844SAndroid Build Coastguard Worker      candidate.nativeCandidate, [completionHandler](const auto &error) {
463*d9f75844SAndroid Build Coastguard Worker        if (error.ok()) {
464*d9f75844SAndroid Build Coastguard Worker          completionHandler(nil);
465*d9f75844SAndroid Build Coastguard Worker        } else {
466*d9f75844SAndroid Build Coastguard Worker          NSString *str = [NSString stringForStdString:error.message()];
467*d9f75844SAndroid Build Coastguard Worker          NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
468*d9f75844SAndroid Build Coastguard Worker                                             code:static_cast<NSInteger>(error.type())
469*d9f75844SAndroid Build Coastguard Worker                                         userInfo:@{NSLocalizedDescriptionKey : str}];
470*d9f75844SAndroid Build Coastguard Worker          completionHandler(err);
471*d9f75844SAndroid Build Coastguard Worker        }
472*d9f75844SAndroid Build Coastguard Worker      });
473*d9f75844SAndroid Build Coastguard Worker}
474*d9f75844SAndroid Build Coastguard Worker- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)iceCandidates {
475*d9f75844SAndroid Build Coastguard Worker  std::vector<cricket::Candidate> candidates;
476*d9f75844SAndroid Build Coastguard Worker  for (RTC_OBJC_TYPE(RTCIceCandidate) * iceCandidate in iceCandidates) {
477*d9f75844SAndroid Build Coastguard Worker    std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
478*d9f75844SAndroid Build Coastguard Worker        iceCandidate.nativeCandidate);
479*d9f75844SAndroid Build Coastguard Worker    if (candidate) {
480*d9f75844SAndroid Build Coastguard Worker      candidates.push_back(candidate->candidate());
481*d9f75844SAndroid Build Coastguard Worker      // Need to fill the transport name from the sdp_mid.
482*d9f75844SAndroid Build Coastguard Worker      candidates.back().set_transport_name(candidate->sdp_mid());
483*d9f75844SAndroid Build Coastguard Worker    }
484*d9f75844SAndroid Build Coastguard Worker  }
485*d9f75844SAndroid Build Coastguard Worker  if (!candidates.empty()) {
486*d9f75844SAndroid Build Coastguard Worker    _peerConnection->RemoveIceCandidates(candidates);
487*d9f75844SAndroid Build Coastguard Worker  }
488*d9f75844SAndroid Build Coastguard Worker}
489*d9f75844SAndroid Build Coastguard Worker
490*d9f75844SAndroid Build Coastguard Worker- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
491*d9f75844SAndroid Build Coastguard Worker  if (!_peerConnection->AddStream(stream.nativeMediaStream.get())) {
492*d9f75844SAndroid Build Coastguard Worker    RTCLogError(@"Failed to add stream: %@", stream);
493*d9f75844SAndroid Build Coastguard Worker    return;
494*d9f75844SAndroid Build Coastguard Worker  }
495*d9f75844SAndroid Build Coastguard Worker  [_localStreams addObject:stream];
496*d9f75844SAndroid Build Coastguard Worker}
497*d9f75844SAndroid Build Coastguard Worker
498*d9f75844SAndroid Build Coastguard Worker- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
499*d9f75844SAndroid Build Coastguard Worker  _peerConnection->RemoveStream(stream.nativeMediaStream.get());
500*d9f75844SAndroid Build Coastguard Worker  [_localStreams removeObject:stream];
501*d9f75844SAndroid Build Coastguard Worker}
502*d9f75844SAndroid Build Coastguard Worker
503*d9f75844SAndroid Build Coastguard Worker- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
504*d9f75844SAndroid Build Coastguard Worker                                         streamIds:(NSArray<NSString *> *)streamIds {
505*d9f75844SAndroid Build Coastguard Worker  std::vector<std::string> nativeStreamIds;
506*d9f75844SAndroid Build Coastguard Worker  for (NSString *streamId in streamIds) {
507*d9f75844SAndroid Build Coastguard Worker    nativeStreamIds.push_back([streamId UTF8String]);
508*d9f75844SAndroid Build Coastguard Worker  }
509*d9f75844SAndroid Build Coastguard Worker  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
510*d9f75844SAndroid Build Coastguard Worker      _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
511*d9f75844SAndroid Build Coastguard Worker  if (!nativeSenderOrError.ok()) {
512*d9f75844SAndroid Build Coastguard Worker    RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
513*d9f75844SAndroid Build Coastguard Worker    return nil;
514*d9f75844SAndroid Build Coastguard Worker  }
515*d9f75844SAndroid Build Coastguard Worker  return [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
516*d9f75844SAndroid Build Coastguard Worker                                              nativeRtpSender:nativeSenderOrError.MoveValue()];
517*d9f75844SAndroid Build Coastguard Worker}
518*d9f75844SAndroid Build Coastguard Worker
519*d9f75844SAndroid Build Coastguard Worker- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender {
520*d9f75844SAndroid Build Coastguard Worker  bool result = _peerConnection->RemoveTrackOrError(sender.nativeRtpSender).ok();
521*d9f75844SAndroid Build Coastguard Worker  if (!result) {
522*d9f75844SAndroid Build Coastguard Worker    RTCLogError(@"Failed to remote track %@", sender);
523*d9f75844SAndroid Build Coastguard Worker  }
524*d9f75844SAndroid Build Coastguard Worker  return result;
525*d9f75844SAndroid Build Coastguard Worker}
526*d9f75844SAndroid Build Coastguard Worker
527*d9f75844SAndroid Build Coastguard Worker- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack:
528*d9f75844SAndroid Build Coastguard Worker    (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track {
529*d9f75844SAndroid Build Coastguard Worker  return [self addTransceiverWithTrack:track
530*d9f75844SAndroid Build Coastguard Worker                                  init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
531*d9f75844SAndroid Build Coastguard Worker}
532*d9f75844SAndroid Build Coastguard Worker
533*d9f75844SAndroid Build Coastguard Worker- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
534*d9f75844SAndroid Build Coastguard Worker    addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
535*d9f75844SAndroid Build Coastguard Worker                       init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
536*d9f75844SAndroid Build Coastguard Worker  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
537*d9f75844SAndroid Build Coastguard Worker      _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
538*d9f75844SAndroid Build Coastguard Worker  if (!nativeTransceiverOrError.ok()) {
539*d9f75844SAndroid Build Coastguard Worker    RTCLogError(
540*d9f75844SAndroid Build Coastguard Worker        @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
541*d9f75844SAndroid Build Coastguard Worker    return nil;
542*d9f75844SAndroid Build Coastguard Worker  }
543*d9f75844SAndroid Build Coastguard Worker  return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
544*d9f75844SAndroid Build Coastguard Worker           initWithFactory:self.factory
545*d9f75844SAndroid Build Coastguard Worker      nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
546*d9f75844SAndroid Build Coastguard Worker}
547*d9f75844SAndroid Build Coastguard Worker
548*d9f75844SAndroid Build Coastguard Worker- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
549*d9f75844SAndroid Build Coastguard Worker  return [self addTransceiverOfType:mediaType
550*d9f75844SAndroid Build Coastguard Worker                               init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
551*d9f75844SAndroid Build Coastguard Worker}
552*d9f75844SAndroid Build Coastguard Worker
553*d9f75844SAndroid Build Coastguard Worker- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
554*d9f75844SAndroid Build Coastguard Worker    addTransceiverOfType:(RTCRtpMediaType)mediaType
555*d9f75844SAndroid Build Coastguard Worker                    init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
556*d9f75844SAndroid Build Coastguard Worker  webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
557*d9f75844SAndroid Build Coastguard Worker      _peerConnection->AddTransceiver(
558*d9f75844SAndroid Build Coastguard Worker          [RTC_OBJC_TYPE(RTCRtpReceiver) nativeMediaTypeForMediaType:mediaType], init.nativeInit);
559*d9f75844SAndroid Build Coastguard Worker  if (!nativeTransceiverOrError.ok()) {
560*d9f75844SAndroid Build Coastguard Worker    RTCLogError(@"Failed to add transceiver %@: %s",
561*d9f75844SAndroid Build Coastguard Worker                [RTC_OBJC_TYPE(RTCRtpReceiver) stringForMediaType:mediaType],
562*d9f75844SAndroid Build Coastguard Worker                nativeTransceiverOrError.error().message());
563*d9f75844SAndroid Build Coastguard Worker    return nil;
564*d9f75844SAndroid Build Coastguard Worker  }
565*d9f75844SAndroid Build Coastguard Worker  return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
566*d9f75844SAndroid Build Coastguard Worker           initWithFactory:self.factory
567*d9f75844SAndroid Build Coastguard Worker      nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
568*d9f75844SAndroid Build Coastguard Worker}
569*d9f75844SAndroid Build Coastguard Worker
570*d9f75844SAndroid Build Coastguard Worker- (void)restartIce {
571*d9f75844SAndroid Build Coastguard Worker  _peerConnection->RestartIce();
572*d9f75844SAndroid Build Coastguard Worker}
573*d9f75844SAndroid Build Coastguard Worker
574*d9f75844SAndroid Build Coastguard Worker- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
575*d9f75844SAndroid Build Coastguard Worker          completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
576*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(completionHandler != nil);
577*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer =
578*d9f75844SAndroid Build Coastguard Worker      rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler);
579*d9f75844SAndroid Build Coastguard Worker  webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
580*d9f75844SAndroid Build Coastguard Worker  CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
581*d9f75844SAndroid Build Coastguard Worker
582*d9f75844SAndroid Build Coastguard Worker  _peerConnection->CreateOffer(observer.get(), options);
583*d9f75844SAndroid Build Coastguard Worker}
584*d9f75844SAndroid Build Coastguard Worker
585*d9f75844SAndroid Build Coastguard Worker- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
586*d9f75844SAndroid Build Coastguard Worker           completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
587*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(completionHandler != nil);
588*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer =
589*d9f75844SAndroid Build Coastguard Worker      rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler);
590*d9f75844SAndroid Build Coastguard Worker  webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
591*d9f75844SAndroid Build Coastguard Worker  CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
592*d9f75844SAndroid Build Coastguard Worker
593*d9f75844SAndroid Build Coastguard Worker  _peerConnection->CreateAnswer(observer.get(), options);
594*d9f75844SAndroid Build Coastguard Worker}
595*d9f75844SAndroid Build Coastguard Worker
596*d9f75844SAndroid Build Coastguard Worker- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
597*d9f75844SAndroid Build Coastguard Worker          completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
598*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(completionHandler != nil);
599*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer =
600*d9f75844SAndroid Build Coastguard Worker      rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
601*d9f75844SAndroid Build Coastguard Worker  _peerConnection->SetLocalDescription(sdp.nativeDescription, observer);
602*d9f75844SAndroid Build Coastguard Worker}
603*d9f75844SAndroid Build Coastguard Worker
604*d9f75844SAndroid Build Coastguard Worker- (void)setLocalDescriptionWithCompletionHandler:
605*d9f75844SAndroid Build Coastguard Worker    (RTCSetSessionDescriptionCompletionHandler)completionHandler {
606*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(completionHandler != nil);
607*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer =
608*d9f75844SAndroid Build Coastguard Worker      rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
609*d9f75844SAndroid Build Coastguard Worker  _peerConnection->SetLocalDescription(observer);
610*d9f75844SAndroid Build Coastguard Worker}
611*d9f75844SAndroid Build Coastguard Worker
612*d9f75844SAndroid Build Coastguard Worker- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
613*d9f75844SAndroid Build Coastguard Worker           completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
614*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(completionHandler != nil);
615*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer =
616*d9f75844SAndroid Build Coastguard Worker      rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
617*d9f75844SAndroid Build Coastguard Worker  _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer);
618*d9f75844SAndroid Build Coastguard Worker}
619*d9f75844SAndroid Build Coastguard Worker
620*d9f75844SAndroid Build Coastguard Worker- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
621*d9f75844SAndroid Build Coastguard Worker          currentBitrateBps:(nullable NSNumber *)currentBitrateBps
622*d9f75844SAndroid Build Coastguard Worker              maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
623*d9f75844SAndroid Build Coastguard Worker  webrtc::BitrateSettings params;
624*d9f75844SAndroid Build Coastguard Worker  if (minBitrateBps != nil) {
625*d9f75844SAndroid Build Coastguard Worker    params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
626*d9f75844SAndroid Build Coastguard Worker  }
627*d9f75844SAndroid Build Coastguard Worker  if (currentBitrateBps != nil) {
628*d9f75844SAndroid Build Coastguard Worker    params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
629*d9f75844SAndroid Build Coastguard Worker  }
630*d9f75844SAndroid Build Coastguard Worker  if (maxBitrateBps != nil) {
631*d9f75844SAndroid Build Coastguard Worker    params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
632*d9f75844SAndroid Build Coastguard Worker  }
633*d9f75844SAndroid Build Coastguard Worker  return _peerConnection->SetBitrate(params).ok();
634*d9f75844SAndroid Build Coastguard Worker}
635*d9f75844SAndroid Build Coastguard Worker
636*d9f75844SAndroid Build Coastguard Worker- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
637*d9f75844SAndroid Build Coastguard Worker                      maxSizeInBytes:(int64_t)maxSizeInBytes {
638*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(filePath.length);
639*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK_GT(maxSizeInBytes, 0);
640*d9f75844SAndroid Build Coastguard Worker  RTC_DCHECK(!_hasStartedRtcEventLog);
641*d9f75844SAndroid Build Coastguard Worker  if (_hasStartedRtcEventLog) {
642*d9f75844SAndroid Build Coastguard Worker    RTCLogError(@"Event logging already started.");
643*d9f75844SAndroid Build Coastguard Worker    return NO;
644*d9f75844SAndroid Build Coastguard Worker  }
645*d9f75844SAndroid Build Coastguard Worker  FILE *f = fopen(filePath.UTF8String, "wb");
646*d9f75844SAndroid Build Coastguard Worker  if (!f) {
647*d9f75844SAndroid Build Coastguard Worker    RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
648*d9f75844SAndroid Build Coastguard Worker    return NO;
649*d9f75844SAndroid Build Coastguard Worker  }
650*d9f75844SAndroid Build Coastguard Worker  // TODO(eladalon): It would be better to not allow negative values into PC.
651*d9f75844SAndroid Build Coastguard Worker  const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput :
652*d9f75844SAndroid Build Coastguard Worker                                                 rtc::saturated_cast<size_t>(maxSizeInBytes);
653*d9f75844SAndroid Build Coastguard Worker
654*d9f75844SAndroid Build Coastguard Worker  _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog(
655*d9f75844SAndroid Build Coastguard Worker      std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size));
656*d9f75844SAndroid Build Coastguard Worker  return _hasStartedRtcEventLog;
657*d9f75844SAndroid Build Coastguard Worker}
658*d9f75844SAndroid Build Coastguard Worker
659*d9f75844SAndroid Build Coastguard Worker- (void)stopRtcEventLog {
660*d9f75844SAndroid Build Coastguard Worker  _peerConnection->StopRtcEventLog();
661*d9f75844SAndroid Build Coastguard Worker  _hasStartedRtcEventLog = NO;
662*d9f75844SAndroid Build Coastguard Worker}
663*d9f75844SAndroid Build Coastguard Worker
664*d9f75844SAndroid Build Coastguard Worker- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId {
665*d9f75844SAndroid Build Coastguard Worker  std::string nativeKind = [NSString stdStringForString:kind];
666*d9f75844SAndroid Build Coastguard Worker  std::string nativeStreamId = [NSString stdStringForString:streamId];
667*d9f75844SAndroid Build Coastguard Worker  rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
668*d9f75844SAndroid Build Coastguard Worker      _peerConnection->CreateSender(nativeKind, nativeStreamId));
669*d9f75844SAndroid Build Coastguard Worker  return nativeSender ? [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
670*d9f75844SAndroid Build Coastguard Worker                                                             nativeRtpSender:nativeSender] :
671*d9f75844SAndroid Build Coastguard Worker                        nil;
672*d9f75844SAndroid Build Coastguard Worker}
673*d9f75844SAndroid Build Coastguard Worker
674*d9f75844SAndroid Build Coastguard Worker- (NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *)senders {
675*d9f75844SAndroid Build Coastguard Worker  std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
676*d9f75844SAndroid Build Coastguard Worker      _peerConnection->GetSenders());
677*d9f75844SAndroid Build Coastguard Worker  NSMutableArray *senders = [[NSMutableArray alloc] init];
678*d9f75844SAndroid Build Coastguard Worker  for (const auto &nativeSender : nativeSenders) {
679*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCRtpSender) *sender =
680*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
681*d9f75844SAndroid Build Coastguard Worker                                             nativeRtpSender:nativeSender];
682*d9f75844SAndroid Build Coastguard Worker    [senders addObject:sender];
683*d9f75844SAndroid Build Coastguard Worker  }
684*d9f75844SAndroid Build Coastguard Worker  return senders;
685*d9f75844SAndroid Build Coastguard Worker}
686*d9f75844SAndroid Build Coastguard Worker
687*d9f75844SAndroid Build Coastguard Worker- (NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *)receivers {
688*d9f75844SAndroid Build Coastguard Worker  std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
689*d9f75844SAndroid Build Coastguard Worker      _peerConnection->GetReceivers());
690*d9f75844SAndroid Build Coastguard Worker  NSMutableArray *receivers = [[NSMutableArray alloc] init];
691*d9f75844SAndroid Build Coastguard Worker  for (const auto &nativeReceiver : nativeReceivers) {
692*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCRtpReceiver) *receiver =
693*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:self.factory
694*d9f75844SAndroid Build Coastguard Worker                                             nativeRtpReceiver:nativeReceiver];
695*d9f75844SAndroid Build Coastguard Worker    [receivers addObject:receiver];
696*d9f75844SAndroid Build Coastguard Worker  }
697*d9f75844SAndroid Build Coastguard Worker  return receivers;
698*d9f75844SAndroid Build Coastguard Worker}
699*d9f75844SAndroid Build Coastguard Worker
700*d9f75844SAndroid Build Coastguard Worker- (NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *)transceivers {
701*d9f75844SAndroid Build Coastguard Worker  std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
702*d9f75844SAndroid Build Coastguard Worker      _peerConnection->GetTransceivers());
703*d9f75844SAndroid Build Coastguard Worker  NSMutableArray *transceivers = [[NSMutableArray alloc] init];
704*d9f75844SAndroid Build Coastguard Worker  for (const auto &nativeTransceiver : nativeTransceivers) {
705*d9f75844SAndroid Build Coastguard Worker    RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
706*d9f75844SAndroid Build Coastguard Worker        [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:self.factory
707*d9f75844SAndroid Build Coastguard Worker                                             nativeRtpTransceiver:nativeTransceiver];
708*d9f75844SAndroid Build Coastguard Worker    [transceivers addObject:transceiver];
709*d9f75844SAndroid Build Coastguard Worker  }
710*d9f75844SAndroid Build Coastguard Worker  return transceivers;
711*d9f75844SAndroid Build Coastguard Worker}
712*d9f75844SAndroid Build Coastguard Worker
713*d9f75844SAndroid Build Coastguard Worker#pragma mark - Private
714*d9f75844SAndroid Build Coastguard Worker
715*d9f75844SAndroid Build Coastguard Worker+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
716*d9f75844SAndroid Build Coastguard Worker    (RTCSignalingState)state {
717*d9f75844SAndroid Build Coastguard Worker  switch (state) {
718*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateStable:
719*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kStable;
720*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveLocalOffer:
721*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kHaveLocalOffer;
722*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveLocalPrAnswer:
723*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
724*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveRemoteOffer:
725*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
726*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveRemotePrAnswer:
727*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
728*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateClosed:
729*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kClosed;
730*d9f75844SAndroid Build Coastguard Worker  }
731*d9f75844SAndroid Build Coastguard Worker}
732*d9f75844SAndroid Build Coastguard Worker
733*d9f75844SAndroid Build Coastguard Worker+ (RTCSignalingState)signalingStateForNativeState:
734*d9f75844SAndroid Build Coastguard Worker    (webrtc::PeerConnectionInterface::SignalingState)nativeState {
735*d9f75844SAndroid Build Coastguard Worker  switch (nativeState) {
736*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kStable:
737*d9f75844SAndroid Build Coastguard Worker      return RTCSignalingStateStable;
738*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kHaveLocalOffer:
739*d9f75844SAndroid Build Coastguard Worker      return RTCSignalingStateHaveLocalOffer;
740*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
741*d9f75844SAndroid Build Coastguard Worker      return RTCSignalingStateHaveLocalPrAnswer;
742*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
743*d9f75844SAndroid Build Coastguard Worker      return RTCSignalingStateHaveRemoteOffer;
744*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
745*d9f75844SAndroid Build Coastguard Worker      return RTCSignalingStateHaveRemotePrAnswer;
746*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kClosed:
747*d9f75844SAndroid Build Coastguard Worker      return RTCSignalingStateClosed;
748*d9f75844SAndroid Build Coastguard Worker  }
749*d9f75844SAndroid Build Coastguard Worker}
750*d9f75844SAndroid Build Coastguard Worker
751*d9f75844SAndroid Build Coastguard Worker+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
752*d9f75844SAndroid Build Coastguard Worker  switch (state) {
753*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateStable:
754*d9f75844SAndroid Build Coastguard Worker      return @"STABLE";
755*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveLocalOffer:
756*d9f75844SAndroid Build Coastguard Worker      return @"HAVE_LOCAL_OFFER";
757*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveLocalPrAnswer:
758*d9f75844SAndroid Build Coastguard Worker      return @"HAVE_LOCAL_PRANSWER";
759*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveRemoteOffer:
760*d9f75844SAndroid Build Coastguard Worker      return @"HAVE_REMOTE_OFFER";
761*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateHaveRemotePrAnswer:
762*d9f75844SAndroid Build Coastguard Worker      return @"HAVE_REMOTE_PRANSWER";
763*d9f75844SAndroid Build Coastguard Worker    case RTCSignalingStateClosed:
764*d9f75844SAndroid Build Coastguard Worker      return @"CLOSED";
765*d9f75844SAndroid Build Coastguard Worker  }
766*d9f75844SAndroid Build Coastguard Worker}
767*d9f75844SAndroid Build Coastguard Worker
768*d9f75844SAndroid Build Coastguard Worker+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
769*d9f75844SAndroid Build Coastguard Worker        (RTCPeerConnectionState)state {
770*d9f75844SAndroid Build Coastguard Worker  switch (state) {
771*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateNew:
772*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
773*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateConnecting:
774*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
775*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateConnected:
776*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
777*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateFailed:
778*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
779*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateDisconnected:
780*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
781*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateClosed:
782*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
783*d9f75844SAndroid Build Coastguard Worker  }
784*d9f75844SAndroid Build Coastguard Worker}
785*d9f75844SAndroid Build Coastguard Worker
786*d9f75844SAndroid Build Coastguard Worker+ (RTCPeerConnectionState)connectionStateForNativeState:
787*d9f75844SAndroid Build Coastguard Worker        (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
788*d9f75844SAndroid Build Coastguard Worker  switch (nativeState) {
789*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
790*d9f75844SAndroid Build Coastguard Worker      return RTCPeerConnectionStateNew;
791*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
792*d9f75844SAndroid Build Coastguard Worker      return RTCPeerConnectionStateConnecting;
793*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
794*d9f75844SAndroid Build Coastguard Worker      return RTCPeerConnectionStateConnected;
795*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
796*d9f75844SAndroid Build Coastguard Worker      return RTCPeerConnectionStateFailed;
797*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
798*d9f75844SAndroid Build Coastguard Worker      return RTCPeerConnectionStateDisconnected;
799*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
800*d9f75844SAndroid Build Coastguard Worker      return RTCPeerConnectionStateClosed;
801*d9f75844SAndroid Build Coastguard Worker  }
802*d9f75844SAndroid Build Coastguard Worker}
803*d9f75844SAndroid Build Coastguard Worker
804*d9f75844SAndroid Build Coastguard Worker+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
805*d9f75844SAndroid Build Coastguard Worker  switch (state) {
806*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateNew:
807*d9f75844SAndroid Build Coastguard Worker      return @"NEW";
808*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateConnecting:
809*d9f75844SAndroid Build Coastguard Worker      return @"CONNECTING";
810*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateConnected:
811*d9f75844SAndroid Build Coastguard Worker      return @"CONNECTED";
812*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateFailed:
813*d9f75844SAndroid Build Coastguard Worker      return @"FAILED";
814*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateDisconnected:
815*d9f75844SAndroid Build Coastguard Worker      return @"DISCONNECTED";
816*d9f75844SAndroid Build Coastguard Worker    case RTCPeerConnectionStateClosed:
817*d9f75844SAndroid Build Coastguard Worker      return @"CLOSED";
818*d9f75844SAndroid Build Coastguard Worker  }
819*d9f75844SAndroid Build Coastguard Worker}
820*d9f75844SAndroid Build Coastguard Worker
821*d9f75844SAndroid Build Coastguard Worker+ (webrtc::PeerConnectionInterface::IceConnectionState)
822*d9f75844SAndroid Build Coastguard Worker    nativeIceConnectionStateForState:(RTCIceConnectionState)state {
823*d9f75844SAndroid Build Coastguard Worker  switch (state) {
824*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateNew:
825*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionNew;
826*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateChecking:
827*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionChecking;
828*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateConnected:
829*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionConnected;
830*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateCompleted:
831*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
832*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateFailed:
833*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionFailed;
834*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateDisconnected:
835*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
836*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateClosed:
837*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionClosed;
838*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateCount:
839*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceConnectionMax;
840*d9f75844SAndroid Build Coastguard Worker  }
841*d9f75844SAndroid Build Coastguard Worker}
842*d9f75844SAndroid Build Coastguard Worker
843*d9f75844SAndroid Build Coastguard Worker+ (RTCIceConnectionState)iceConnectionStateForNativeState:
844*d9f75844SAndroid Build Coastguard Worker    (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
845*d9f75844SAndroid Build Coastguard Worker  switch (nativeState) {
846*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionNew:
847*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateNew;
848*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionChecking:
849*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateChecking;
850*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionConnected:
851*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateConnected;
852*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
853*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateCompleted;
854*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionFailed:
855*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateFailed;
856*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
857*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateDisconnected;
858*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionClosed:
859*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateClosed;
860*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceConnectionMax:
861*d9f75844SAndroid Build Coastguard Worker      return RTCIceConnectionStateCount;
862*d9f75844SAndroid Build Coastguard Worker  }
863*d9f75844SAndroid Build Coastguard Worker}
864*d9f75844SAndroid Build Coastguard Worker
865*d9f75844SAndroid Build Coastguard Worker+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
866*d9f75844SAndroid Build Coastguard Worker  switch (state) {
867*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateNew:
868*d9f75844SAndroid Build Coastguard Worker      return @"NEW";
869*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateChecking:
870*d9f75844SAndroid Build Coastguard Worker      return @"CHECKING";
871*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateConnected:
872*d9f75844SAndroid Build Coastguard Worker      return @"CONNECTED";
873*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateCompleted:
874*d9f75844SAndroid Build Coastguard Worker      return @"COMPLETED";
875*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateFailed:
876*d9f75844SAndroid Build Coastguard Worker      return @"FAILED";
877*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateDisconnected:
878*d9f75844SAndroid Build Coastguard Worker      return @"DISCONNECTED";
879*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateClosed:
880*d9f75844SAndroid Build Coastguard Worker      return @"CLOSED";
881*d9f75844SAndroid Build Coastguard Worker    case RTCIceConnectionStateCount:
882*d9f75844SAndroid Build Coastguard Worker      return @"COUNT";
883*d9f75844SAndroid Build Coastguard Worker  }
884*d9f75844SAndroid Build Coastguard Worker}
885*d9f75844SAndroid Build Coastguard Worker
886*d9f75844SAndroid Build Coastguard Worker+ (webrtc::PeerConnectionInterface::IceGatheringState)
887*d9f75844SAndroid Build Coastguard Worker    nativeIceGatheringStateForState:(RTCIceGatheringState)state {
888*d9f75844SAndroid Build Coastguard Worker  switch (state) {
889*d9f75844SAndroid Build Coastguard Worker    case RTCIceGatheringStateNew:
890*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceGatheringNew;
891*d9f75844SAndroid Build Coastguard Worker    case RTCIceGatheringStateGathering:
892*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceGatheringGathering;
893*d9f75844SAndroid Build Coastguard Worker    case RTCIceGatheringStateComplete:
894*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kIceGatheringComplete;
895*d9f75844SAndroid Build Coastguard Worker  }
896*d9f75844SAndroid Build Coastguard Worker}
897*d9f75844SAndroid Build Coastguard Worker
898*d9f75844SAndroid Build Coastguard Worker+ (RTCIceGatheringState)iceGatheringStateForNativeState:
899*d9f75844SAndroid Build Coastguard Worker    (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
900*d9f75844SAndroid Build Coastguard Worker  switch (nativeState) {
901*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceGatheringNew:
902*d9f75844SAndroid Build Coastguard Worker      return RTCIceGatheringStateNew;
903*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceGatheringGathering:
904*d9f75844SAndroid Build Coastguard Worker      return RTCIceGatheringStateGathering;
905*d9f75844SAndroid Build Coastguard Worker    case webrtc::PeerConnectionInterface::kIceGatheringComplete:
906*d9f75844SAndroid Build Coastguard Worker      return RTCIceGatheringStateComplete;
907*d9f75844SAndroid Build Coastguard Worker  }
908*d9f75844SAndroid Build Coastguard Worker}
909*d9f75844SAndroid Build Coastguard Worker
910*d9f75844SAndroid Build Coastguard Worker+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
911*d9f75844SAndroid Build Coastguard Worker  switch (state) {
912*d9f75844SAndroid Build Coastguard Worker    case RTCIceGatheringStateNew:
913*d9f75844SAndroid Build Coastguard Worker      return @"NEW";
914*d9f75844SAndroid Build Coastguard Worker    case RTCIceGatheringStateGathering:
915*d9f75844SAndroid Build Coastguard Worker      return @"GATHERING";
916*d9f75844SAndroid Build Coastguard Worker    case RTCIceGatheringStateComplete:
917*d9f75844SAndroid Build Coastguard Worker      return @"COMPLETE";
918*d9f75844SAndroid Build Coastguard Worker  }
919*d9f75844SAndroid Build Coastguard Worker}
920*d9f75844SAndroid Build Coastguard Worker
921*d9f75844SAndroid Build Coastguard Worker+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
922*d9f75844SAndroid Build Coastguard Worker    nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
923*d9f75844SAndroid Build Coastguard Worker  switch (level) {
924*d9f75844SAndroid Build Coastguard Worker    case RTCStatsOutputLevelStandard:
925*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
926*d9f75844SAndroid Build Coastguard Worker    case RTCStatsOutputLevelDebug:
927*d9f75844SAndroid Build Coastguard Worker      return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
928*d9f75844SAndroid Build Coastguard Worker  }
929*d9f75844SAndroid Build Coastguard Worker}
930*d9f75844SAndroid Build Coastguard Worker
931*d9f75844SAndroid Build Coastguard Worker- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
932*d9f75844SAndroid Build Coastguard Worker  return _peerConnection;
933*d9f75844SAndroid Build Coastguard Worker}
934*d9f75844SAndroid Build Coastguard Worker
935*d9f75844SAndroid Build Coastguard Worker@end
936