From c75b35ab401bc092c2ad73434f63322bb910bb2f Mon Sep 17 00:00:00 2001 From: Yura Yaroshevich Date: Wed, 27 Jun 2018 17:09:14 +0300 Subject: [PATCH] Fixed crash when PCF is destroyed before DataChannel in ObjC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:9231 Change-Id: Ifad698b366be61d33ffca81cf4f8ca8aba2988a2 Reviewed-on: https://webrtc-review.googlesource.com/86040 Reviewed-by: Kári Helgason Commit-Queue: Kári Helgason Cr-Commit-Position: refs/heads/master@{#23771} --- .../PeerConnection/RTCDataChannel+Private.h | 6 ++-- .../Classes/PeerConnection/RTCDataChannel.mm | 7 +++-- .../RTCPeerConnection+DataChannel.mm | 2 +- .../PeerConnection/RTCPeerConnection.mm | 4 +-- .../RTCPeerConnectionFactory_xctest.m | 30 +++++++++++++++++++ 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel+Private.h index 5ab308b10e..9849fd95c9 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel+Private.h +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel+Private.h @@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN +@class RTCPeerConnectionFactory; + @interface RTCDataBuffer () /** @@ -31,8 +33,8 @@ NS_ASSUME_NONNULL_BEGIN @interface RTCDataChannel () /** Initialize an RTCDataChannel from a native DataChannelInterface. */ -- (instancetype)initWithNativeDataChannel: - (rtc::scoped_refptr)nativeDataChannel +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + nativeDataChannel:(rtc::scoped_refptr)nativeDataChannel NS_DESIGNATED_INITIALIZER; + (webrtc::DataChannelInterface::DataState)nativeDataChannelStateForState: diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel.mm index 706e43e2ed..06ca453bd0 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel.mm @@ -85,6 +85,7 @@ class DataChannelDelegateAdapter : public DataChannelObserver { @implementation RTCDataChannel { + RTCPeerConnectionFactory *_factory; rtc::scoped_refptr _nativeDataChannel; std::unique_ptr _observer; BOOL _isObserverRegistered; @@ -165,10 +166,12 @@ class DataChannelDelegateAdapter : public DataChannelObserver { #pragma mark - Private -- (instancetype)initWithNativeDataChannel: - (rtc::scoped_refptr)nativeDataChannel { +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + nativeDataChannel: + (rtc::scoped_refptr)nativeDataChannel { NSParameterAssert(nativeDataChannel); if (self = [super init]) { + _factory = factory; _nativeDataChannel = nativeDataChannel; _observer.reset(new webrtc::DataChannelDelegateAdapter(self)); _nativeDataChannel->RegisterObserver(_observer.get()); diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+DataChannel.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+DataChannel.mm index d17d9ac2f4..c6f2b0bc9f 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+DataChannel.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+DataChannel.mm @@ -27,7 +27,7 @@ if (!dataChannel) { return nil; } - return [[RTCDataChannel alloc] initWithNativeDataChannel:dataChannel]; + return [[RTCDataChannel alloc] initWithFactory:self.factory nativeDataChannel:dataChannel]; } @end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm index 8d10c34b6e..b5c8cba689 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm @@ -163,9 +163,9 @@ void PeerConnectionDelegateAdapter::OnTrack( void PeerConnectionDelegateAdapter::OnDataChannel( rtc::scoped_refptr data_channel) { - RTCDataChannel *dataChannel = - [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel]; RTCPeerConnection *peer_connection = peer_connection_; + RTCDataChannel *dataChannel = [[RTCDataChannel alloc] initWithFactory:peer_connection.factory + nativeDataChannel:data_channel]; [peer_connection.delegate peerConnection:peer_connection didOpenDataChannel:dataChannel]; } diff --git a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m index f8eb89a4cf..f33b21852c 100644 --- a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m +++ b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m @@ -9,6 +9,8 @@ */ #import +#import +#import #import #import #import @@ -60,4 +62,32 @@ XCTAssertTrue(true, "Expect test does not crash"); } +- (void)testDataChannelLifetime { + @autoreleasepool { + RTCConfiguration *config = [[RTCConfiguration alloc] init]; + RTCMediaConstraints *contraints = + [[RTCMediaConstraints alloc] initWithMandatoryConstraints:@{} optionalConstraints:nil]; + RTCDataChannelConfiguration *dataChannelConfig = [[RTCDataChannelConfiguration alloc] init]; + + RTCPeerConnectionFactory *factory; + RTCPeerConnection *peerConnection; + RTCDataChannel *dataChannel; + + @autoreleasepool { + factory = [[RTCPeerConnectionFactory alloc] init]; + peerConnection = + [factory peerConnectionWithConfiguration:config constraints:contraints delegate:nil]; + dataChannel = + [peerConnection dataChannelForLabel:@"test_channel" configuration:dataChannelConfig]; + XCTAssertTrue(dataChannel != nil); + [peerConnection close]; + peerConnection = nil; + factory = nil; + } + dataChannel = nil; + } + + XCTAssertTrue(true, "Expect test does not crash"); +} + @end