Fixed crash when PCF is destroyed before MediaStream in ObjC
Bug: webrtc:9231
Change-Id: I04e76172dd0d5ee5e9040e773e63fd4df0c797ce
Reviewed-on: https://webrtc-review.googlesource.com/84580
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23699}
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream+Private.h
index f95d15c..3986066 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream+Private.h
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream+Private.h
@@ -26,8 +26,8 @@
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory streamId:(NSString *)streamId;
/** Initialize an RTCMediaStream from a native MediaStreamInterface. */
-- (instancetype)initWithNativeMediaStream:
- (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream;
+- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
+ nativeMediaStream:(rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream;
@end
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream.mm
index ff0cbf5..52f1771 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCMediaStream.mm
@@ -19,6 +19,7 @@
#import "RTCVideoTrack+Private.h"
@implementation RTCMediaStream {
+ RTCPeerConnectionFactory *_factory;
NSMutableArray *_audioTracks;
NSMutableArray *_videoTracks;
rtc::scoped_refptr<webrtc::MediaStreamInterface> _nativeMediaStream;
@@ -31,7 +32,7 @@
std::string nativeId = [NSString stdStringForString:streamId];
rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
factory.nativeFactory->CreateLocalMediaStream(nativeId);
- return [self initWithNativeMediaStream:stream];
+ return [self initWithFactory:factory nativeMediaStream:stream];
}
- (NSArray<RTCAudioTrack *> *)audioTracks {
@@ -91,10 +92,13 @@
return _nativeMediaStream;
}
-- (instancetype)initWithNativeMediaStream:
- (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream {
+- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
+ nativeMediaStream:
+ (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream {
NSParameterAssert(nativeMediaStream);
if (self = [super init]) {
+ _factory = factory;
+
webrtc::AudioTrackVector audioTracks = nativeMediaStream->GetAudioTracks();
webrtc::VideoTrackVector videoTracks = nativeMediaStream->GetVideoTracks();
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h
index f533605..15b05de 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection+Private.h
@@ -56,6 +56,9 @@
@interface RTCPeerConnection ()
+/** The factory used to create this RTCPeerConnection */
+@property(nonatomic, readonly) RTCPeerConnectionFactory *factory;
+
/** The native PeerConnectionInterface created during construction. */
@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::PeerConnectionInterface>
nativePeerConnection;
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
index bea0ede..8d10c34 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnection.mm
@@ -132,18 +132,19 @@
void PeerConnectionDelegateAdapter::OnAddStream(
rtc::scoped_refptr<MediaStreamInterface> stream) {
- RTCMediaStream *mediaStream =
- [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
RTCPeerConnection *peer_connection = peer_connection_;
+ RTCMediaStream *mediaStream =
+ [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
[peer_connection.delegate peerConnection:peer_connection
didAddStream:mediaStream];
}
void PeerConnectionDelegateAdapter::OnRemoveStream(
rtc::scoped_refptr<MediaStreamInterface> stream) {
- RTCMediaStream *mediaStream =
- [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
RTCPeerConnection *peer_connection = peer_connection_;
+ RTCMediaStream *mediaStream =
+ [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
+
[peer_connection.delegate peerConnection:peer_connection
didRemoveStream:mediaStream];
}
@@ -225,7 +226,8 @@
respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
for (const auto& nativeStream : streams) {
- RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithNativeMediaStream:nativeStream];
+ RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
+ nativeMediaStream:nativeStream];
[mediaStreams addObject:mediaStream];
}
RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:receiver];
@@ -249,6 +251,7 @@
}
@synthesize delegate = _delegate;
+@synthesize factory = _factory;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
configuration:(RTCConfiguration *)configuration
diff --git a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m
index 1c678d6..f8eb89a 100644
--- a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m
+++ b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactory_xctest.m
@@ -28,18 +28,36 @@
RTCMediaConstraints *contraints =
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:@{} optionalConstraints:nil];
- RTCPeerConnectionFactory *factory = [[RTCPeerConnectionFactory alloc] init];
+ RTCPeerConnectionFactory *factory;
+ RTCPeerConnection *peerConnection;
- RTCPeerConnection *peerConnection =
- [factory peerConnectionWithConfiguration:config constraints:contraints delegate:nil];
-
- [peerConnection close];
-
- factory = nil;
+ @autoreleasepool {
+ factory = [[RTCPeerConnectionFactory alloc] init];
+ peerConnection =
+ [factory peerConnectionWithConfiguration:config constraints:contraints delegate:nil];
+ [peerConnection close];
+ factory = nil;
+ }
peerConnection = nil;
}
XCTAssertTrue(true, @"Expect test does not crash");
}
+- (void)testMediaStreamLifetime {
+ @autoreleasepool {
+ RTCPeerConnectionFactory *factory;
+ RTCMediaStream *mediaStream;
+
+ @autoreleasepool {
+ factory = [[RTCPeerConnectionFactory alloc] init];
+ mediaStream = [factory mediaStreamWithStreamId:@"mediaStream"];
+ factory = nil;
+ }
+ mediaStream = nil;
+ }
+
+ XCTAssertTrue(true, "Expect test does not crash");
+}
+
@end