From ba700f642bec7537941f3aa40907fcc1273853bb Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Mon, 4 Dec 2017 13:43:27 +0100 Subject: [PATCH] Android: Generate JNI code for RtpReceiver and PeerConnection.Observer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:8278 Change-Id: Ief62c37dd6820c2eb1ce94e37e0a61dd8726caae Reviewed-on: https://webrtc-review.googlesource.com/28621 Commit-Queue: Magnus Jedvert Reviewed-by: Sami Kalliomäki Cr-Commit-Position: refs/heads/master@{#21035} --- sdk/android/BUILD.gn | 7 +- .../api/org/webrtc/PeerConnection.java | 97 ++++++++----- sdk/android/api/org/webrtc/RtpReceiver.java | 31 ++-- sdk/android/src/jni/jni_helpers.h | 10 +- .../src/jni/pc/java_native_conversion.cc | 11 +- .../src/jni/pc/java_native_conversion.h | 4 +- sdk/android/src/jni/pc/peerconnection_jni.cc | 35 ++--- .../src/jni/pc/peerconnectionobserver_jni.cc | 135 ++++++------------ .../src/jni/pc/peerconnectionobserver_jni.h | 8 +- .../pc/{rtpreceiver_jni.cc => rtpreceiver.cc} | 67 +++++++-- sdk/android/src/jni/pc/rtpreceiver.h | 41 ++++++ .../src/jni/pc/rtpreceiverobserver_jni.cc | 34 ----- .../src/jni/pc/rtpreceiverobserver_jni.h | 39 ----- sdk/android/src/jni/pc/rtpsender_jni.cc | 3 +- 14 files changed, 250 insertions(+), 272 deletions(-) rename sdk/android/src/jni/pc/{rtpreceiver_jni.cc => rtpreceiver.cc} (57%) create mode 100644 sdk/android/src/jni/pc/rtpreceiver.h delete mode 100644 sdk/android/src/jni/pc/rtpreceiverobserver_jni.cc delete mode 100644 sdk/android/src/jni/pc/rtpreceiverobserver_jni.h diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index c7427da178..cfaf0a4287 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -298,9 +298,11 @@ generate_jni("generated_peerconnection_jni") { "api/org/webrtc/MediaStreamTrack.java", "api/org/webrtc/NetworkMonitor.java", "api/org/webrtc/NetworkMonitorAutoDetect.java", + "api/org/webrtc/PeerConnection.java", "api/org/webrtc/RTCStats.java", "api/org/webrtc/RTCStatsCollectorCallback.java", "api/org/webrtc/RTCStatsReport.java", + "api/org/webrtc/RtpReceiver.java", "api/org/webrtc/StatsObserver.java", "api/org/webrtc/StatsReport.java", ] @@ -334,9 +336,8 @@ rtc_static_library("peerconnection_jni") { "src/jni/pc/peerconnectionobserver_jni.h", "src/jni/pc/rtcstatscollectorcallbackwrapper.cc", "src/jni/pc/rtcstatscollectorcallbackwrapper.h", - "src/jni/pc/rtpreceiver_jni.cc", - "src/jni/pc/rtpreceiverobserver_jni.cc", - "src/jni/pc/rtpreceiverobserver_jni.h", + "src/jni/pc/rtpreceiver.cc", + "src/jni/pc/rtpreceiver.h", "src/jni/pc/rtpsender_jni.cc", "src/jni/pc/sdpobserver_jni.h", "src/jni/pc/statsobserver_jni.cc", diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java index 9bc4ebf309..24425f09fb 100644 --- a/sdk/android/api/org/webrtc/PeerConnection.java +++ b/sdk/android/api/org/webrtc/PeerConnection.java @@ -22,7 +22,16 @@ import java.util.List; */ public class PeerConnection { /** Tracks PeerConnectionInterface::IceGatheringState */ - public enum IceGatheringState { NEW, GATHERING, COMPLETE } + public enum IceGatheringState { + NEW, + GATHERING, + COMPLETE; + + @CalledByNative("IceGatheringState") + static IceGatheringState fromNativeIndex(int nativeIndex) { + return values()[nativeIndex]; + } + } /** Tracks PeerConnectionInterface::IceConnectionState */ public enum IceConnectionState { @@ -32,7 +41,12 @@ public class PeerConnection { COMPLETED, FAILED, DISCONNECTED, - CLOSED + CLOSED; + + @CalledByNative("IceConnectionState") + static IceConnectionState fromNativeIndex(int nativeIndex) { + return values()[nativeIndex]; + } } /** Tracks PeerConnectionInterface::TlsCertPolicy */ @@ -48,46 +62,51 @@ public class PeerConnection { HAVE_LOCAL_PRANSWER, HAVE_REMOTE_OFFER, HAVE_REMOTE_PRANSWER, - CLOSED + CLOSED; + + @CalledByNative("SignalingState") + static SignalingState fromNativeIndex(int nativeIndex) { + return values()[nativeIndex]; + } } /** Java version of PeerConnectionObserver. */ public static interface Observer { /** Triggered when the SignalingState changes. */ - public void onSignalingChange(SignalingState newState); + @CalledByNative("Observer") void onSignalingChange(SignalingState newState); /** Triggered when the IceConnectionState changes. */ - public void onIceConnectionChange(IceConnectionState newState); + @CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState); /** Triggered when the ICE connection receiving status changes. */ - public void onIceConnectionReceivingChange(boolean receiving); + @CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving); /** Triggered when the IceGatheringState changes. */ - public void onIceGatheringChange(IceGatheringState newState); + @CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState); /** Triggered when a new ICE candidate has been found. */ - public void onIceCandidate(IceCandidate candidate); + @CalledByNative("Observer") void onIceCandidate(IceCandidate candidate); /** Triggered when some ICE candidates have been removed. */ - public void onIceCandidatesRemoved(IceCandidate[] candidates); + @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates); /** Triggered when media is received on a new stream from remote peer. */ - public void onAddStream(MediaStream stream); + @CalledByNative("Observer") void onAddStream(MediaStream stream); /** Triggered when a remote peer close a stream. */ - public void onRemoveStream(MediaStream stream); + @CalledByNative("Observer") void onRemoveStream(MediaStream stream); /** Triggered when a remote peer opens a DataChannel. */ - public void onDataChannel(DataChannel dataChannel); + @CalledByNative("Observer") void onDataChannel(DataChannel dataChannel); /** Triggered when renegotiation is necessary. */ - public void onRenegotiationNeeded(); + @CalledByNative("Observer") void onRenegotiationNeeded(); /** * Triggered when a new track is signaled by the remote peer, as a result of * setRemoteDescription. */ - public void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams); + @CalledByNative("Observer") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams); } /** Java version of PeerConnectionInterface.IceServer. */ @@ -369,19 +388,19 @@ public class PeerConnection { public native void setAudioRecording(boolean recording); public boolean setConfiguration(RTCConfiguration config) { - return nativeSetConfiguration(config, nativeObserver); + return setNativeConfiguration(config, nativeObserver); } public boolean addIceCandidate(IceCandidate candidate) { - return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); + return addNativeIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); } public boolean removeIceCandidates(final IceCandidate[] candidates) { - return nativeRemoveIceCandidates(candidates); + return removeNativeIceCandidates(candidates); } public boolean addStream(MediaStream stream) { - boolean ret = nativeAddLocalStream(stream.nativeStream); + boolean ret = addNativeLocalStream(stream.nativeStream); if (!ret) { return false; } @@ -390,7 +409,7 @@ public class PeerConnection { } public void removeStream(MediaStream stream) { - nativeRemoveLocalStream(stream.nativeStream); + removeNativeLocalStream(stream.nativeStream); localStreams.remove(stream); } @@ -432,7 +451,7 @@ public class PeerConnection { * @return A new RtpSender object if successful, or null otherwise. */ public RtpSender createSender(String kind, String stream_id) { - RtpSender new_sender = nativeCreateSender(kind, stream_id); + RtpSender new_sender = createNativeSender(kind, stream_id); if (new_sender != null) { senders.add(new_sender); } @@ -445,7 +464,7 @@ public class PeerConnection { for (RtpSender sender : senders) { sender.dispose(); } - senders = nativeGetSenders(); + senders = getNativeSenders(); return Collections.unmodifiableList(senders); } @@ -453,20 +472,20 @@ public class PeerConnection { for (RtpReceiver receiver : receivers) { receiver.dispose(); } - receivers = nativeGetReceivers(); + receivers = getNativeReceivers(); return Collections.unmodifiableList(receivers); } // Older, non-standard implementation of getStats. @Deprecated public boolean getStats(StatsObserver observer, MediaStreamTrack track) { - return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack); + return oldGetNativeStats(observer, (track == null) ? 0 : track.nativeTrack); } // Gets stats using the new stats collection API, see webrtc/api/stats/. These // will replace old stats collection API when the new API has matured enough. public void getStats(RTCStatsCollectorCallback callback) { - nativeNewGetStats(callback); + newGetNativeStats(callback); } // Limits the bandwidth allocated for all RTP streams sent by this @@ -479,13 +498,13 @@ public class PeerConnection { // continue until the stopRtcEventLog function is called. The max_size_bytes // argument is ignored, it is added for future use. public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) { - return nativeStartRtcEventLog(file_descriptor, max_size_bytes); + return startNativeRtcEventLog(file_descriptor, max_size_bytes); } // Stops recording an RTC event log. If no RTC event log is currently being // recorded, this call will have no effect. public void stopRtcEventLog() { - nativeStopRtcEventLog(); + stopNativeRtcEventLog(); } // TODO(fischman): add support for DTMF-related methods once that API @@ -517,7 +536,7 @@ public class PeerConnection { public void dispose() { close(); for (MediaStream stream : localStreams) { - nativeRemoveLocalStream(stream.nativeStream); + removeNativeLocalStream(stream.nativeStream); stream.dispose(); } localStreams.clear(); @@ -535,28 +554,28 @@ public class PeerConnection { private static native void freeObserver(long nativeObserver); - public native boolean nativeSetConfiguration(RTCConfiguration config, long nativeObserver); + private native boolean setNativeConfiguration(RTCConfiguration config, long nativeObserver); - private native boolean nativeAddIceCandidate( + private native boolean addNativeIceCandidate( String sdpMid, int sdpMLineIndex, String iceCandidateSdp); - private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates); + private native boolean removeNativeIceCandidates(final IceCandidate[] candidates); - private native boolean nativeAddLocalStream(long nativeStream); + private native boolean addNativeLocalStream(long nativeStream); - private native void nativeRemoveLocalStream(long nativeStream); + private native void removeNativeLocalStream(long nativeStream); - private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack); + private native boolean oldGetNativeStats(StatsObserver observer, long nativeTrack); - private native void nativeNewGetStats(RTCStatsCollectorCallback callback); + private native void newGetNativeStats(RTCStatsCollectorCallback callback); - private native RtpSender nativeCreateSender(String kind, String stream_id); + private native RtpSender createNativeSender(String kind, String stream_id); - private native List nativeGetSenders(); + private native List getNativeSenders(); - private native List nativeGetReceivers(); + private native List getNativeReceivers(); - private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes); + private native boolean startNativeRtcEventLog(int file_descriptor, int max_size_bytes); - private native void nativeStopRtcEventLog(); + private native void stopNativeRtcEventLog(); } diff --git a/sdk/android/api/org/webrtc/RtpReceiver.java b/sdk/android/api/org/webrtc/RtpReceiver.java index 69dfd9230f..ac296952ad 100644 --- a/sdk/android/api/org/webrtc/RtpReceiver.java +++ b/sdk/android/api/org/webrtc/RtpReceiver.java @@ -10,11 +10,14 @@ package org.webrtc; +import org.webrtc.MediaStreamTrack; + /** Java wrapper for a C++ RtpReceiverInterface. */ public class RtpReceiver { /** Java wrapper for a C++ RtpReceiverObserverInterface*/ public static interface Observer { // Called when the first audio or video packet is received. + @CalledByNative("Observer") public void onFirstPacketReceived(MediaStreamTrack.MediaType media_type); } @@ -23,9 +26,10 @@ public class RtpReceiver { private MediaStreamTrack cachedTrack; + @CalledByNative public RtpReceiver(long nativeRtpReceiver) { this.nativeRtpReceiver = nativeRtpReceiver; - long track = nativeGetTrack(nativeRtpReceiver); + long track = getNativeTrack(nativeRtpReceiver); // We can assume that an RtpReceiver always has an associated track. cachedTrack = new MediaStreamTrack(track); } @@ -35,21 +39,22 @@ public class RtpReceiver { } public boolean setParameters(RtpParameters parameters) { - return nativeSetParameters(nativeRtpReceiver, parameters); + return parameters == null ? false : setNativeParameters(nativeRtpReceiver, parameters); } public RtpParameters getParameters() { - return nativeGetParameters(nativeRtpReceiver); + return getNativeParameters(nativeRtpReceiver); } public String id() { - return nativeId(nativeRtpReceiver); + return getNativeId(nativeRtpReceiver); } + @CalledByNative public void dispose() { cachedTrack.dispose(); if (nativeObserver != 0) { - nativeUnsetObserver(nativeRtpReceiver, nativeObserver); + unsetNativeObserver(nativeRtpReceiver, nativeObserver); nativeObserver = 0; } JniCommon.nativeReleaseRef(nativeRtpReceiver); @@ -58,23 +63,23 @@ public class RtpReceiver { public void SetObserver(Observer observer) { // Unset the existing one before setting a new one. if (nativeObserver != 0) { - nativeUnsetObserver(nativeRtpReceiver, nativeObserver); + unsetNativeObserver(nativeRtpReceiver, nativeObserver); } - nativeObserver = nativeSetObserver(nativeRtpReceiver, observer); + nativeObserver = setNativeObserver(nativeRtpReceiver, observer); } // This should increment the reference count of the track. // Will be released in dispose(). - private static native long nativeGetTrack(long nativeRtpReceiver); + private static native long getNativeTrack(long nativeRtpReceiver); - private static native boolean nativeSetParameters( + private static native boolean setNativeParameters( long nativeRtpReceiver, RtpParameters parameters); - private static native RtpParameters nativeGetParameters(long nativeRtpReceiver); + private static native RtpParameters getNativeParameters(long nativeRtpReceiver); - private static native String nativeId(long nativeRtpReceiver); + private static native String getNativeId(long nativeRtpReceiver); - private static native long nativeSetObserver(long nativeRtpReceiver, Observer observer); + private static native long setNativeObserver(long nativeRtpReceiver, Observer observer); - private static native long nativeUnsetObserver(long nativeRtpReceiver, long nativeObserver); + private static native void unsetNativeObserver(long nativeRtpReceiver, long nativeObserver); }; diff --git a/sdk/android/src/jni/jni_helpers.h b/sdk/android/src/jni/jni_helpers.h index bfef3a8802..c0982df20b 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -155,14 +155,22 @@ class ScopedGlobalRef { public: ScopedGlobalRef(JNIEnv* jni, T obj) : obj_(static_cast(jni->NewGlobalRef(obj))) {} + + ScopedGlobalRef(ScopedGlobalRef&& other) : obj_(other.obj_) { + other.obj_ = nullptr; + } + ~ScopedGlobalRef() { - DeleteGlobalRef(AttachCurrentThreadIfNeeded(), obj_); + if (obj_) { + DeleteGlobalRef(AttachCurrentThreadIfNeeded(), obj_); + } } T operator*() const { return obj_; } private: T obj_; + RTC_DISALLOW_COPY_AND_ASSIGN(ScopedGlobalRef); }; // Provides a convenient way to iterate over a Java Iterable using the diff --git a/sdk/android/src/jni/pc/java_native_conversion.cc b/sdk/android/src/jni/pc/java_native_conversion.cc index db4f785ec1..f8f0763725 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.cc +++ b/sdk/android/src/jni/pc/java_native_conversion.cc @@ -471,10 +471,8 @@ void JavaToNativeRTCConfiguration( } } -void JavaToNativeRtpParameters(JNIEnv* jni, - jobject j_parameters, - RtpParameters* parameters) { - RTC_CHECK(parameters != nullptr); +RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters) { + RtpParameters parameters; jclass parameters_class = jni->FindClass("org/webrtc/RtpParameters"); jfieldID encodings_id = GetFieldID(jni, parameters_class, "encodings", "Ljava/util/List;"); @@ -507,7 +505,7 @@ void JavaToNativeRtpParameters(JNIEnv* jni, CHECK_EXCEPTION(jni) << "error during CallLongMethod"; encoding.ssrc = ssrc_value; } - parameters->encodings.push_back(encoding); + parameters.encodings.push_back(encoding); } // Convert codecs. @@ -533,8 +531,9 @@ void JavaToNativeRtpParameters(JNIEnv* jni, jobject j_num_channels = GetNullableObjectField(jni, j_codec, num_channels_id); codec.num_channels = JavaToNativeOptionalInt(jni, j_num_channels); - parameters->codecs.push_back(codec); + parameters.codecs.push_back(codec); } + return parameters; } jobject NativeToJavaRtpParameters(JNIEnv* jni, diff --git a/sdk/android/src/jni/pc/java_native_conversion.h b/sdk/android/src/jni/pc/java_native_conversion.h index faa4084aab..ecdbf1b14f 100644 --- a/sdk/android/src/jni/pc/java_native_conversion.h +++ b/sdk/android/src/jni/pc/java_native_conversion.h @@ -98,9 +98,7 @@ void JavaToNativeRTCConfiguration( /********************************************************* * RtpParameters, used for RtpSender and RtpReceiver APIs. *********************************************************/ -void JavaToNativeRtpParameters(JNIEnv* jni, - jobject j_parameters, - RtpParameters* parameters); +RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, jobject j_parameters); jobject NativeToJavaRtpParameters(JNIEnv* jni, const RtpParameters& parameters); diff --git a/sdk/android/src/jni/pc/peerconnection_jni.cc b/sdk/android/src/jni/pc/peerconnection_jni.cc index c3f2d12d42..e1c90beb68 100644 --- a/sdk/android/src/jni/pc/peerconnection_jni.cc +++ b/sdk/android/src/jni/pc/peerconnection_jni.cc @@ -168,7 +168,7 @@ JNI_FUNCTION_DECLARATION(void, } JNI_FUNCTION_DECLARATION(jboolean, - PeerConnection_nativeSetConfiguration, + PeerConnection_setNativeConfiguration, JNIEnv* jni, jobject j_pc, jobject j_rtc_config, @@ -185,7 +185,7 @@ JNI_FUNCTION_DECLARATION(jboolean, } JNI_FUNCTION_DECLARATION(jboolean, - PeerConnection_nativeAddIceCandidate, + PeerConnection_addNativeIceCandidate, JNIEnv* jni, jobject j_pc, jstring j_sdp_mid, @@ -199,7 +199,7 @@ JNI_FUNCTION_DECLARATION(jboolean, } JNI_FUNCTION_DECLARATION(jboolean, - PeerConnection_nativeRemoveIceCandidates, + PeerConnection_removeNativeIceCandidates, JNIEnv* jni, jobject j_pc, jobjectArray j_candidates) { @@ -213,7 +213,7 @@ JNI_FUNCTION_DECLARATION(jboolean, } JNI_FUNCTION_DECLARATION(jboolean, - PeerConnection_nativeAddLocalStream, + PeerConnection_addNativeLocalStream, JNIEnv* jni, jobject j_pc, jlong native_stream) { @@ -222,7 +222,7 @@ JNI_FUNCTION_DECLARATION(jboolean, } JNI_FUNCTION_DECLARATION(void, - PeerConnection_nativeRemoveLocalStream, + PeerConnection_removeNativeLocalStream, JNIEnv* jni, jobject j_pc, jlong native_stream) { @@ -231,7 +231,7 @@ JNI_FUNCTION_DECLARATION(void, } JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_nativeCreateSender, + PeerConnection_createNativeSender, JNIEnv* jni, jobject j_pc, jstring j_kind, @@ -258,7 +258,7 @@ JNI_FUNCTION_DECLARATION(jobject, } JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_nativeGetSenders, + PeerConnection_getNativeSenders, JNIEnv* jni, jobject j_pc) { jclass j_array_list_class = FindClass(jni, "java/util/ArrayList"); @@ -289,7 +289,7 @@ JNI_FUNCTION_DECLARATION(jobject, } JNI_FUNCTION_DECLARATION(jobject, - PeerConnection_nativeGetReceivers, + PeerConnection_getNativeReceivers, JNIEnv* jni, jobject j_pc) { jclass j_array_list_class = FindClass(jni, "java/util/ArrayList"); @@ -300,18 +300,9 @@ JNI_FUNCTION_DECLARATION(jobject, jobject j_receivers = jni->NewObject(j_array_list_class, j_array_list_ctor); CHECK_EXCEPTION(jni) << "error during NewObject"; - jclass j_rtp_receiver_class = FindClass(jni, "org/webrtc/RtpReceiver"); - jmethodID j_rtp_receiver_ctor = - GetMethodID(jni, j_rtp_receiver_class, "", "(J)V"); - auto receivers = ExtractNativePC(jni, j_pc)->GetReceivers(); for (const auto& receiver : receivers) { - jlong nativeReceiverPtr = jlongFromPointer(receiver.get()); - jobject j_receiver = jni->NewObject(j_rtp_receiver_class, - j_rtp_receiver_ctor, nativeReceiverPtr); - CHECK_EXCEPTION(jni) << "error during NewObject"; - // Receiver is now owned by Java object, and will be freed from there. - receiver->AddRef(); + jobject j_receiver = NativeToJavaRtpReceiver(jni, receiver); jni->CallBooleanMethod(j_receivers, j_array_list_add, j_receiver); CHECK_EXCEPTION(jni) << "error during CallBooleanMethod"; } @@ -319,7 +310,7 @@ JNI_FUNCTION_DECLARATION(jobject, } JNI_FUNCTION_DECLARATION(bool, - PeerConnection_nativeOldGetStats, + PeerConnection_oldGetNativeStats, JNIEnv* jni, jobject j_pc, jobject j_observer, @@ -332,7 +323,7 @@ JNI_FUNCTION_DECLARATION(bool, } JNI_FUNCTION_DECLARATION(void, - PeerConnection_nativeNewGetStats, + PeerConnection_newGetNativeStats, JNIEnv* jni, jobject j_pc, jobject j_callback) { @@ -357,7 +348,7 @@ JNI_FUNCTION_DECLARATION(jboolean, } JNI_FUNCTION_DECLARATION(bool, - PeerConnection_nativeStartRtcEventLog, + PeerConnection_startNativeRtcEventLog, JNIEnv* jni, jobject j_pc, int file_descriptor, @@ -367,7 +358,7 @@ JNI_FUNCTION_DECLARATION(bool, } JNI_FUNCTION_DECLARATION(void, - PeerConnection_nativeStopRtcEventLog, + PeerConnection_stopNativeRtcEventLog, JNIEnv* jni, jobject j_pc) { ExtractNativePC(jni, j_pc)->StopRtcEventLog(); diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc index 4ad107eb91..db5b3ddb52 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc @@ -15,6 +15,7 @@ #include "rtc_base/ptr_util.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaStream_jni.h" +#include "sdk/android/generated_peerconnection_jni/jni/PeerConnection_jni.h" #include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/datachannel.h" @@ -31,87 +32,68 @@ static JNIEnv* jni() { PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni, jobject j_observer) - : j_observer_global_(jni, j_observer), - j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)), - j_rtp_receiver_class_(jni, FindClass(jni, "org/webrtc/RtpReceiver")), - j_rtp_receiver_ctor_( - GetMethodID(jni, *j_rtp_receiver_class_, "", "(J)V")) {} + : j_observer_global_(jni, j_observer) {} PeerConnectionObserverJni::~PeerConnectionObserverJni() { ScopedLocalRefFrame local_ref_frame(jni()); while (!remote_streams_.empty()) DisposeRemoteStream(remote_streams_.begin()); - while (!rtp_receivers_.empty()) - DisposeRtpReceiver(rtp_receivers_.begin()); } void PeerConnectionObserverJni::OnIceCandidate( const IceCandidateInterface* candidate) { JNIEnv* env = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(env); - jobject j_candidate = NativeToJavaIceCandidate(env, *candidate); - - jmethodID m = GetMethodID(env, *j_observer_class_, "onIceCandidate", - "(Lorg/webrtc/IceCandidate;)V"); - env->CallVoidMethod(*j_observer_global_, m, j_candidate); - CHECK_EXCEPTION(env) << "error during CallVoidMethod"; + Java_Observer_onIceCandidate(env, *j_observer_global_, + NativeToJavaIceCandidate(env, *candidate)); } void PeerConnectionObserverJni::OnIceCandidatesRemoved( const std::vector& candidates) { - ScopedLocalRefFrame local_ref_frame(jni()); - jobjectArray candidates_array = NativeToJavaCandidateArray(jni(), candidates); - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceCandidatesRemoved", - "([Lorg/webrtc/IceCandidate;)V"); - jni()->CallVoidMethod(*j_observer_global_, m, candidates_array); - CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + Java_Observer_onIceCandidatesRemoved( + env, *j_observer_global_, NativeToJavaCandidateArray(env, candidates)); } void PeerConnectionObserverJni::OnSignalingChange( PeerConnectionInterface::SignalingState new_state) { - ScopedLocalRefFrame local_ref_frame(jni()); - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSignalingChange", - "(Lorg/webrtc/PeerConnection$SignalingState;)V"); - jobject new_state_enum = JavaEnumFromIndexAndClassName( - jni(), "PeerConnection$SignalingState", new_state); - jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + Java_Observer_onSignalingChange( + env, *j_observer_global_, + Java_SignalingState_fromNativeIndex(env, new_state)); } void PeerConnectionObserverJni::OnIceConnectionChange( PeerConnectionInterface::IceConnectionState new_state) { - ScopedLocalRefFrame local_ref_frame(jni()); - jmethodID m = - GetMethodID(jni(), *j_observer_class_, "onIceConnectionChange", - "(Lorg/webrtc/PeerConnection$IceConnectionState;)V"); - jobject new_state_enum = JavaEnumFromIndexAndClassName( - jni(), "PeerConnection$IceConnectionState", new_state); - jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + Java_Observer_onIceConnectionChange( + env, *j_observer_global_, + Java_IceConnectionState_fromNativeIndex(env, new_state)); } void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) { - ScopedLocalRefFrame local_ref_frame(jni()); - jmethodID m = GetMethodID(jni(), *j_observer_class_, - "onIceConnectionReceivingChange", "(Z)V"); - jni()->CallVoidMethod(*j_observer_global_, m, receiving); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + Java_Observer_onIceConnectionReceivingChange(env, *j_observer_global_, + receiving); } void PeerConnectionObserverJni::OnIceGatheringChange( PeerConnectionInterface::IceGatheringState new_state) { - ScopedLocalRefFrame local_ref_frame(jni()); - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceGatheringChange", - "(Lorg/webrtc/PeerConnection$IceGatheringState;)V"); - jobject new_state_enum = JavaEnumFromIndexAndClassName( - jni(), "PeerConnection$IceGatheringState", new_state); - jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + Java_Observer_onIceGatheringChange( + env, *j_observer_global_, + Java_IceGatheringState_fromNativeIndex(env, new_state)); } void PeerConnectionObserverJni::OnAddStream( rtc::scoped_refptr stream) { - ScopedLocalRefFrame local_ref_frame(jni()); + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); // The stream could be added into the remote_streams_ map when calling // OnAddTrack. jobject j_stream = GetOrCreateJavaStream(stream); @@ -123,10 +105,7 @@ void PeerConnectionObserverJni::OnAddStream( AddNativeVideoTrackToJavaStream(track, j_stream); } - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream", - "(Lorg/webrtc/MediaStream;)V"); - jni()->CallVoidMethod(*j_observer_global_, m, j_stream); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + Java_Observer_onAddStream(env, *j_observer_global_, j_stream); // Create an observer to update the Java stream when the native stream's set // of tracks changes. @@ -194,15 +173,12 @@ void PeerConnectionObserverJni::OnVideoTrackRemovedFromStream( void PeerConnectionObserverJni::OnRemoveStream( rtc::scoped_refptr stream) { - ScopedLocalRefFrame local_ref_frame(jni()); + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); RTC_CHECK(it != remote_streams_.end()) << "unexpected stream: " << std::hex << stream; - jobject j_stream = it->second; - jmethodID m = GetMethodID(jni(), *j_observer_class_, "onRemoveStream", - "(Lorg/webrtc/MediaStream;)V"); - jni()->CallVoidMethod(*j_observer_global_, m, j_stream); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + Java_Observer_onRemoveStream(env, *j_observer_global_, it->second); // Release the refptr reference so that DisposeRemoteStream can assert // it removes the final reference. @@ -214,38 +190,26 @@ void PeerConnectionObserverJni::OnDataChannel( rtc::scoped_refptr channel) { JNIEnv* env = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(env); - jobject j_channel = WrapNativeDataChannel(env, channel); - jmethodID m = GetMethodID(env, *j_observer_class_, "onDataChannel", - "(Lorg/webrtc/DataChannel;)V"); - env->CallVoidMethod(*j_observer_global_, m, j_channel); - CHECK_EXCEPTION(env) << "error during CallVoidMethod"; + Java_Observer_onDataChannel(env, *j_observer_global_, + WrapNativeDataChannel(env, channel)); } void PeerConnectionObserverJni::OnRenegotiationNeeded() { - ScopedLocalRefFrame local_ref_frame(jni()); - jmethodID m = - GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V"); - jni()->CallVoidMethod(*j_observer_global_, m); - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + Java_Observer_onRenegotiationNeeded(env, *j_observer_global_); } void PeerConnectionObserverJni::OnAddTrack( rtc::scoped_refptr receiver, const std::vector>& streams) { - ScopedLocalRefFrame local_ref_frame(jni()); - jobject j_rtp_receiver = - jni()->NewObject(*j_rtp_receiver_class_, j_rtp_receiver_ctor_, - jlongFromPointer(receiver.get())); - CHECK_EXCEPTION(jni()) << "error during NewObject"; - receiver->AddRef(); - rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver); + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedLocalRefFrame local_ref_frame(env); + jobject j_rtp_receiver = NativeToJavaRtpReceiver(env, receiver); + rtp_receivers_.emplace_back(env, j_rtp_receiver); - jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); - jmethodID m = - GetMethodID(jni(), *j_observer_class_, "onAddTrack", - "(Lorg/webrtc/RtpReceiver;[Lorg/webrtc/MediaStream;)V"); - jni()->CallVoidMethod(*j_observer_global_, m, j_rtp_receiver, j_stream_array); - CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; + Java_Observer_onAddTrack(env, *j_observer_global_, j_rtp_receiver, + NativeToJavaMediaStreamArray(env, streams)); } void PeerConnectionObserverJni::SetConstraints( @@ -274,17 +238,6 @@ void PeerConnectionObserverJni::DisposeRemoteStream( DeleteGlobalRef(env, j_stream); } -void PeerConnectionObserverJni::DisposeRtpReceiver( - const NativeToJavaRtpReceiverMap::iterator& it) { - jobject j_rtp_receiver = it->second; - rtp_receivers_.erase(it); - jni()->CallVoidMethod( - j_rtp_receiver, - GetMethodID(jni(), *j_rtp_receiver_class_, "dispose", "()V")); - CHECK_EXCEPTION(jni()) << "error during RtpReceiver.dispose()"; - DeleteGlobalRef(jni(), j_rtp_receiver); -} - // If the NativeToJavaStreamsMap contains the stream, return it. // Otherwise, create a new Java MediaStream. jobject PeerConnectionObserverJni::GetOrCreateJavaStream( diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.h b/sdk/android/src/jni/pc/peerconnectionobserver_jni.h index 6f95a38567..46e68cb5ce 100644 --- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.h +++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.h @@ -19,6 +19,7 @@ #include "api/peerconnectioninterface.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/mediaconstraints_jni.h" +#include "sdk/android/src/jni/pc/rtpreceiver.h" namespace webrtc { namespace jni { @@ -57,14 +58,12 @@ class PeerConnectionObserverJni : public PeerConnectionObserver, private: typedef std::map NativeToJavaStreamsMap; - typedef std::map NativeToJavaRtpReceiverMap; typedef std::map NativeToJavaMediaTrackMap; typedef std::map NativeMediaStreamTrackToNativeRtpReceiver; void DisposeRemoteStream(const NativeToJavaStreamsMap::iterator& it); - void DisposeRtpReceiver(const NativeToJavaRtpReceiverMap::iterator& it); // If the NativeToJavaStreamsMap contains the stream, return it. // Otherwise, create a new Java MediaStream. @@ -100,14 +99,11 @@ class PeerConnectionObserverJni : public PeerConnectionObserver, MediaStreamInterface* stream); const ScopedGlobalRef j_observer_global_; - const ScopedGlobalRef j_observer_class_; - const ScopedGlobalRef j_rtp_receiver_class_; - const jmethodID j_rtp_receiver_ctor_; // C++ -> Java remote streams. The stored jobects are global refs and must be // manually deleted upon removal. Use DisposeRemoteStream(). NativeToJavaStreamsMap remote_streams_; - NativeToJavaRtpReceiverMap rtp_receivers_; + std::vector rtp_receivers_; std::unique_ptr constraints_; std::vector> stream_observers_; }; diff --git a/sdk/android/src/jni/pc/rtpreceiver_jni.cc b/sdk/android/src/jni/pc/rtpreceiver.cc similarity index 57% rename from sdk/android/src/jni/pc/rtpreceiver_jni.cc rename to sdk/android/src/jni/pc/rtpreceiver.cc index eb60cc0c0f..0381b3d595 100644 --- a/sdk/android/src/jni/pc/rtpreceiver_jni.cc +++ b/sdk/android/src/jni/pc/rtpreceiver.cc @@ -8,16 +8,61 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "api/rtpreceiverinterface.h" +#include "sdk/android/src/jni/pc/rtpreceiver.h" + +#include "sdk/android/generated_peerconnection_jni/jni/RtpReceiver_jni.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/java_native_conversion.h" -#include "sdk/android/src/jni/pc/rtpreceiverobserver_jni.h" namespace webrtc { namespace jni { +namespace { + +// Adapter between the C++ RtpReceiverObserverInterface and the Java +// RtpReceiver.Observer interface. Wraps an instance of the Java interface and +// dispatches C++ callbacks to Java. +class RtpReceiverObserverJni : public RtpReceiverObserverInterface { + public: + RtpReceiverObserverJni(JNIEnv* env, jobject j_observer) + : j_observer_global_(env, j_observer) {} + + ~RtpReceiverObserverJni() override = default; + + void OnFirstPacketReceived(cricket::MediaType media_type) override { + JNIEnv* const env = AttachCurrentThreadIfNeeded(); + Java_Observer_onFirstPacketReceived(env, *j_observer_global_, + NativeToJavaMediaType(env, media_type)); + } + + private: + const ScopedGlobalRef j_observer_global_; +}; + +} // namespace + +jobject NativeToJavaRtpReceiver( + JNIEnv* env, + rtc::scoped_refptr receiver) { + // Receiver is now owned by Java object, and will be freed from there. + return Java_RtpReceiver_Constructor(env, + jlongFromPointer(receiver.release())); +} + +JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner(JNIEnv* env, + jobject j_receiver) + : j_receiver_(env, j_receiver) {} + +JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner( + JavaRtpReceiverGlobalOwner&& other) = default; + +JavaRtpReceiverGlobalOwner::~JavaRtpReceiverGlobalOwner() { + if (*j_receiver_) + Java_RtpReceiver_dispose(AttachCurrentThreadIfNeeded(), *j_receiver_); +} + JNI_FUNCTION_DECLARATION(jlong, - RtpReceiver_nativeGetTrack, + RtpReceiver_getNativeTrack, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer, @@ -29,22 +74,18 @@ JNI_FUNCTION_DECLARATION(jlong, } JNI_FUNCTION_DECLARATION(jboolean, - RtpReceiver_nativeSetParameters, + RtpReceiver_setNativeParameters, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer, jobject j_parameters) { - if (IsNull(jni, j_parameters)) { - return false; - } - RtpParameters parameters; - JavaToNativeRtpParameters(jni, j_parameters, ¶meters); + RtpParameters parameters = JavaToNativeRtpParameters(jni, j_parameters); return reinterpret_cast(j_rtp_receiver_pointer) ->SetParameters(parameters); } JNI_FUNCTION_DECLARATION(jobject, - RtpReceiver_nativeGetParameters, + RtpReceiver_getNativeParameters, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer) { @@ -55,7 +96,7 @@ JNI_FUNCTION_DECLARATION(jobject, } JNI_FUNCTION_DECLARATION(jstring, - RtpReceiver_nativeId, + RtpReceiver_getNativeId, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer) { @@ -65,7 +106,7 @@ JNI_FUNCTION_DECLARATION(jstring, } JNI_FUNCTION_DECLARATION(jlong, - RtpReceiver_nativeSetObserver, + RtpReceiver_setNativeObserver, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer, @@ -78,7 +119,7 @@ JNI_FUNCTION_DECLARATION(jlong, } JNI_FUNCTION_DECLARATION(void, - RtpReceiver_nativeUnsetObserver, + RtpReceiver_unsetNativeObserver, JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer, diff --git a/sdk/android/src/jni/pc/rtpreceiver.h b/sdk/android/src/jni/pc/rtpreceiver.h new file mode 100644 index 0000000000..ec87d7c46c --- /dev/null +++ b/sdk/android/src/jni/pc/rtpreceiver.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef SDK_ANDROID_SRC_JNI_PC_RTPRECEIVER_H_ +#define SDK_ANDROID_SRC_JNI_PC_RTPRECEIVER_H_ + +#include + +#include "api/rtpreceiverinterface.h" +#include "sdk/android/src/jni/jni_helpers.h" + +namespace webrtc { +namespace jni { + +jobject NativeToJavaRtpReceiver( + JNIEnv* env, + rtc::scoped_refptr receiver); + +// Takes ownership of the passed |j_receiver| and stores it as a global +// reference. Will call dispose() in the dtor. +class JavaRtpReceiverGlobalOwner { + public: + JavaRtpReceiverGlobalOwner(JNIEnv* env, jobject j_receiver); + JavaRtpReceiverGlobalOwner(JavaRtpReceiverGlobalOwner&& other); + ~JavaRtpReceiverGlobalOwner(); + + private: + ScopedGlobalRef j_receiver_; +}; + +} // namespace jni +} // namespace webrtc + +#endif // SDK_ANDROID_SRC_JNI_PC_RTPRECEIVER_H_ diff --git a/sdk/android/src/jni/pc/rtpreceiverobserver_jni.cc b/sdk/android/src/jni/pc/rtpreceiverobserver_jni.cc deleted file mode 100644 index 8e900631da..0000000000 --- a/sdk/android/src/jni/pc/rtpreceiverobserver_jni.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "sdk/android/src/jni/pc/rtpreceiverobserver_jni.h" - -#include "sdk/android/src/jni/pc/java_native_conversion.h" - -namespace webrtc { -namespace jni { - -void RtpReceiverObserverJni::OnFirstPacketReceived( - cricket::MediaType media_type) { - JNIEnv* const jni = AttachCurrentThreadIfNeeded(); - - jmethodID j_on_first_packet_received_mid = GetMethodID( - jni, GetObjectClass(jni, *j_observer_global_), "onFirstPacketReceived", - "(Lorg/webrtc/MediaStreamTrack$MediaType;)V"); - // Get the Java version of media type. - jobject JavaMediaType = NativeToJavaMediaType(jni, media_type); - // Trigger the callback function. - jni->CallVoidMethod(*j_observer_global_, j_on_first_packet_received_mid, - JavaMediaType); - CHECK_EXCEPTION(jni) << "error during CallVoidMethod"; -} - -} // namespace jni -} // namespace webrtc diff --git a/sdk/android/src/jni/pc/rtpreceiverobserver_jni.h b/sdk/android/src/jni/pc/rtpreceiverobserver_jni.h deleted file mode 100644 index c6455338e8..0000000000 --- a/sdk/android/src/jni/pc/rtpreceiverobserver_jni.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef SDK_ANDROID_SRC_JNI_PC_RTPRECEIVEROBSERVER_JNI_H_ -#define SDK_ANDROID_SRC_JNI_PC_RTPRECEIVEROBSERVER_JNI_H_ - -#include "api/rtpreceiverinterface.h" -#include "sdk/android/src/jni/jni_helpers.h" - -namespace webrtc { -namespace jni { - -// Adapter between the C++ RtpReceiverObserverInterface and the Java -// RtpReceiver.Observer interface. Wraps an instance of the Java interface and -// dispatches C++ callbacks to Java. -class RtpReceiverObserverJni : public RtpReceiverObserverInterface { - public: - RtpReceiverObserverJni(JNIEnv* jni, jobject j_observer) - : j_observer_global_(jni, j_observer) {} - - ~RtpReceiverObserverJni() override {} - - void OnFirstPacketReceived(cricket::MediaType media_type) override; - - private: - const ScopedGlobalRef j_observer_global_; -}; - -} // namespace jni -} // namespace webrtc - -#endif // SDK_ANDROID_SRC_JNI_PC_RTPRECEIVEROBSERVER_JNI_H_ diff --git a/sdk/android/src/jni/pc/rtpsender_jni.cc b/sdk/android/src/jni/pc/rtpsender_jni.cc index a30bc6c87e..7dd34bbb1f 100644 --- a/sdk/android/src/jni/pc/rtpsender_jni.cc +++ b/sdk/android/src/jni/pc/rtpsender_jni.cc @@ -56,8 +56,7 @@ JNI_FUNCTION_DECLARATION(jboolean, if (IsNull(jni, j_parameters)) { return false; } - RtpParameters parameters; - JavaToNativeRtpParameters(jni, j_parameters, ¶meters); + RtpParameters parameters = JavaToNativeRtpParameters(jni, j_parameters); return reinterpret_cast(j_rtp_sender_pointer) ->SetParameters(parameters); }