Throw IllegalStateException if native objects are used after dispose.
This makes it easier to debug issues related to double dispose /
use after dispose.
Bug: webrtc:7566, webrtc:8297
Change-Id: I07429b2b794deabb62b5f3ea1cf92eea6f66a149
Reviewed-on: https://webrtc-review.googlesource.com/102540
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Paulina Hensman <phensman@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24894}
diff --git a/sdk/android/api/org/webrtc/AudioSource.java b/sdk/android/api/org/webrtc/AudioSource.java
index 99fcad1..f8104e5 100644
--- a/sdk/android/api/org/webrtc/AudioSource.java
+++ b/sdk/android/api/org/webrtc/AudioSource.java
@@ -18,4 +18,9 @@
public AudioSource(long nativeSource) {
super(nativeSource);
}
+
+ /** Returns a pointer to webrtc::AudioSourceInterface. */
+ long getNativeAudioSource() {
+ return getNativeMediaSource();
+ }
}
diff --git a/sdk/android/api/org/webrtc/AudioTrack.java b/sdk/android/api/org/webrtc/AudioTrack.java
index 828e89c..ca745db 100644
--- a/sdk/android/api/org/webrtc/AudioTrack.java
+++ b/sdk/android/api/org/webrtc/AudioTrack.java
@@ -20,7 +20,12 @@
* 0 to 10.
*/
public void setVolume(double volume) {
- nativeSetVolume(super.nativeTrack, volume);
+ nativeSetVolume(getNativeAudioTrack(), volume);
+ }
+
+ /** Returns a pointer to webrtc::AudioTrackInterface. */
+ long getNativeAudioTrack() {
+ return getNativeMediaStreamTrack();
}
private static native void nativeSetVolume(long track, double volume);
diff --git a/sdk/android/api/org/webrtc/DataChannel.java b/sdk/android/api/org/webrtc/DataChannel.java
index 53ea0d8..f51dab9 100644
--- a/sdk/android/api/org/webrtc/DataChannel.java
+++ b/sdk/android/api/org/webrtc/DataChannel.java
@@ -102,7 +102,7 @@
}
}
- private final long nativeDataChannel;
+ private long nativeDataChannel;
private long nativeObserver;
@CalledByNative
@@ -112,6 +112,7 @@
/** Register |observer|, replacing any previously-registered observer. */
public void registerObserver(Observer observer) {
+ checkDataChannelExists();
if (nativeObserver != 0) {
nativeUnregisterObserver(nativeObserver);
}
@@ -120,18 +121,22 @@
/** Unregister the (only) observer. */
public void unregisterObserver() {
+ checkDataChannelExists();
nativeUnregisterObserver(nativeObserver);
}
public String label() {
+ checkDataChannelExists();
return nativeLabel();
}
public int id() {
+ checkDataChannelExists();
return nativeId();
}
public State state() {
+ checkDataChannelExists();
return nativeState();
}
@@ -141,16 +146,19 @@
* to the network.
*/
public long bufferedAmount() {
+ checkDataChannelExists();
return nativeBufferedAmount();
}
/** Close the channel. */
public void close() {
+ checkDataChannelExists();
nativeClose();
}
/** Send |data| to the remote peer; return success. */
public boolean send(Buffer buffer) {
+ checkDataChannelExists();
// TODO(fischman): this could be cleverer about avoiding copies if the
// ByteBuffer is direct and/or is backed by an array.
byte[] data = new byte[buffer.data.remaining()];
@@ -160,7 +168,9 @@
/** Dispose of native resources attached to this channel. */
public void dispose() {
+ checkDataChannelExists();
JniCommon.nativeReleaseRef(nativeDataChannel);
+ nativeDataChannel = 0;
}
@CalledByNative
@@ -168,6 +178,12 @@
return nativeDataChannel;
}
+ private void checkDataChannelExists() {
+ if (nativeDataChannel == 0) {
+ throw new IllegalStateException("DataChannel has been disposed.");
+ }
+ }
+
private native long nativeRegisterObserver(Observer observer);
private native void nativeUnregisterObserver(long observer);
private native String nativeLabel();
diff --git a/sdk/android/api/org/webrtc/DtmfSender.java b/sdk/android/api/org/webrtc/DtmfSender.java
index 9f203f3..6549823 100644
--- a/sdk/android/api/org/webrtc/DtmfSender.java
+++ b/sdk/android/api/org/webrtc/DtmfSender.java
@@ -12,7 +12,7 @@
/** Java wrapper for a C++ DtmfSenderInterface. */
public class DtmfSender {
- final long nativeDtmfSender;
+ private long nativeDtmfSender;
public DtmfSender(long nativeDtmfSender) {
this.nativeDtmfSender = nativeDtmfSender;
@@ -22,6 +22,7 @@
* @return true if this DtmfSender is capable of sending DTMF. Otherwise false.
*/
public boolean canInsertDtmf() {
+ checkDtmfSenderExists();
return nativeCanInsertDtmf(nativeDtmfSender);
}
@@ -43,6 +44,7 @@
* @return true on success and false on failure.
*/
public boolean insertDtmf(String tones, int duration, int interToneGap) {
+ checkDtmfSenderExists();
return nativeInsertDtmf(nativeDtmfSender, tones, duration, interToneGap);
}
@@ -50,6 +52,7 @@
* @return The tones remaining to be played out
*/
public String tones() {
+ checkDtmfSenderExists();
return nativeTones(nativeDtmfSender);
}
@@ -58,6 +61,7 @@
* insertDtmf() method, or the default value of 100 ms if insertDtmf() was never called.
*/
public int duration() {
+ checkDtmfSenderExists();
return nativeDuration(nativeDtmfSender);
}
@@ -67,11 +71,20 @@
* called.
*/
public int interToneGap() {
+ checkDtmfSenderExists();
return nativeInterToneGap(nativeDtmfSender);
}
public void dispose() {
+ checkDtmfSenderExists();
JniCommon.nativeReleaseRef(nativeDtmfSender);
+ nativeDtmfSender = 0;
+ }
+
+ private void checkDtmfSenderExists() {
+ if (nativeDtmfSender == 0) {
+ throw new IllegalStateException("DtmfSender has been disposed.");
+ }
}
private static native boolean nativeCanInsertDtmf(long dtmfSender);
diff --git a/sdk/android/api/org/webrtc/MediaSource.java b/sdk/android/api/org/webrtc/MediaSource.java
index 3f20dd7..0b19e1a 100644
--- a/sdk/android/api/org/webrtc/MediaSource.java
+++ b/sdk/android/api/org/webrtc/MediaSource.java
@@ -25,18 +25,33 @@
}
}
- final long nativeSource; // Package-protected for PeerConnectionFactory.
+ private long nativeSource;
public MediaSource(long nativeSource) {
this.nativeSource = nativeSource;
}
public State state() {
+ checkMediaSourceExists();
return nativeGetState(nativeSource);
}
public void dispose() {
+ checkMediaSourceExists();
JniCommon.nativeReleaseRef(nativeSource);
+ nativeSource = 0;
+ }
+
+ /** Returns a pointer to webrtc::MediaSourceInterface. */
+ protected long getNativeMediaSource() {
+ checkMediaSourceExists();
+ return nativeSource;
+ }
+
+ private void checkMediaSourceExists() {
+ if (nativeSource == 0) {
+ throw new IllegalStateException("MediaSource has been disposed.");
+ }
}
private static native State nativeGetState(long pointer);
diff --git a/sdk/android/api/org/webrtc/MediaStream.java b/sdk/android/api/org/webrtc/MediaStream.java
index 7f4a434..e530fe5 100644
--- a/sdk/android/api/org/webrtc/MediaStream.java
+++ b/sdk/android/api/org/webrtc/MediaStream.java
@@ -11,8 +11,8 @@
package org.webrtc;
import java.util.ArrayList;
-import java.util.List;
import java.util.Iterator;
+import java.util.List;
/** Java wrapper for a C++ MediaStreamInterface. */
public class MediaStream {
@@ -21,8 +21,7 @@
public final List<AudioTrack> audioTracks = new ArrayList<>();
public final List<VideoTrack> videoTracks = new ArrayList<>();
public final List<VideoTrack> preservedVideoTracks = new ArrayList<>();
- // Package-protected for PeerConnection.
- final long nativeStream;
+ private long nativeStream;
@CalledByNative
public MediaStream(long nativeStream) {
@@ -30,7 +29,8 @@
}
public boolean addTrack(AudioTrack track) {
- if (nativeAddAudioTrackToNativeStream(nativeStream, track.nativeTrack)) {
+ checkMediaStreamExists();
+ if (nativeAddAudioTrackToNativeStream(nativeStream, track.getNativeAudioTrack())) {
audioTracks.add(track);
return true;
}
@@ -38,7 +38,8 @@
}
public boolean addTrack(VideoTrack track) {
- if (nativeAddVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
+ checkMediaStreamExists();
+ if (nativeAddVideoTrackToNativeStream(nativeStream, track.getNativeVideoTrack())) {
videoTracks.add(track);
return true;
}
@@ -49,7 +50,8 @@
// is called. If video track need to be preserved after MediaStream is destroyed it
// should be added to MediaStream using addPreservedTrack() call.
public boolean addPreservedTrack(VideoTrack track) {
- if (nativeAddVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
+ checkMediaStreamExists();
+ if (nativeAddVideoTrackToNativeStream(nativeStream, track.getNativeVideoTrack())) {
preservedVideoTracks.add(track);
return true;
}
@@ -57,18 +59,21 @@
}
public boolean removeTrack(AudioTrack track) {
+ checkMediaStreamExists();
audioTracks.remove(track);
- return nativeRemoveAudioTrack(nativeStream, track.nativeTrack);
+ return nativeRemoveAudioTrack(nativeStream, track.getNativeAudioTrack());
}
public boolean removeTrack(VideoTrack track) {
+ checkMediaStreamExists();
videoTracks.remove(track);
preservedVideoTracks.remove(track);
- return nativeRemoveVideoTrack(nativeStream, track.nativeTrack);
+ return nativeRemoveVideoTrack(nativeStream, track.getNativeVideoTrack());
}
@CalledByNative
public void dispose() {
+ checkMediaStreamExists();
// Remove and release previously added audio and video tracks.
while (!audioTracks.isEmpty()) {
AudioTrack track = audioTracks.get(0 /* index */);
@@ -85,9 +90,11 @@
removeTrack(preservedVideoTracks.get(0 /* index */));
}
JniCommon.nativeReleaseRef(nativeStream);
+ nativeStream = 0;
}
public String getId() {
+ checkMediaStreamExists();
return nativeGetId(nativeStream);
}
@@ -116,12 +123,24 @@
removeMediaStreamTrack(videoTracks, nativeTrack);
}
+ /** Returns a pointer to webrtc::MediaStreamInterface. */
+ long getNativeMediaStream() {
+ checkMediaStreamExists();
+ return nativeStream;
+ }
+
+ private void checkMediaStreamExists() {
+ if (nativeStream == 0) {
+ throw new IllegalStateException("MediaStream has been disposed.");
+ }
+ }
+
private static void removeMediaStreamTrack(
List<? extends MediaStreamTrack> tracks, long nativeTrack) {
final Iterator<? extends MediaStreamTrack> it = tracks.iterator();
while (it.hasNext()) {
MediaStreamTrack track = it.next();
- if (track.nativeTrack == nativeTrack) {
+ if (track.getNativeMediaStreamTrack() == nativeTrack) {
track.dispose();
it.remove();
return;
diff --git a/sdk/android/api/org/webrtc/MediaStreamTrack.java b/sdk/android/api/org/webrtc/MediaStreamTrack.java
index 198da1e..944c7ef 100644
--- a/sdk/android/api/org/webrtc/MediaStreamTrack.java
+++ b/sdk/android/api/org/webrtc/MediaStreamTrack.java
@@ -70,34 +70,52 @@
}
}
- final long nativeTrack;
+ private long nativeTrack;
public MediaStreamTrack(long nativeTrack) {
this.nativeTrack = nativeTrack;
}
public String id() {
+ checkMediaStreamTrackExists();
return nativeGetId(nativeTrack);
}
public String kind() {
+ checkMediaStreamTrackExists();
return nativeGetKind(nativeTrack);
}
public boolean enabled() {
+ checkMediaStreamTrackExists();
return nativeGetEnabled(nativeTrack);
}
public boolean setEnabled(boolean enable) {
+ checkMediaStreamTrackExists();
return nativeSetEnabled(nativeTrack, enable);
}
public State state() {
+ checkMediaStreamTrackExists();
return nativeGetState(nativeTrack);
}
public void dispose() {
+ checkMediaStreamTrackExists();
JniCommon.nativeReleaseRef(nativeTrack);
+ nativeTrack = 0;
+ }
+
+ long getNativeMediaStreamTrack() {
+ checkMediaStreamTrackExists();
+ return nativeTrack;
+ }
+
+ private void checkMediaStreamTrackExists() {
+ if (nativeTrack == 0) {
+ throw new IllegalStateException("MediaStreamTrack has been disposed.");
+ }
}
private static native String nativeGetId(long track);
diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java
index 2f9adcf..84d49eb 100644
--- a/sdk/android/api/org/webrtc/PeerConnection.java
+++ b/sdk/android/api/org/webrtc/PeerConnection.java
@@ -781,7 +781,7 @@
* use addTrack instead.
*/
public boolean addStream(MediaStream stream) {
- boolean ret = nativeAddLocalStream(stream.nativeStream);
+ boolean ret = nativeAddLocalStream(stream.getNativeMediaStream());
if (!ret) {
return false;
}
@@ -795,7 +795,7 @@
* removeTrack instead.
*/
public void removeStream(MediaStream stream) {
- nativeRemoveLocalStream(stream.nativeStream);
+ nativeRemoveLocalStream(stream.getNativeMediaStream());
localStreams.remove(stream);
}
@@ -905,7 +905,7 @@
if (track == null || streamIds == null) {
throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
}
- RtpSender newSender = nativeAddTrack(track.nativeTrack, streamIds);
+ RtpSender newSender = nativeAddTrack(track.getNativeMediaStreamTrack(), streamIds);
if (newSender == null) {
throw new IllegalStateException("C++ addTrack failed.");
}
@@ -922,7 +922,7 @@
if (sender == null) {
throw new NullPointerException("No RtpSender specified for removeTrack.");
}
- return nativeRemoveTrack(sender.nativeRtpSender);
+ return nativeRemoveTrack(sender.getNativeRtpSender());
}
/**
@@ -962,7 +962,8 @@
if (init == null) {
init = new RtpTransceiver.RtpTransceiverInit();
}
- RtpTransceiver newTransceiver = nativeAddTransceiverWithTrack(track.nativeTrack, init);
+ RtpTransceiver newTransceiver =
+ nativeAddTransceiverWithTrack(track.getNativeMediaStreamTrack(), init);
if (newTransceiver == null) {
throw new IllegalStateException("C++ addTransceiver failed.");
}
@@ -993,7 +994,7 @@
// Older, non-standard implementation of getStats.
@Deprecated
public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) {
- return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
+ return nativeOldGetStats(observer, (track == null) ? 0 : track.getNativeMediaStreamTrack());
}
/**
@@ -1070,7 +1071,7 @@
public void dispose() {
close();
for (MediaStream stream : localStreams) {
- nativeRemoveLocalStream(stream.nativeStream);
+ nativeRemoveLocalStream(stream.getNativeMediaStream());
stream.dispose();
}
localStreams.clear();
diff --git a/sdk/android/api/org/webrtc/PeerConnectionFactory.java b/sdk/android/api/org/webrtc/PeerConnectionFactory.java
index 672bd0e..eb98e92 100644
--- a/sdk/android/api/org/webrtc/PeerConnectionFactory.java
+++ b/sdk/android/api/org/webrtc/PeerConnectionFactory.java
@@ -28,7 +28,7 @@
private static final String TAG = "PeerConnectionFactory";
private static final String VIDEO_CAPTURER_THREAD_NAME = "VideoCapturerThread";
- private final long nativeFactory;
+ private long nativeFactory;
private static volatile boolean internalTracerInitialized;
@Nullable private static Thread networkThread;
@Nullable private static Thread workerThread;
@@ -307,6 +307,7 @@
PeerConnection createPeerConnectionInternal(PeerConnection.RTCConfiguration rtcConfig,
MediaConstraints constraints, PeerConnection.Observer observer,
SSLCertificateVerifier sslCertificateVerifier) {
+ checkPeerConnectionFactoryExists();
long nativeObserver = PeerConnection.createNativePeerConnectionObserver(observer);
if (nativeObserver == 0) {
return null;
@@ -364,61 +365,80 @@
}
public MediaStream createLocalMediaStream(String label) {
+ checkPeerConnectionFactoryExists();
return new MediaStream(nativeCreateLocalMediaStream(nativeFactory, label));
}
public VideoSource createVideoSource(boolean isScreencast) {
+ checkPeerConnectionFactoryExists();
return new VideoSource(nativeCreateVideoSource(nativeFactory, isScreencast));
}
public VideoTrack createVideoTrack(String id, VideoSource source) {
- return new VideoTrack(nativeCreateVideoTrack(nativeFactory, id, source.nativeSource));
+ checkPeerConnectionFactoryExists();
+ return new VideoTrack(
+ nativeCreateVideoTrack(nativeFactory, id, source.getNativeVideoTrackSource()));
}
public AudioSource createAudioSource(MediaConstraints constraints) {
+ checkPeerConnectionFactoryExists();
return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints));
}
public AudioTrack createAudioTrack(String id, AudioSource source) {
- return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.nativeSource));
+ checkPeerConnectionFactoryExists();
+ return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.getNativeAudioSource()));
}
// Starts recording an AEC dump. Ownership of the file is transfered to the
// native code. If an AEC dump is already in progress, it will be stopped and
// a new one will start using the provided file.
public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
+ checkPeerConnectionFactoryExists();
return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
}
// Stops recording an AEC dump. If no AEC dump is currently being recorded,
// this call will have no effect.
public void stopAecDump() {
+ checkPeerConnectionFactoryExists();
nativeStopAecDump(nativeFactory);
}
public void dispose() {
+ checkPeerConnectionFactoryExists();
nativeFreeFactory(nativeFactory);
networkThread = null;
workerThread = null;
signalingThread = null;
MediaCodecVideoEncoder.disposeEglContext();
MediaCodecVideoDecoder.disposeEglContext();
+ nativeFactory = 0;
}
public void threadsCallbacks() {
+ checkPeerConnectionFactoryExists();
nativeInvokeThreadsCallbacks(nativeFactory);
}
/** Returns a pointer to the native webrtc::PeerConnectionFactoryInterface. */
public long getNativePeerConnectionFactory() {
+ checkPeerConnectionFactoryExists();
return nativeGetNativePeerConnectionFactory(nativeFactory);
}
/** Returns a pointer to the native OwnedFactoryAndThreads object */
public long getNativeOwnedFactoryAndThreads() {
+ checkPeerConnectionFactoryExists();
return nativeFactory;
}
+ private void checkPeerConnectionFactoryExists() {
+ if (nativeFactory == 0) {
+ throw new IllegalStateException("PeerConnectionFactory has been disposed.");
+ }
+ }
+
private static void printStackTrace(@Nullable Thread thread, String threadName) {
if (thread != null) {
StackTraceElement[] stackTraces = thread.getStackTrace();
diff --git a/sdk/android/api/org/webrtc/RtpReceiver.java b/sdk/android/api/org/webrtc/RtpReceiver.java
index 4da7537..8be494f 100644
--- a/sdk/android/api/org/webrtc/RtpReceiver.java
+++ b/sdk/android/api/org/webrtc/RtpReceiver.java
@@ -22,7 +22,7 @@
public void onFirstPacketReceived(MediaStreamTrack.MediaType media_type);
}
- final long nativeRtpReceiver;
+ private long nativeRtpReceiver;
private long nativeObserver;
@Nullable private MediaStreamTrack cachedTrack;
@@ -40,28 +40,34 @@
}
public boolean setParameters(@Nullable RtpParameters parameters) {
+ checkRtpReceiverExists();
return parameters == null ? false : nativeSetParameters(nativeRtpReceiver, parameters);
}
public RtpParameters getParameters() {
+ checkRtpReceiverExists();
return nativeGetParameters(nativeRtpReceiver);
}
public String id() {
+ checkRtpReceiverExists();
return nativeGetId(nativeRtpReceiver);
}
@CalledByNative
public void dispose() {
+ checkRtpReceiverExists();
cachedTrack.dispose();
if (nativeObserver != 0) {
nativeUnsetObserver(nativeRtpReceiver, nativeObserver);
nativeObserver = 0;
}
JniCommon.nativeReleaseRef(nativeRtpReceiver);
+ nativeRtpReceiver = 0;
}
public void SetObserver(Observer observer) {
+ checkRtpReceiverExists();
// Unset the existing one before setting a new one.
if (nativeObserver != 0) {
nativeUnsetObserver(nativeRtpReceiver, nativeObserver);
@@ -70,9 +76,16 @@
}
public void setFrameDecryptor(FrameDecryptor frameDecryptor) {
+ checkRtpReceiverExists();
nativeSetFrameDecryptor(nativeRtpReceiver, frameDecryptor.getNativeFrameDecryptor());
}
+ private void checkRtpReceiverExists() {
+ if (nativeRtpReceiver == 0) {
+ throw new IllegalStateException("RtpReceiver has been disposed.");
+ }
+ }
+
// This should increment the reference count of the track.
// Will be released in dispose().
private static native long nativeGetTrack(long rtpReceiver);
diff --git a/sdk/android/api/org/webrtc/RtpSender.java b/sdk/android/api/org/webrtc/RtpSender.java
index e2a9932..9d7451d 100644
--- a/sdk/android/api/org/webrtc/RtpSender.java
+++ b/sdk/android/api/org/webrtc/RtpSender.java
@@ -14,7 +14,7 @@
/** Java wrapper for a C++ RtpSenderInterface. */
public class RtpSender {
- final long nativeRtpSender;
+ private long nativeRtpSender;
@Nullable private MediaStreamTrack cachedTrack;
private boolean ownsTrack = true;
@@ -45,7 +45,8 @@
* @return true on success and false on failure.
*/
public boolean setTrack(@Nullable MediaStreamTrack track, boolean takeOwnership) {
- if (!nativeSetTrack(nativeRtpSender, (track == null) ? 0 : track.nativeTrack)) {
+ checkRtpSenderExists();
+ if (!nativeSetTrack(nativeRtpSender, (track == null) ? 0 : track.getNativeMediaStreamTrack())) {
return false;
}
if (cachedTrack != null && ownsTrack) {
@@ -62,14 +63,17 @@
}
public boolean setParameters(RtpParameters parameters) {
+ checkRtpSenderExists();
return nativeSetParameters(nativeRtpSender, parameters);
}
public RtpParameters getParameters() {
+ checkRtpSenderExists();
return nativeGetParameters(nativeRtpSender);
}
public String id() {
+ checkRtpSenderExists();
return nativeGetId(nativeRtpSender);
}
@@ -79,10 +83,12 @@
}
public void setFrameEncryptor(FrameEncryptor frameEncryptor) {
+ checkRtpSenderExists();
nativeSetFrameEncryptor(nativeRtpSender, frameEncryptor.getNativeFrameEncryptor());
}
public void dispose() {
+ checkRtpSenderExists();
if (dtmfSender != null) {
dtmfSender.dispose();
}
@@ -90,6 +96,19 @@
cachedTrack.dispose();
}
JniCommon.nativeReleaseRef(nativeRtpSender);
+ nativeRtpSender = 0;
+ }
+
+ /** Returns a pointer to webrtc::RtpSenderInterface. */
+ long getNativeRtpSender() {
+ checkRtpSenderExists();
+ return nativeRtpSender;
+ }
+
+ private void checkRtpSenderExists() {
+ if (nativeRtpSender == 0) {
+ throw new IllegalStateException("RtpSender has been disposed.");
+ }
}
private static native boolean nativeSetTrack(long rtpSender, long nativeTrack);
diff --git a/sdk/android/api/org/webrtc/RtpTransceiver.java b/sdk/android/api/org/webrtc/RtpTransceiver.java
index 93326a4..a4a5aa0 100644
--- a/sdk/android/api/org/webrtc/RtpTransceiver.java
+++ b/sdk/android/api/org/webrtc/RtpTransceiver.java
@@ -13,7 +13,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import org.webrtc.RtpParameters.Encoding;
/**
* Java wrapper for a C++ RtpTransceiverInterface.
@@ -96,7 +95,7 @@
}
}
- private final long nativeRtpTransceiver;
+ private long nativeRtpTransceiver;
private RtpSender cachedSender;
private RtpReceiver cachedReceiver;
@@ -112,6 +111,7 @@
* type as well.
*/
public MediaStreamTrack.MediaType getMediaType() {
+ checkRtpTransceiverExists();
return nativeGetMediaType(nativeRtpTransceiver);
}
@@ -122,6 +122,7 @@
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid
*/
public String getMid() {
+ checkRtpTransceiverExists();
return nativeGetMid(nativeRtpTransceiver);
}
@@ -153,6 +154,7 @@
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped
*/
public boolean isStopped() {
+ checkRtpTransceiverExists();
return nativeStopped(nativeRtpTransceiver);
}
@@ -162,6 +164,7 @@
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
*/
public RtpTransceiverDirection getDirection() {
+ checkRtpTransceiverExists();
return nativeDirection(nativeRtpTransceiver);
}
@@ -172,6 +175,7 @@
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection
*/
public RtpTransceiverDirection getCurrentDirection() {
+ checkRtpTransceiverExists();
return nativeCurrentDirection(nativeRtpTransceiver);
}
@@ -183,6 +187,7 @@
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
*/
public void setDirection(RtpTransceiverDirection rtpTransceiverDirection) {
+ checkRtpTransceiverExists();
nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection);
}
@@ -192,14 +197,23 @@
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop
*/
public void stop() {
+ checkRtpTransceiverExists();
nativeStop(nativeRtpTransceiver);
}
@CalledByNative
public void dispose() {
+ checkRtpTransceiverExists();
cachedSender.dispose();
cachedReceiver.dispose();
JniCommon.nativeReleaseRef(nativeRtpTransceiver);
+ nativeRtpTransceiver = 0;
+ }
+
+ private void checkRtpTransceiverExists() {
+ if (nativeRtpTransceiver == 0) {
+ throw new IllegalStateException("RtpTransceiver has been disposed.");
+ }
}
private static native MediaStreamTrack.MediaType nativeGetMediaType(long rtpTransceiver);
diff --git a/sdk/android/api/org/webrtc/TurnCustomizer.java b/sdk/android/api/org/webrtc/TurnCustomizer.java
index bfc72ea..41bedb7 100644
--- a/sdk/android/api/org/webrtc/TurnCustomizer.java
+++ b/sdk/android/api/org/webrtc/TurnCustomizer.java
@@ -12,20 +12,30 @@
/** Java wrapper for a C++ TurnCustomizer. */
public class TurnCustomizer {
- final long nativeTurnCustomizer;
+ private long nativeTurnCustomizer;
public TurnCustomizer(long nativeTurnCustomizer) {
this.nativeTurnCustomizer = nativeTurnCustomizer;
}
public void dispose() {
+ checkTurnCustomizerExists();
nativeFreeTurnCustomizer(nativeTurnCustomizer);
+ nativeTurnCustomizer = 0;
}
private static native void nativeFreeTurnCustomizer(long turnCustomizer);
+ /** Return a pointer to webrtc::TurnCustomizer. */
@CalledByNative
long getNativeTurnCustomizer() {
+ checkTurnCustomizerExists();
return nativeTurnCustomizer;
}
+
+ private void checkTurnCustomizerExists() {
+ if (nativeTurnCustomizer == 0) {
+ throw new IllegalStateException("TurnCustomizer has been disposed.");
+ }
+ }
}
diff --git a/sdk/android/api/org/webrtc/VideoSource.java b/sdk/android/api/org/webrtc/VideoSource.java
index e0c6167..7f9f3e5 100644
--- a/sdk/android/api/org/webrtc/VideoSource.java
+++ b/sdk/android/api/org/webrtc/VideoSource.java
@@ -30,13 +30,18 @@
* maintain the input orientation, so it doesn't matter if e.g. 1280x720 or 720x1280 is requested.
*/
public void adaptOutputFormat(int width, int height, int fps) {
- nativeAdaptOutputFormat(nativeSource, width, height, fps);
+ nativeAdaptOutputFormat(getNativeVideoTrackSource(), width, height, fps);
}
public CapturerObserver getCapturerObserver() {
return capturerObserver;
}
+ /** Returns a pointer to webrtc::VideoTrackSourceInterface. */
+ long getNativeVideoTrackSource() {
+ return getNativeMediaSource();
+ }
+
// Returns source->internal() from webrtc::VideoTrackSourceProxy.
private static native long nativeGetInternalSource(long source);
private static native void nativeAdaptOutputFormat(long source, int width, int height, int fps);
diff --git a/sdk/android/api/org/webrtc/VideoTrack.java b/sdk/android/api/org/webrtc/VideoTrack.java
index 5495ee8..5e33e1e 100644
--- a/sdk/android/api/org/webrtc/VideoTrack.java
+++ b/sdk/android/api/org/webrtc/VideoTrack.java
@@ -10,8 +10,8 @@
package org.webrtc;
-import java.util.IdentityHashMap;
import java.util.ArrayList;
+import java.util.IdentityHashMap;
import java.util.List;
/** Java version of VideoTrackInterface. */
@@ -39,7 +39,7 @@
if (!sinks.containsKey(sink)) {
final long nativeSink = nativeWrapSink(sink);
sinks.put(sink, nativeSink);
- nativeAddSink(nativeTrack, nativeSink);
+ nativeAddSink(getNativeMediaStreamTrack(), nativeSink);
}
}
@@ -51,7 +51,7 @@
public void removeSink(VideoSink sink) {
final Long nativeSink = sinks.remove(sink);
if (nativeSink != null) {
- nativeRemoveSink(nativeTrack, nativeSink);
+ nativeRemoveSink(getNativeMediaStreamTrack(), nativeSink);
nativeFreeSink(nativeSink);
}
}
@@ -59,13 +59,18 @@
@Override
public void dispose() {
for (long nativeSink : sinks.values()) {
- nativeRemoveSink(nativeTrack, nativeSink);
+ nativeRemoveSink(getNativeMediaStreamTrack(), nativeSink);
nativeFreeSink(nativeSink);
}
sinks.clear();
super.dispose();
}
+ /** Returns a pointer to webrtc::VideoTrackInterface. */
+ long getNativeVideoTrack() {
+ return getNativeMediaStreamTrack();
+ }
+
private static native void nativeAddSink(long track, long nativeSink);
private static native void nativeRemoveSink(long track, long nativeSink);
private static native long nativeWrapSink(VideoSink sink);