diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 9daae54666..ea5b4b497a 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -269,15 +269,6 @@ rtc_static_library("null_media_jni") { } } -generate_jni("generated_peerconnection_jni") { - sources = [ - "api/org/webrtc/NetworkMonitor.java", - "api/org/webrtc/NetworkMonitorAutoDetect.java", - ] - jni_package = "" - jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" -} - rtc_static_library("peerconnection_jni") { sources = [ "src/jni/androidnetworkmonitor_jni.h", @@ -337,7 +328,6 @@ rtc_static_library("peerconnection_jni") { deps = [ ":base_jni", - ":generated_peerconnection_jni", "../..:webrtc_common", "../../api/video_codecs:video_codecs_api", "../../media:rtc_data", diff --git a/sdk/android/api/org/webrtc/NetworkMonitor.java b/sdk/android/api/org/webrtc/NetworkMonitor.java index ad070eb61e..29530da98b 100644 --- a/sdk/android/api/org/webrtc/NetworkMonitor.java +++ b/sdk/android/api/org/webrtc/NetworkMonitor.java @@ -63,7 +63,6 @@ public class NetworkMonitor { /** * Returns the singleton instance. */ - @CalledByNative public static NetworkMonitor getInstance() { if (instance == null) { instance = new NetworkMonitor(); @@ -78,11 +77,12 @@ public class NetworkMonitor { } /** + * Called by the native code. + * * Enables auto detection of the current network state based on notifications * from the system. Note that this requires the embedding app have the * platform ACCESS_NETWORK_STATE permission. */ - @CalledByNative private void startMonitoring(long nativeObserver) { Logging.d(TAG, "Start monitoring from native observer " + nativeObserver); nativeNetworkObservers.add(nativeObserver); @@ -96,7 +96,7 @@ public class NetworkMonitor { updateObserverActiveNetworkList(nativeObserver); } - @CalledByNative + // Called by the native code. private void stopMonitoring(long nativeObserver) { Logging.d(TAG, "Stop monitoring from native observer " + nativeObserver); nativeNetworkObservers.remove(nativeObserver); @@ -106,13 +106,13 @@ public class NetworkMonitor { } } - // Returns true if network binding is supported on this platform. - @CalledByNative + // Called by the native code to determine if network binding is supported + // on this platform. private boolean networkBindingSupported() { return autoDetector != null && autoDetector.supportNetworkCallback(); } - @CalledByNative + // Called by the native code to get the Android SDK version. private static int androidSdkInt() { return Build.VERSION.SDK_INT; } @@ -215,16 +215,9 @@ public class NetworkMonitor { return connectionType != ConnectionType.CONNECTION_NONE; } - @NativeClassQualifiedName("webrtc::jni::AndroidNetworkMonitor") private native void nativeNotifyConnectionTypeChanged(long nativePtr); - - @NativeClassQualifiedName("webrtc::jni::AndroidNetworkMonitor") private native void nativeNotifyOfNetworkConnect(long nativePtr, NetworkInformation networkInfo); - - @NativeClassQualifiedName("webrtc::jni::AndroidNetworkMonitor") private native void nativeNotifyOfNetworkDisconnect(long nativePtr, long networkHandle); - - @NativeClassQualifiedName("webrtc::jni::AndroidNetworkMonitor") private native void nativeNotifyOfActiveNetworkList( long nativePtr, NetworkInformation[] networkInfos); diff --git a/sdk/android/api/org/webrtc/NetworkMonitorAutoDetect.java b/sdk/android/api/org/webrtc/NetworkMonitorAutoDetect.java index 86eb1c20f6..9cae2ef331 100644 --- a/sdk/android/api/org/webrtc/NetworkMonitorAutoDetect.java +++ b/sdk/android/api/org/webrtc/NetworkMonitorAutoDetect.java @@ -62,11 +62,6 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver { public IPAddress(byte[] address) { this.address = address; } - - @CalledByNative("IPAddress") - private byte[] getAddress() { - return address; - } } /** Java version of NetworkMonitor.NetworkInformation */ @@ -82,26 +77,6 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver { this.handle = handle; this.ipAddresses = addresses; } - - @CalledByNative("NetworkInformation") - private IPAddress[] getIpAddresses() { - return ipAddresses; - } - - @CalledByNative("NetworkInformation") - private ConnectionType getConnectionType() { - return type; - } - - @CalledByNative("NetworkInformation") - private long getHandle() { - return handle; - } - - @CalledByNative("NetworkInformation") - private String getName() { - return name; - } }; static class NetworkState { diff --git a/sdk/android/src/jni/pc/androidnetworkmonitor_jni.cc b/sdk/android/src/jni/pc/androidnetworkmonitor_jni.cc index 5cac107398..ff1f4f66ee 100644 --- a/sdk/android/src/jni/pc/androidnetworkmonitor_jni.cc +++ b/sdk/android/src/jni/pc/androidnetworkmonitor_jni.cc @@ -17,8 +17,7 @@ #include "rtc_base/bind.h" #include "rtc_base/checks.h" #include "rtc_base/ipaddress.h" -#include "sdk/android/generated_peerconnection_jni/jni/NetworkMonitorAutoDetect_jni.h" -#include "sdk/android/generated_peerconnection_jni/jni/NetworkMonitor_jni.h" +#include "sdk/android/src/jni/classreferenceholder.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { @@ -29,6 +28,8 @@ enum AndroidSdkVersion { SDK_VERSION_MARSHMALLOW = 23 }; +int AndroidNetworkMonitor::android_sdk_int_ = 0; + static NetworkType GetNetworkTypeFromJava(JNIEnv* jni, jobject j_network_type) { std::string enum_name = GetJavaEnumName(jni, j_network_type); if (enum_name == "CONNECTION_UNKNOWN") { @@ -86,7 +87,10 @@ static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) { } static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject j_ip_address) { - jbyteArray j_addresses = Java_IPAddress_getAddress(jni, j_ip_address); + jclass j_ip_address_class = GetObjectClass(jni, j_ip_address); + jfieldID j_address_id = GetFieldID(jni, j_ip_address_class, "address", "[B"); + jbyteArray j_addresses = + static_cast(GetObjectField(jni, j_ip_address, j_address_id)); size_t address_length = jni->GetArrayLength(j_addresses); jbyte* addr_array = jni->GetByteArrayElements(j_addresses, nullptr); CHECK_EXCEPTION(jni) << "Error during GetIPAddressFromJava"; @@ -122,15 +126,26 @@ static void GetIPAddressesFromJava(JNIEnv* jni, static NetworkInformation GetNetworkInformationFromJava( JNIEnv* jni, jobject j_network_info) { + jclass j_network_info_class = GetObjectClass(jni, j_network_info); + jfieldID j_interface_name_id = + GetFieldID(jni, j_network_info_class, "name", "Ljava/lang/String;"); + jfieldID j_handle_id = GetFieldID(jni, j_network_info_class, "handle", "J"); + jfieldID j_type_id = + GetFieldID(jni, j_network_info_class, "type", + "Lorg/webrtc/NetworkMonitorAutoDetect$ConnectionType;"); + jfieldID j_ip_addresses_id = + GetFieldID(jni, j_network_info_class, "ipAddresses", + "[Lorg/webrtc/NetworkMonitorAutoDetect$IPAddress;"); + NetworkInformation network_info; network_info.interface_name = JavaToStdString( - jni, Java_NetworkInformation_getName(jni, j_network_info)); + jni, GetStringField(jni, j_network_info, j_interface_name_id)); network_info.handle = static_cast( - Java_NetworkInformation_getHandle(jni, j_network_info)); + GetLongField(jni, j_network_info, j_handle_id)); network_info.type = GetNetworkTypeFromJava( - jni, Java_NetworkInformation_getConnectionType(jni, j_network_info)); - jobjectArray j_ip_addresses = - Java_NetworkInformation_getIpAddresses(jni, j_network_info); + jni, GetObjectField(jni, j_network_info, j_type_id)); + jobjectArray j_ip_addresses = static_cast( + GetObjectField(jni, j_network_info, j_ip_addresses_id)); GetIPAddressesFromJava(jni, j_ip_addresses, &network_info.ip_addresses); return network_info; } @@ -146,9 +161,25 @@ std::string NetworkInformation::ToString() const { return ss.str(); } -AndroidNetworkMonitor::AndroidNetworkMonitor(JNIEnv* env) - : android_sdk_int_(Java_NetworkMonitor_androidSdkInt(env)), - j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)) {} +AndroidNetworkMonitor::AndroidNetworkMonitor() + : j_network_monitor_class_(jni(), + FindClass(jni(), "org/webrtc/NetworkMonitor")), + j_network_monitor_( + jni(), + jni()->CallStaticObjectMethod( + *j_network_monitor_class_, + GetStaticMethodID(jni(), + *j_network_monitor_class_, + "getInstance", + "()Lorg/webrtc/NetworkMonitor;"))) { + CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.init"; + if (android_sdk_int_ <= 0) { + jmethodID m = GetStaticMethodID(jni(), *j_network_monitor_class_, + "androidSdkInt", "()I"); + android_sdk_int_ = jni()->CallStaticIntMethod(*j_network_monitor_class_, m); + CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.androidSdkInt"; + } +} void AndroidNetworkMonitor::Start() { RTC_CHECK(thread_checker_.CalledOnValidThread()); @@ -162,9 +193,10 @@ void AndroidNetworkMonitor::Start() { // it creates sockets. worker_thread()->socketserver()->set_network_binder(this); - JNIEnv* env = AttachCurrentThreadIfNeeded(); - Java_NetworkMonitor_startMonitoring(env, *j_network_monitor_, - jlongFromPointer(this)); + jmethodID m = + GetMethodID(jni(), *j_network_monitor_class_, "startMonitoring", "(J)V"); + jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this)); + CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; } void AndroidNetworkMonitor::Stop() { @@ -180,9 +212,10 @@ void AndroidNetworkMonitor::Stop() { worker_thread()->socketserver()->set_network_binder(nullptr); } - JNIEnv* env = AttachCurrentThreadIfNeeded(); - Java_NetworkMonitor_stopMonitoring(env, *j_network_monitor_, - jlongFromPointer(this)); + jmethodID m = + GetMethodID(jni(), *j_network_monitor_class_, "stopMonitoring", "(J)V"); + jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this)); + CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring"; network_handle_by_address_.clear(); network_info_by_handle_.clear(); @@ -195,11 +228,14 @@ rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork( const rtc::IPAddress& address) { RTC_CHECK(thread_checker_.CalledOnValidThread()); + jmethodID network_binding_supported_id = GetMethodID( + jni(), *j_network_monitor_class_, "networkBindingSupported", "()Z"); // Android prior to Lollipop didn't have support for binding sockets to // networks. This may also occur if there is no connectivity manager service. - JNIEnv* env = AttachCurrentThreadIfNeeded(); - const bool network_binding_supported = - Java_NetworkMonitor_networkBindingSupported(env, *j_network_monitor_); + bool network_binding_supported = jni()->CallBooleanMethod( + *j_network_monitor_, network_binding_supported_id); + CHECK_EXCEPTION(jni()) + << "Error during NetworkMonitor.networkBindingSupported"; if (!network_binding_supported) { RTC_LOG(LS_WARNING) << "BindSocketToNetwork is not supported on this platform " @@ -351,40 +387,60 @@ rtc::AdapterType AndroidNetworkMonitor::GetAdapterType( rtc::NetworkMonitorInterface* AndroidNetworkMonitorFactory::CreateNetworkMonitor() { - return new AndroidNetworkMonitor(AttachCurrentThreadIfNeeded()); + return new AndroidNetworkMonitor(); } -void AndroidNetworkMonitor::NotifyConnectionTypeChanged(JNIEnv* env, - jobject j_caller) { - OnNetworksChanged(); +JNI_FUNCTION_DECLARATION(void, + NetworkMonitor_nativeNotifyConnectionTypeChanged, + JNIEnv* jni, + jobject j_monitor, + jlong j_native_monitor) { + rtc::NetworkMonitorInterface* network_monitor = + reinterpret_cast(j_native_monitor); + network_monitor->OnNetworksChanged(); } -void AndroidNetworkMonitor::NotifyOfActiveNetworkList( - JNIEnv* env, - jobject j_caller, - jobjectArray j_network_infos) { +JNI_FUNCTION_DECLARATION(void, + NetworkMonitor_nativeNotifyOfActiveNetworkList, + JNIEnv* jni, + jobject j_monitor, + jlong j_native_monitor, + jobjectArray j_network_infos) { + AndroidNetworkMonitor* network_monitor = + reinterpret_cast(j_native_monitor); std::vector network_infos; - size_t num_networks = env->GetArrayLength(j_network_infos); + size_t num_networks = jni->GetArrayLength(j_network_infos); for (size_t i = 0; i < num_networks; ++i) { - jobject j_network_info = env->GetObjectArrayElement(j_network_infos, i); - CHECK_EXCEPTION(env) << "Error during GetObjectArrayElement"; - network_infos.push_back(GetNetworkInformationFromJava(env, j_network_info)); + jobject j_network_info = jni->GetObjectArrayElement(j_network_infos, i); + CHECK_EXCEPTION(jni) << "Error during GetObjectArrayElement"; + network_infos.push_back(GetNetworkInformationFromJava(jni, j_network_info)); } - SetNetworkInfos(network_infos); + network_monitor->SetNetworkInfos(network_infos); } -void AndroidNetworkMonitor::NotifyOfNetworkConnect(JNIEnv* env, - jobject j_caller, - jobject j_network_info) { +JNI_FUNCTION_DECLARATION(void, + NetworkMonitor_nativeNotifyOfNetworkConnect, + JNIEnv* jni, + jobject j_monitor, + jlong j_native_monitor, + jobject j_network_info) { + AndroidNetworkMonitor* network_monitor = + reinterpret_cast(j_native_monitor); NetworkInformation network_info = - GetNetworkInformationFromJava(env, j_network_info); - OnNetworkConnected(network_info); + GetNetworkInformationFromJava(jni, j_network_info); + network_monitor->OnNetworkConnected(network_info); } -void AndroidNetworkMonitor::NotifyOfNetworkDisconnect(JNIEnv* env, - jobject j_caller, - jlong network_handle) { - OnNetworkDisconnected(static_cast(network_handle)); +JNI_FUNCTION_DECLARATION(void, + NetworkMonitor_nativeNotifyOfNetworkDisconnect, + JNIEnv* jni, + jobject j_monitor, + jlong j_native_monitor, + jlong network_handle) { + AndroidNetworkMonitor* network_monitor = + reinterpret_cast(j_native_monitor); + network_monitor->OnNetworkDisconnected( + static_cast(network_handle)); } } // namespace jni diff --git a/sdk/android/src/jni/pc/androidnetworkmonitor_jni.h b/sdk/android/src/jni/pc/androidnetworkmonitor_jni.h index cf8d50fe71..70e3acd17b 100644 --- a/sdk/android/src/jni/pc/androidnetworkmonitor_jni.h +++ b/sdk/android/src/jni/pc/androidnetworkmonitor_jni.h @@ -52,7 +52,7 @@ struct NetworkInformation { class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, public rtc::NetworkBinderInterface { public: - explicit AndroidNetworkMonitor(JNIEnv* env); + AndroidNetworkMonitor(); // TODO(sakal): Remove once down stream dependencies have been updated. static void SetAndroidContext(JNIEnv* jni, jobject context) {} @@ -69,22 +69,15 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, // Always expected to be called on the network thread. void SetNetworkInfos(const std::vector& network_infos); - void NotifyConnectionTypeChanged(JNIEnv* env, jobject j_caller); - void NotifyOfNetworkConnect(JNIEnv* env, - jobject j_caller, - jobject j_network_info); - void NotifyOfNetworkDisconnect(JNIEnv* env, - jobject j_caller, - jlong network_handle); - void NotifyOfActiveNetworkList(JNIEnv* env, - jobject j_caller, - jobjectArray j_network_infos); - private: + static jobject application_context_; + static int android_sdk_int_; + JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); } + void OnNetworkConnected_w(const NetworkInformation& network_info); void OnNetworkDisconnected_w(NetworkHandle network_handle); - const int android_sdk_int_; + ScopedGlobalRef j_network_monitor_class_; ScopedGlobalRef j_network_monitor_; rtc::ThreadChecker thread_checker_; bool started_ = false;