Fixed crash when PCF is destroyed before DataChannel in ObjC
Bug: webrtc:9231
Change-Id: Ifad698b366be61d33ffca81cf4f8ca8aba2988a2
Reviewed-on: https://webrtc-review.googlesource.com/86040
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23771}
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel+Private.h
index 5ab308b..9849fd9 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 @@
@interface RTCDataChannel ()
/** Initialize an RTCDataChannel from a native DataChannelInterface. */
-- (instancetype)initWithNativeDataChannel:
- (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel
+- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
+ nativeDataChannel:(rtc::scoped_refptr<webrtc::DataChannelInterface>)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 706e43e..06ca453 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCDataChannel.mm
@@ -85,6 +85,7 @@
@implementation RTCDataChannel {
+ RTCPeerConnectionFactory *_factory;
rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel;
std::unique_ptr<webrtc::DataChannelDelegateAdapter> _observer;
BOOL _isObserverRegistered;
@@ -165,10 +166,12 @@
#pragma mark - Private
-- (instancetype)initWithNativeDataChannel:
- (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel {
+- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
+ nativeDataChannel:
+ (rtc::scoped_refptr<webrtc::DataChannelInterface>)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 d17d9ac..c6f2b0b 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 8d10c34..b5c8cba 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
@@ -163,9 +163,9 @@
void PeerConnectionDelegateAdapter::OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> 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 f8eb89a..f33b218 100644
--- a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m
+++ b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m
@@ -9,6 +9,8 @@
*/
#import <WebRTC/RTCConfiguration.h>
+#import <WebRTC/RTCDataChannel.h>
+#import <WebRTC/RTCDataChannelConfiguration.h>
#import <WebRTC/RTCMediaConstraints.h>
#import <WebRTC/RTCPeerConnection.h>
#import <WebRTC/RTCPeerConnectionFactory.h>
@@ -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