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