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