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