Android: Generate JNI code for DataChannel
Bug: webrtc:8278
Change-Id: I107c839656500971cbd3da7557e14776759c318a
Reviewed-on: https://webrtc-review.googlesource.com/25820
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20873}
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index ecf8a1e..c346563 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -278,6 +278,7 @@
generate_jni("generated_peerconnection_jni") {
sources = [
+ "api/org/webrtc/DataChannel.java",
"api/org/webrtc/MediaConstraints.java",
"api/org/webrtc/NetworkMonitor.java",
"api/org/webrtc/NetworkMonitorAutoDetect.java",
@@ -293,9 +294,8 @@
"src/jni/pc/androidnetworkmonitor_jni.h",
"src/jni/pc/audiotrack_jni.cc",
"src/jni/pc/callsessionfilerotatinglogsink_jni.cc",
- "src/jni/pc/datachannel_jni.cc",
- "src/jni/pc/datachannelobserver_jni.cc",
- "src/jni/pc/datachannelobserver_jni.h",
+ "src/jni/pc/datachannel.cc",
+ "src/jni/pc/datachannel.h",
"src/jni/pc/dtmfsender_jni.cc",
"src/jni/pc/java_native_conversion.cc",
"src/jni/pc/java_native_conversion.h",
diff --git a/sdk/android/api/org/webrtc/DataChannel.java b/sdk/android/api/org/webrtc/DataChannel.java
index dc64ccc..883025e 100644
--- a/sdk/android/api/org/webrtc/DataChannel.java
+++ b/sdk/android/api/org/webrtc/DataChannel.java
@@ -26,17 +26,34 @@
// Optional unsigned short in WebIDL, -1 means unspecified.
public int id = -1;
- public Init() {}
+ @CalledByNative("Init")
+ boolean getOrdered() {
+ return ordered;
+ }
- // Called only by native code.
- private Init(boolean ordered, int maxRetransmitTimeMs, int maxRetransmits, String protocol,
- boolean negotiated, int id) {
- this.ordered = ordered;
- this.maxRetransmitTimeMs = maxRetransmitTimeMs;
- this.maxRetransmits = maxRetransmits;
- this.protocol = protocol;
- this.negotiated = negotiated;
- this.id = id;
+ @CalledByNative("Init")
+ int getMaxRetransmitTimeMs() {
+ return maxRetransmitTimeMs;
+ }
+
+ @CalledByNative("Init")
+ int getMaxRetransmits() {
+ return maxRetransmits;
+ }
+
+ @CalledByNative("Init")
+ String getProtocol() {
+ return protocol;
+ }
+
+ @CalledByNative("Init")
+ boolean getNegotiated() {
+ return negotiated;
+ }
+
+ @CalledByNative("Init")
+ int getId() {
+ return id;
}
}
@@ -51,6 +68,7 @@
*/
public final boolean binary;
+ @CalledByNative("Buffer")
public Buffer(ByteBuffer data, boolean binary) {
this.data = data;
this.binary = binary;
@@ -60,23 +78,34 @@
/** Java version of C++ DataChannelObserver. */
public interface Observer {
/** The data channel's bufferedAmount has changed. */
- public void onBufferedAmountChange(long previousAmount);
+ @CalledByNative("Observer") public void onBufferedAmountChange(long previousAmount);
/** The data channel state has changed. */
- public void onStateChange();
+ @CalledByNative("Observer") public void onStateChange();
/**
* A data buffer was successfully received. NOTE: |buffer.data| will be
* freed once this function returns so callers who want to use the data
* asynchronously must make sure to copy it first.
*/
- public void onMessage(Buffer buffer);
+ @CalledByNative("Observer") public void onMessage(Buffer buffer);
}
/** Keep in sync with DataChannelInterface::DataState. */
- public enum State { CONNECTING, OPEN, CLOSING, CLOSED }
+ public enum State {
+ CONNECTING,
+ OPEN,
+ CLOSING,
+ CLOSED;
+
+ @CalledByNative("State")
+ static State fromNativeIndex(int nativeIndex) {
+ return values()[nativeIndex];
+ }
+ }
private final long nativeDataChannel;
private long nativeObserver;
+ @CalledByNative
public DataChannel(long nativeDataChannel) {
this.nativeDataChannel = nativeDataChannel;
}
@@ -123,5 +152,12 @@
private native boolean sendNative(byte[] data, boolean binary);
/** Dispose of native resources attached to this channel. */
- public native void dispose();
+ public void dispose() {
+ JniCommon.nativeReleaseRef(nativeDataChannel);
+ }
+
+ @CalledByNative
+ long getNativeDataChannel() {
+ return nativeDataChannel;
+ }
};
diff --git a/sdk/android/src/jni/classreferenceholder.cc b/sdk/android/src/jni/classreferenceholder.cc
index 910aa56..1187d3e 100644
--- a/sdk/android/src/jni/classreferenceholder.cc
+++ b/sdk/android/src/jni/classreferenceholder.cc
@@ -63,10 +63,6 @@
LoadClass(jni, "org/webrtc/Camera1Enumerator");
LoadClass(jni, "org/webrtc/Camera2Enumerator");
LoadClass(jni, "org/webrtc/CameraEnumerationAndroid");
- LoadClass(jni, "org/webrtc/DataChannel");
- LoadClass(jni, "org/webrtc/DataChannel$Buffer");
- LoadClass(jni, "org/webrtc/DataChannel$Init");
- LoadClass(jni, "org/webrtc/DataChannel$State");
LoadClass(jni, "org/webrtc/EglBase");
LoadClass(jni, "org/webrtc/EglBase$Context");
LoadClass(jni, "org/webrtc/EglBase14$Context");
diff --git a/sdk/android/src/jni/pc/datachannel.cc b/sdk/android/src/jni/pc/datachannel.cc
new file mode 100644
index 0000000..758e4b9
--- /dev/null
+++ b/sdk/android/src/jni/pc/datachannel.cc
@@ -0,0 +1,159 @@
+/*
+ * 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 <memory>
+
+#include <limits>
+
+#include "api/datachannelinterface.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/ptr_util.h"
+#include "sdk/android/generated_peerconnection_jni/jni/DataChannel_jni.h"
+#include "sdk/android/src/jni/jni_helpers.h"
+#include "sdk/android/src/jni/pc/datachannel.h"
+
+namespace webrtc {
+namespace jni {
+
+namespace {
+// Adapter for a Java DataChannel$Observer presenting a C++ DataChannelObserver
+// and dispatching the callback from C++ back to Java.
+class DataChannelObserverJni : public DataChannelObserver {
+ public:
+ DataChannelObserverJni(JNIEnv* jni, jobject j_observer);
+ virtual ~DataChannelObserverJni() {}
+
+ void OnBufferedAmountChange(uint64_t previous_amount) override;
+ void OnStateChange() override;
+ void OnMessage(const DataBuffer& buffer) override;
+
+ private:
+ const ScopedGlobalRef<jobject> j_observer_global_;
+};
+
+DataChannelObserverJni::DataChannelObserverJni(JNIEnv* jni, jobject j_observer)
+ : j_observer_global_(jni, j_observer) {}
+
+void DataChannelObserverJni::OnBufferedAmountChange(uint64_t previous_amount) {
+ JNIEnv* env = AttachCurrentThreadIfNeeded();
+ Java_Observer_onBufferedAmountChange(env, *j_observer_global_,
+ previous_amount);
+}
+
+void DataChannelObserverJni::OnStateChange() {
+ JNIEnv* env = AttachCurrentThreadIfNeeded();
+ Java_Observer_onStateChange(env, *j_observer_global_);
+}
+
+void DataChannelObserverJni::OnMessage(const DataBuffer& buffer) {
+ JNIEnv* env = AttachCurrentThreadIfNeeded();
+ ScopedLocalRefFrame local_ref_frame(env);
+ jobject byte_buffer = env->NewDirectByteBuffer(
+ const_cast<char*>(buffer.data.data<char>()), buffer.data.size());
+ jobject j_buffer = Java_Buffer_Constructor(env, byte_buffer, buffer.binary);
+ Java_Observer_onMessage(env, *j_observer_global_, j_buffer);
+}
+
+DataChannelInterface* ExtractNativeDC(JNIEnv* jni, jobject j_dc) {
+ jlong j_d = Java_DataChannel_getNativeDataChannel(jni, j_dc);
+ return reinterpret_cast<DataChannelInterface*>(j_d);
+}
+
+} // namespace
+
+DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init) {
+ DataChannelInit init;
+ init.ordered = Java_Init_getOrdered(env, j_init);
+ init.maxRetransmitTime = Java_Init_getMaxRetransmitTimeMs(env, j_init);
+ init.maxRetransmits = Java_Init_getMaxRetransmits(env, j_init);
+ init.protocol = JavaToStdString(env, Java_Init_getProtocol(env, j_init));
+ init.negotiated = Java_Init_getNegotiated(env, j_init);
+ init.id = Java_Init_getId(env, j_init);
+ return init;
+}
+
+jobject WrapNativeDataChannel(
+ JNIEnv* env,
+ rtc::scoped_refptr<DataChannelInterface> channel) {
+ // Channel is now owned by Java object, and will be freed from there.
+ return channel ? Java_DataChannel_Constructor(
+ env, jlongFromPointer(channel.release()))
+ : nullptr;
+}
+
+JNI_FUNCTION_DECLARATION(jlong,
+ DataChannel_registerObserverNative,
+ JNIEnv* jni,
+ jobject j_dc,
+ jobject j_observer) {
+ auto observer = rtc::MakeUnique<DataChannelObserverJni>(jni, j_observer);
+ ExtractNativeDC(jni, j_dc)->RegisterObserver(observer.get());
+ return jlongFromPointer(observer.release());
+}
+
+JNI_FUNCTION_DECLARATION(void,
+ DataChannel_unregisterObserverNative,
+ JNIEnv* jni,
+ jobject j_dc,
+ jlong native_observer) {
+ ExtractNativeDC(jni, j_dc)->UnregisterObserver();
+ delete reinterpret_cast<DataChannelObserverJni*>(native_observer);
+}
+
+JNI_FUNCTION_DECLARATION(jstring,
+ DataChannel_label,
+ JNIEnv* jni,
+ jobject j_dc) {
+ return JavaStringFromStdString(jni, ExtractNativeDC(jni, j_dc)->label());
+}
+
+JNI_FUNCTION_DECLARATION(jint, DataChannel_id, JNIEnv* jni, jobject j_dc) {
+ int id = ExtractNativeDC(jni, j_dc)->id();
+ RTC_CHECK_LE(id, std::numeric_limits<int32_t>::max())
+ << "id overflowed jint!";
+ return static_cast<jint>(id);
+}
+
+JNI_FUNCTION_DECLARATION(jobject,
+ DataChannel_state,
+ JNIEnv* jni,
+ jobject j_dc) {
+ return Java_State_fromNativeIndex(jni, ExtractNativeDC(jni, j_dc)->state());
+}
+
+JNI_FUNCTION_DECLARATION(jlong,
+ DataChannel_bufferedAmount,
+ JNIEnv* jni,
+ jobject j_dc) {
+ uint64_t buffered_amount = ExtractNativeDC(jni, j_dc)->buffered_amount();
+ RTC_CHECK_LE(buffered_amount, std::numeric_limits<int64_t>::max())
+ << "buffered_amount overflowed jlong!";
+ return static_cast<jlong>(buffered_amount);
+}
+
+JNI_FUNCTION_DECLARATION(void, DataChannel_close, JNIEnv* jni, jobject j_dc) {
+ ExtractNativeDC(jni, j_dc)->Close();
+}
+
+JNI_FUNCTION_DECLARATION(jboolean,
+ DataChannel_sendNative,
+ JNIEnv* jni,
+ jobject j_dc,
+ jbyteArray data,
+ jboolean binary) {
+ jbyte* bytes = jni->GetByteArrayElements(data, nullptr);
+ bool ret = ExtractNativeDC(jni, j_dc)->Send(DataBuffer(
+ rtc::CopyOnWriteBuffer(bytes, jni->GetArrayLength(data)), binary));
+ jni->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
+ return ret;
+}
+
+} // namespace jni
+} // namespace webrtc
diff --git a/sdk/android/src/jni/pc/datachannel.h b/sdk/android/src/jni/pc/datachannel.h
new file mode 100644
index 0000000..557520a
--- /dev/null
+++ b/sdk/android/src/jni/pc/datachannel.h
@@ -0,0 +1,25 @@
+/*
+ * 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_DATACHANNEL_H_
+#define SDK_ANDROID_SRC_JNI_PC_DATACHANNEL_H_
+
+namespace webrtc {
+namespace jni {
+
+DataChannelInit JavaToNativeDataChannelInit(JNIEnv* env, jobject j_init);
+
+jobject WrapNativeDataChannel(JNIEnv* env,
+ rtc::scoped_refptr<DataChannelInterface> channel);
+
+} // namespace jni
+} // namespace webrtc
+
+#endif // SDK_ANDROID_SRC_JNI_PC_DATACHANNEL_H_
diff --git a/sdk/android/src/jni/pc/datachannel_jni.cc b/sdk/android/src/jni/pc/datachannel_jni.cc
deleted file mode 100644
index a4e3cb6..0000000
--- a/sdk/android/src/jni/pc/datachannel_jni.cc
+++ /dev/null
@@ -1,101 +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 <memory>
-
-#include "api/datachannelinterface.h"
-#include "sdk/android/src/jni/jni_helpers.h"
-#include "sdk/android/src/jni/pc/datachannelobserver_jni.h"
-
-namespace webrtc {
-namespace jni {
-
-static DataChannelInterface* ExtractNativeDC(JNIEnv* jni, jobject j_dc) {
- jfieldID native_dc_id =
- GetFieldID(jni, GetObjectClass(jni, j_dc), "nativeDataChannel", "J");
- jlong j_d = GetLongField(jni, j_dc, native_dc_id);
- return reinterpret_cast<DataChannelInterface*>(j_d);
-}
-
-JNI_FUNCTION_DECLARATION(jlong,
- DataChannel_registerObserverNative,
- JNIEnv* jni,
- jobject j_dc,
- jobject j_observer) {
- std::unique_ptr<DataChannelObserverJni> observer(
- new DataChannelObserverJni(jni, j_observer));
- ExtractNativeDC(jni, j_dc)->RegisterObserver(observer.get());
- return jlongFromPointer(observer.release());
-}
-
-JNI_FUNCTION_DECLARATION(void,
- DataChannel_unregisterObserverNative,
- JNIEnv* jni,
- jobject j_dc,
- jlong native_observer) {
- ExtractNativeDC(jni, j_dc)->UnregisterObserver();
- delete reinterpret_cast<DataChannelObserverJni*>(native_observer);
-}
-
-JNI_FUNCTION_DECLARATION(jstring,
- DataChannel_label,
- JNIEnv* jni,
- jobject j_dc) {
- return JavaStringFromStdString(jni, ExtractNativeDC(jni, j_dc)->label());
-}
-
-JNI_FUNCTION_DECLARATION(jint, DataChannel_id, JNIEnv* jni, jobject j_dc) {
- int id = ExtractNativeDC(jni, j_dc)->id();
- RTC_CHECK_LE(id, std::numeric_limits<int32_t>::max())
- << "id overflowed jint!";
- return static_cast<jint>(id);
-}
-
-JNI_FUNCTION_DECLARATION(jobject,
- DataChannel_state,
- JNIEnv* jni,
- jobject j_dc) {
- return JavaEnumFromIndexAndClassName(jni, "DataChannel$State",
- ExtractNativeDC(jni, j_dc)->state());
-}
-
-JNI_FUNCTION_DECLARATION(jlong,
- DataChannel_bufferedAmount,
- JNIEnv* jni,
- jobject j_dc) {
- uint64_t buffered_amount = ExtractNativeDC(jni, j_dc)->buffered_amount();
- RTC_CHECK_LE(buffered_amount, std::numeric_limits<int64_t>::max())
- << "buffered_amount overflowed jlong!";
- return static_cast<jlong>(buffered_amount);
-}
-
-JNI_FUNCTION_DECLARATION(void, DataChannel_close, JNIEnv* jni, jobject j_dc) {
- ExtractNativeDC(jni, j_dc)->Close();
-}
-
-JNI_FUNCTION_DECLARATION(jboolean,
- DataChannel_sendNative,
- JNIEnv* jni,
- jobject j_dc,
- jbyteArray data,
- jboolean binary) {
- jbyte* bytes = jni->GetByteArrayElements(data, NULL);
- bool ret = ExtractNativeDC(jni, j_dc)->Send(DataBuffer(
- rtc::CopyOnWriteBuffer(bytes, jni->GetArrayLength(data)), binary));
- jni->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
- return ret;
-}
-
-JNI_FUNCTION_DECLARATION(void, DataChannel_dispose, JNIEnv* jni, jobject j_dc) {
- CHECK_RELEASE(ExtractNativeDC(jni, j_dc));
-}
-
-} // namespace jni
-} // namespace webrtc
diff --git a/sdk/android/src/jni/pc/datachannelobserver_jni.cc b/sdk/android/src/jni/pc/datachannelobserver_jni.cc
deleted file mode 100644
index 1ca8932..0000000
--- a/sdk/android/src/jni/pc/datachannelobserver_jni.cc
+++ /dev/null
@@ -1,67 +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/datachannelobserver_jni.h"
-
-#include "sdk/android/src/jni/classreferenceholder.h"
-
-namespace webrtc {
-namespace jni {
-
-// Convenience, used since callbacks occur on the signaling thread, which may
-// be a non-Java thread.
-static JNIEnv* jni() {
- return AttachCurrentThreadIfNeeded();
-}
-
-DataChannelObserverJni::DataChannelObserverJni(JNIEnv* jni, jobject j_observer)
- : j_observer_global_(jni, j_observer),
- j_observer_class_(jni, GetObjectClass(jni, j_observer)),
- j_buffer_class_(jni, FindClass(jni, "org/webrtc/DataChannel$Buffer")),
- j_on_buffered_amount_change_mid_(GetMethodID(jni,
- *j_observer_class_,
- "onBufferedAmountChange",
- "(J)V")),
- j_on_state_change_mid_(
- GetMethodID(jni, *j_observer_class_, "onStateChange", "()V")),
- j_on_message_mid_(GetMethodID(jni,
- *j_observer_class_,
- "onMessage",
- "(Lorg/webrtc/DataChannel$Buffer;)V")),
- j_buffer_ctor_(GetMethodID(jni,
- *j_buffer_class_,
- "<init>",
- "(Ljava/nio/ByteBuffer;Z)V")) {}
-
-void DataChannelObserverJni::OnBufferedAmountChange(uint64_t previous_amount) {
- ScopedLocalRefFrame local_ref_frame(jni());
- jni()->CallVoidMethod(*j_observer_global_, j_on_buffered_amount_change_mid_,
- previous_amount);
- CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
-}
-
-void DataChannelObserverJni::OnStateChange() {
- ScopedLocalRefFrame local_ref_frame(jni());
- jni()->CallVoidMethod(*j_observer_global_, j_on_state_change_mid_);
- CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
-}
-
-void DataChannelObserverJni::OnMessage(const DataBuffer& buffer) {
- ScopedLocalRefFrame local_ref_frame(jni());
- jobject byte_buffer = jni()->NewDirectByteBuffer(
- const_cast<char*>(buffer.data.data<char>()), buffer.data.size());
- jobject j_buffer = jni()->NewObject(*j_buffer_class_, j_buffer_ctor_,
- byte_buffer, buffer.binary);
- jni()->CallVoidMethod(*j_observer_global_, j_on_message_mid_, j_buffer);
- CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
-}
-
-} // namespace jni
-} // namespace webrtc
diff --git a/sdk/android/src/jni/pc/datachannelobserver_jni.h b/sdk/android/src/jni/pc/datachannelobserver_jni.h
deleted file mode 100644
index dcea9de..0000000
--- a/sdk/android/src/jni/pc/datachannelobserver_jni.h
+++ /dev/null
@@ -1,44 +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_DATACHANNELOBSERVER_JNI_H_
-#define SDK_ANDROID_SRC_JNI_PC_DATACHANNELOBSERVER_JNI_H_
-
-#include "api/datachannelinterface.h"
-#include "sdk/android/src/jni/jni_helpers.h"
-
-namespace webrtc {
-namespace jni {
-
-// Adapter for a Java DataChannel$Observer presenting a C++ DataChannelObserver
-// and dispatching the callback from C++ back to Java.
-class DataChannelObserverJni : public DataChannelObserver {
- public:
- DataChannelObserverJni(JNIEnv* jni, jobject j_observer);
- virtual ~DataChannelObserverJni() {}
-
- void OnBufferedAmountChange(uint64_t previous_amount) override;
- void OnStateChange() override;
- void OnMessage(const DataBuffer& buffer) override;
-
- private:
- const ScopedGlobalRef<jobject> j_observer_global_;
- const ScopedGlobalRef<jclass> j_observer_class_;
- const ScopedGlobalRef<jclass> j_buffer_class_;
- const jmethodID j_on_buffered_amount_change_mid_;
- const jmethodID j_on_state_change_mid_;
- const jmethodID j_on_message_mid_;
- const jmethodID j_buffer_ctor_;
-};
-
-} // namespace jni
-} // namespace webrtc
-
-#endif // SDK_ANDROID_SRC_JNI_PC_DATACHANNELOBSERVER_JNI_H_
diff --git a/sdk/android/src/jni/pc/java_native_conversion.cc b/sdk/android/src/jni/pc/java_native_conversion.cc
index 31668e9..56a1f4e 100644
--- a/sdk/android/src/jni/pc/java_native_conversion.cc
+++ b/sdk/android/src/jni/pc/java_native_conversion.cc
@@ -18,31 +18,6 @@
namespace webrtc {
namespace jni {
-DataChannelInit JavaToNativeDataChannelInit(JNIEnv* jni, jobject j_init) {
- DataChannelInit init;
-
- jclass j_init_class = FindClass(jni, "org/webrtc/DataChannel$Init");
- jfieldID ordered_id = GetFieldID(jni, j_init_class, "ordered", "Z");
- jfieldID max_retransmit_time_id =
- GetFieldID(jni, j_init_class, "maxRetransmitTimeMs", "I");
- jfieldID max_retransmits_id =
- GetFieldID(jni, j_init_class, "maxRetransmits", "I");
- jfieldID protocol_id =
- GetFieldID(jni, j_init_class, "protocol", "Ljava/lang/String;");
- jfieldID negotiated_id = GetFieldID(jni, j_init_class, "negotiated", "Z");
- jfieldID id_id = GetFieldID(jni, j_init_class, "id", "I");
-
- init.ordered = GetBooleanField(jni, j_init, ordered_id);
- init.maxRetransmitTime = GetIntField(jni, j_init, max_retransmit_time_id);
- init.maxRetransmits = GetIntField(jni, j_init, max_retransmits_id);
- init.protocol =
- JavaToStdString(jni, GetStringField(jni, j_init, protocol_id));
- init.negotiated = GetBooleanField(jni, j_init, negotiated_id);
- init.id = GetIntField(jni, j_init, id_id);
-
- return init;
-}
-
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type) {
jclass j_media_type_class =
FindClass(jni, "org/webrtc/MediaStreamTrack$MediaType");
diff --git a/sdk/android/src/jni/pc/java_native_conversion.h b/sdk/android/src/jni/pc/java_native_conversion.h
index 73e1eef..9b74ad3 100644
--- a/sdk/android/src/jni/pc/java_native_conversion.h
+++ b/sdk/android/src/jni/pc/java_native_conversion.h
@@ -30,8 +30,6 @@
namespace webrtc {
namespace jni {
-DataChannelInit JavaToNativeDataChannelInit(JNIEnv* jni, jobject j_init);
-
cricket::MediaType JavaToNativeMediaType(JNIEnv* jni, jobject j_media_type);
jobject NativeToJavaMediaType(JNIEnv* jni, cricket::MediaType media_type);
diff --git a/sdk/android/src/jni/pc/peerconnection_jni.cc b/sdk/android/src/jni/pc/peerconnection_jni.cc
index 8183700..075f382 100644
--- a/sdk/android/src/jni/pc/peerconnection_jni.cc
+++ b/sdk/android/src/jni/pc/peerconnection_jni.cc
@@ -37,6 +37,7 @@
#include "rtc_base/logging.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/jni_helpers.h"
+#include "sdk/android/src/jni/pc/datachannel.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h"
#include "sdk/android/src/jni/pc/mediaconstraints_jni.h"
#include "sdk/android/src/jni/pc/peerconnectionobserver_jni.h"
@@ -95,23 +96,7 @@
rtc::scoped_refptr<DataChannelInterface> channel(
ExtractNativePC(jni, j_pc)->CreateDataChannel(
JavaToStdString(jni, j_label), &init));
- // Mustn't pass channel.get() directly through NewObject to avoid reading its
- // vararg parameter as 64-bit and reading memory that doesn't belong to the
- // 32-bit parameter.
- jlong nativeChannelPtr = jlongFromPointer(channel.get());
- if (!nativeChannelPtr) {
- RTC_LOG(LS_ERROR) << "Failed to create DataChannel";
- return nullptr;
- }
- jclass j_data_channel_class = FindClass(jni, "org/webrtc/DataChannel");
- jmethodID j_data_channel_ctor =
- GetMethodID(jni, j_data_channel_class, "<init>", "(J)V");
- jobject j_channel = jni->NewObject(j_data_channel_class, j_data_channel_ctor,
- nativeChannelPtr);
- CHECK_EXCEPTION(jni) << "error during NewObject";
- // Channel is now owned by Java object, and will be freed from there.
- channel->AddRef();
- return j_channel;
+ return WrapNativeDataChannel(jni, channel);
}
JNI_FUNCTION_DECLARATION(void,
diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc b/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc
index a0eac91..03436de 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/src/jni/classreferenceholder.h"
+#include "sdk/android/src/jni/pc/datachannel.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h"
namespace webrtc {
@@ -46,9 +47,6 @@
j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")),
j_video_track_ctor_(
GetMethodID(jni, *j_video_track_class_, "<init>", "(J)V")),
- j_data_channel_class_(jni, FindClass(jni, "org/webrtc/DataChannel")),
- j_data_channel_ctor_(
- GetMethodID(jni, *j_data_channel_class_, "<init>", "(J)V")),
j_rtp_receiver_class_(jni, FindClass(jni, "org/webrtc/RtpReceiver")),
j_rtp_receiver_ctor_(
GetMethodID(jni, *j_rtp_receiver_class_, "<init>", "(J)V")) {}
@@ -290,23 +288,13 @@
void PeerConnectionObserverJni::OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> channel) {
- ScopedLocalRefFrame local_ref_frame(jni());
- jobject j_channel =
- jni()->NewObject(*j_data_channel_class_, j_data_channel_ctor_,
- jlongFromPointer(channel.get()));
- CHECK_EXCEPTION(jni()) << "error during NewObject";
-
- jmethodID m = GetMethodID(jni(), *j_observer_class_, "onDataChannel",
+ 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");
- jni()->CallVoidMethod(*j_observer_global_, m, j_channel);
-
- // Channel is now owned by Java object, and will be freed from
- // DataChannel.dispose(). Important that this be done _after_ the
- // CallVoidMethod above as Java code might call back into native code and be
- // surprised to see a refcount of 2.
- channel->AddRef();
-
- CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
+ env->CallVoidMethod(*j_observer_global_, m, j_channel);
+ CHECK_EXCEPTION(env) << "error during CallVoidMethod";
}
void PeerConnectionObserverJni::OnRenegotiationNeeded() {
diff --git a/sdk/android/src/jni/pc/peerconnectionobserver_jni.h b/sdk/android/src/jni/pc/peerconnectionobserver_jni.h
index d6fd0f3..44eb319 100644
--- a/sdk/android/src/jni/pc/peerconnectionobserver_jni.h
+++ b/sdk/android/src/jni/pc/peerconnectionobserver_jni.h
@@ -118,8 +118,6 @@
const jmethodID j_audio_track_ctor_;
const ScopedGlobalRef<jclass> j_video_track_class_;
const jmethodID j_video_track_ctor_;
- const ScopedGlobalRef<jclass> j_data_channel_class_;
- const jmethodID j_data_channel_ctor_;
const ScopedGlobalRef<jclass> j_rtp_receiver_class_;
const jmethodID j_rtp_receiver_ctor_;