From 08f14dd388f1e535480ced5ede6aadff5c8e2800 Mon Sep 17 00:00:00 2001 From: Yura Yaroshevich Date: Mon, 9 Jul 2018 11:56:06 +0300 Subject: [PATCH] Fixed crash when PCF is destroyed before RTCRtpTranceiver in ObjC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:9231 Change-Id: Icecc319eaf6edd2c4b7b05fda984660412cb0d40 Reviewed-on: https://webrtc-review.googlesource.com/87439 Reviewed-by: Kári Helgason Commit-Queue: Kári Helgason Cr-Commit-Position: refs/heads/master@{#23884} --- .../PeerConnection/RTCPeerConnection.mm | 17 ++++++----- .../RTCRtpTransceiver+Private.h | 7 +++-- .../PeerConnection/RTCRtpTransceiver.mm | 8 +++-- .../RTCPeerConnectionFactory_xctest.m | 29 +++++++++++++++++++ 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm index b5c8cba689..f6b2343eb7 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm @@ -151,9 +151,10 @@ void PeerConnectionDelegateAdapter::OnRemoveStream( void PeerConnectionDelegateAdapter::OnTrack( rtc::scoped_refptr nativeTransceiver) { - RTCRtpTransceiver *transceiver = - [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver]; RTCPeerConnection *peer_connection = peer_connection_; + RTCRtpTransceiver *transceiver = + [[RTCRtpTransceiver alloc] initWithFactory:peer_connection.factory + nativeRtpTransceiver:nativeTransceiver]; if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) { [peer_connection.delegate peerConnection:peer_connection @@ -409,8 +410,8 @@ void PeerConnectionDelegateAdapter::OnAddTrack( @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message()); return nil; } - return - [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; + return [[RTCRtpTransceiver alloc] initWithFactory:self.factory + nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; } - (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType { @@ -428,8 +429,8 @@ void PeerConnectionDelegateAdapter::OnAddTrack( nativeTransceiverOrError.error().message()); return nil; } - return - [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; + return [[RTCRtpTransceiver alloc] initWithFactory:self.factory + nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; } - (void)offerForConstraints:(RTCMediaConstraints *)constraints @@ -554,8 +555,8 @@ void PeerConnectionDelegateAdapter::OnAddTrack( _peerConnection->GetTransceivers()); NSMutableArray *transceivers = [[NSMutableArray alloc] init]; for (auto nativeTransceiver : nativeTransceivers) { - RTCRtpTransceiver *transceiver = - [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver]; + RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory + nativeRtpTransceiver:nativeTransceiver]; [transceivers addObject:transceiver]; } return transceivers; diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h index cc1f4fe42e..ee361ea8bf 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver+Private.h @@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN +@class RTCPeerConnectionFactory; + @interface RTCRtpTransceiverInit () @property(nonatomic, readonly) webrtc::RtpTransceiverInit nativeInit; @@ -26,8 +28,9 @@ NS_ASSUME_NONNULL_BEGIN nativeRtpTransceiver; /** Initialize an RTCRtpTransceiver with a native RtpTransceiverInterface. */ -- (instancetype)initWithNativeRtpTransceiver: - (rtc::scoped_refptr)nativeRtpTransceiver +- (instancetype)initWithFactory:(RTCPeerConnectionFactory*)factory + nativeRtpTransceiver: + (rtc::scoped_refptr)nativeRtpTransceiver NS_DESIGNATED_INITIALIZER; + (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection: diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm index 5fe7569abd..780fcd5fe7 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpTransceiver.mm @@ -45,6 +45,7 @@ @end @implementation RTCRtpTransceiver { + RTCPeerConnectionFactory *_factory; rtc::scoped_refptr _nativeRtpTransceiver; } @@ -120,10 +121,13 @@ return _nativeRtpTransceiver; } -- (instancetype)initWithNativeRtpTransceiver: - (rtc::scoped_refptr)nativeRtpTransceiver { +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + nativeRtpTransceiver: + (rtc::scoped_refptr)nativeRtpTransceiver { + NSParameterAssert(factory); NSParameterAssert(nativeRtpTransceiver); if (self = [super init]) { + _factory = factory; _nativeRtpTransceiver = nativeRtpTransceiver; _sender = [[RTCRtpSender alloc] initWithNativeRtpSender:nativeRtpTransceiver->sender()]; _receiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeRtpTransceiver->receiver()]; diff --git a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m index f33b21852c..4e679fab91 100644 --- a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m +++ b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m @@ -14,6 +14,7 @@ #import #import #import +#import #import @@ -90,4 +91,32 @@ XCTAssertTrue(true, "Expect test does not crash"); } +- (void)testRTCRtpTransceiverLifetime { + @autoreleasepool { + RTCConfiguration *config = [[RTCConfiguration alloc] init]; + config.sdpSemantics = RTCSdpSemanticsUnifiedPlan; + RTCMediaConstraints *contraints = + [[RTCMediaConstraints alloc] initWithMandatoryConstraints:@{} optionalConstraints:nil]; + RTCRtpTransceiverInit *init = [[RTCRtpTransceiverInit alloc] init]; + + RTCPeerConnectionFactory *factory; + RTCPeerConnection *peerConnection; + RTCRtpTransceiver *tranceiver; + + @autoreleasepool { + factory = [[RTCPeerConnectionFactory alloc] init]; + peerConnection = + [factory peerConnectionWithConfiguration:config constraints:contraints delegate:nil]; + tranceiver = [peerConnection addTransceiverOfType:RTCRtpMediaTypeAudio init:init]; + XCTAssertTrue(tranceiver != nil); + [peerConnection close]; + peerConnection = nil; + factory = nil; + } + tranceiver = nil; + } + + XCTAssertTrue(true, "Expect test does not crash"); +} + @end