From cada60193dd77c62568e05cf4f0d130bf372655a Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Mon, 20 Nov 2017 21:55:27 +0100 Subject: [PATCH] Reland "Android: Generate JNI code for androidnetworkmonitor_jni" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 522c1bc6bb945d66bf77f175da48e1644d74511e. Reason for revert: Reland with a temporary fix. Original change's description: > Revert "Android: Generate JNI code for androidnetworkmonitor_jni" > > This reverts commit 768e1c0ea1f2077675df31915132a0557aca400e. > > Reason for revert: Breaks AppRTCMobile. > > Original change's description: > > Android: Generate JNI code for androidnetworkmonitor_jni > > > > Bug: webrtc:8278 > > Change-Id: I8447b2de5ec2610760f7112b6f86e54d94325322 > > Reviewed-on: https://webrtc-review.googlesource.com/24520 > > Reviewed-by: Sami Kalliomäki > > Commit-Queue: Magnus Jedvert > > Cr-Commit-Position: refs/heads/master@{#20796} > > TBR=magjed@webrtc.org,sakal@webrtc.org > > Change-Id: I45f8d19abd81386872b7c095ac7eca21fa06077c > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:8278,webrtc:8556 > Reviewed-on: https://webrtc-review.googlesource.com/24622 > Reviewed-by: Magnus Jedvert > Commit-Queue: Magnus Jedvert > Cr-Commit-Position: refs/heads/master@{#20800} TBR=magjed@webrtc.org,sakal@webrtc.org Change-Id: I7cc404993addb17f0397127a10aac67476ef6ff4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:8278, webrtc:8556 Reviewed-on: https://webrtc-review.googlesource.com/24623 Commit-Queue: Magnus Jedvert Reviewed-by: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#20801} --- sdk/android/BUILD.gn | 10 ++ .../api/org/webrtc/NetworkMonitor.java | 19 ++- .../org/webrtc/NetworkMonitorAutoDetect.java | 26 ++++ .../src/jni/pc/androidnetworkmonitor_jni.cc | 140 ++++++------------ .../src/jni/pc/androidnetworkmonitor_jni.h | 19 ++- 5 files changed, 104 insertions(+), 110 deletions(-) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index ea5b4b497a..9daae54666 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -269,6 +269,15 @@ 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", @@ -328,6 +337,7 @@ 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 29530da98b..ad070eb61e 100644 --- a/sdk/android/api/org/webrtc/NetworkMonitor.java +++ b/sdk/android/api/org/webrtc/NetworkMonitor.java @@ -63,6 +63,7 @@ public class NetworkMonitor { /** * Returns the singleton instance. */ + @CalledByNative public static NetworkMonitor getInstance() { if (instance == null) { instance = new NetworkMonitor(); @@ -77,12 +78,11 @@ 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); } - // Called by the native code. + @CalledByNative private void stopMonitoring(long nativeObserver) { Logging.d(TAG, "Stop monitoring from native observer " + nativeObserver); nativeNetworkObservers.remove(nativeObserver); @@ -106,13 +106,13 @@ public class NetworkMonitor { } } - // Called by the native code to determine if network binding is supported - // on this platform. + // Returns true if network binding is supported on this platform. + @CalledByNative private boolean networkBindingSupported() { return autoDetector != null && autoDetector.supportNetworkCallback(); } - // Called by the native code to get the Android SDK version. + @CalledByNative private static int androidSdkInt() { return Build.VERSION.SDK_INT; } @@ -215,9 +215,16 @@ 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 9cae2ef331..ae7908ddc6 100644 --- a/sdk/android/api/org/webrtc/NetworkMonitorAutoDetect.java +++ b/sdk/android/api/org/webrtc/NetworkMonitorAutoDetect.java @@ -35,6 +35,7 @@ import java.net.SocketException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.webrtc.NetworkMonitorAutoDetect; /** * Borrowed from Chromium's @@ -62,6 +63,11 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver { public IPAddress(byte[] address) { this.address = address; } + + @CalledByNative("IPAddress") + private byte[] getAddress() { + return address; + } } /** Java version of NetworkMonitor.NetworkInformation */ @@ -77,6 +83,26 @@ public class NetworkMonitorAutoDetect extends BroadcastReceiver { this.handle = handle; this.ipAddresses = addresses; } + + @CalledByNative("NetworkInformation") + private IPAddress[] getIpAddresses() { + return ipAddresses; + } + + @CalledByNative("NetworkInformation") + private NetworkMonitorAutoDetect.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 ff1f4f66ee..5cac107398 100644 --- a/sdk/android/src/jni/pc/androidnetworkmonitor_jni.cc +++ b/sdk/android/src/jni/pc/androidnetworkmonitor_jni.cc @@ -17,7 +17,8 @@ #include "rtc_base/bind.h" #include "rtc_base/checks.h" #include "rtc_base/ipaddress.h" -#include "sdk/android/src/jni/classreferenceholder.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/jni_helpers.h" namespace webrtc { @@ -28,8 +29,6 @@ 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") { @@ -87,10 +86,7 @@ static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) { } static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject 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)); + jbyteArray j_addresses = Java_IPAddress_getAddress(jni, j_ip_address); size_t address_length = jni->GetArrayLength(j_addresses); jbyte* addr_array = jni->GetByteArrayElements(j_addresses, nullptr); CHECK_EXCEPTION(jni) << "Error during GetIPAddressFromJava"; @@ -126,26 +122,15 @@ 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, GetStringField(jni, j_network_info, j_interface_name_id)); + jni, Java_NetworkInformation_getName(jni, j_network_info)); network_info.handle = static_cast( - GetLongField(jni, j_network_info, j_handle_id)); + Java_NetworkInformation_getHandle(jni, j_network_info)); network_info.type = GetNetworkTypeFromJava( - jni, GetObjectField(jni, j_network_info, j_type_id)); - jobjectArray j_ip_addresses = static_cast( - GetObjectField(jni, j_network_info, j_ip_addresses_id)); + jni, Java_NetworkInformation_getConnectionType(jni, j_network_info)); + jobjectArray j_ip_addresses = + Java_NetworkInformation_getIpAddresses(jni, j_network_info); GetIPAddressesFromJava(jni, j_ip_addresses, &network_info.ip_addresses); return network_info; } @@ -161,25 +146,9 @@ std::string NetworkInformation::ToString() const { return ss.str(); } -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"; - } -} +AndroidNetworkMonitor::AndroidNetworkMonitor(JNIEnv* env) + : android_sdk_int_(Java_NetworkMonitor_androidSdkInt(env)), + j_network_monitor_(env, Java_NetworkMonitor_getInstance(env)) {} void AndroidNetworkMonitor::Start() { RTC_CHECK(thread_checker_.CalledOnValidThread()); @@ -193,10 +162,9 @@ void AndroidNetworkMonitor::Start() { // it creates sockets. worker_thread()->socketserver()->set_network_binder(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"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + Java_NetworkMonitor_startMonitoring(env, *j_network_monitor_, + jlongFromPointer(this)); } void AndroidNetworkMonitor::Stop() { @@ -212,10 +180,9 @@ void AndroidNetworkMonitor::Stop() { worker_thread()->socketserver()->set_network_binder(nullptr); } - 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"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + Java_NetworkMonitor_stopMonitoring(env, *j_network_monitor_, + jlongFromPointer(this)); network_handle_by_address_.clear(); network_info_by_handle_.clear(); @@ -228,14 +195,11 @@ 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. - bool network_binding_supported = jni()->CallBooleanMethod( - *j_network_monitor_, network_binding_supported_id); - CHECK_EXCEPTION(jni()) - << "Error during NetworkMonitor.networkBindingSupported"; + JNIEnv* env = AttachCurrentThreadIfNeeded(); + const bool network_binding_supported = + Java_NetworkMonitor_networkBindingSupported(env, *j_network_monitor_); if (!network_binding_supported) { RTC_LOG(LS_WARNING) << "BindSocketToNetwork is not supported on this platform " @@ -387,60 +351,40 @@ rtc::AdapterType AndroidNetworkMonitor::GetAdapterType( rtc::NetworkMonitorInterface* AndroidNetworkMonitorFactory::CreateNetworkMonitor() { - return new AndroidNetworkMonitor(); + return new AndroidNetworkMonitor(AttachCurrentThreadIfNeeded()); } -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::NotifyConnectionTypeChanged(JNIEnv* env, + jobject j_caller) { + OnNetworksChanged(); } -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); +void AndroidNetworkMonitor::NotifyOfActiveNetworkList( + JNIEnv* env, + jobject j_caller, + jobjectArray j_network_infos) { std::vector network_infos; - size_t num_networks = jni->GetArrayLength(j_network_infos); + size_t num_networks = env->GetArrayLength(j_network_infos); for (size_t i = 0; i < num_networks; ++i) { - 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)); + 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)); } - network_monitor->SetNetworkInfos(network_infos); + SetNetworkInfos(network_infos); } -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); +void AndroidNetworkMonitor::NotifyOfNetworkConnect(JNIEnv* env, + jobject j_caller, + jobject j_network_info) { NetworkInformation network_info = - GetNetworkInformationFromJava(jni, j_network_info); - network_monitor->OnNetworkConnected(network_info); + GetNetworkInformationFromJava(env, j_network_info); + OnNetworkConnected(network_info); } -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)); +void AndroidNetworkMonitor::NotifyOfNetworkDisconnect(JNIEnv* env, + jobject j_caller, + jlong network_handle) { + 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 70e3acd17b..cf8d50fe71 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: - AndroidNetworkMonitor(); + explicit AndroidNetworkMonitor(JNIEnv* env); // TODO(sakal): Remove once down stream dependencies have been updated. static void SetAndroidContext(JNIEnv* jni, jobject context) {} @@ -69,15 +69,22 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase, // Always expected to be called on the network thread. void SetNetworkInfos(const std::vector& network_infos); - private: - static jobject application_context_; - static int android_sdk_int_; - JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); } + 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: void OnNetworkConnected_w(const NetworkInformation& network_info); void OnNetworkDisconnected_w(NetworkHandle network_handle); - ScopedGlobalRef j_network_monitor_class_; + const int android_sdk_int_; ScopedGlobalRef j_network_monitor_; rtc::ThreadChecker thread_checker_; bool started_ = false;