From 82f96e6a56e6230e98ee70de5178d7de69795c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20Kalliom=C3=A4ki?= Date: Mon, 29 Jan 2018 13:18:57 +0100 Subject: [PATCH] Create an experimental Android NDK. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following files were split: sdk/android/native_api/jni_helpers.h -> sdk/android/native_api/jni/java_types.h sdk/android/native_api/jni_helpers.cc -> sdk/android/native_api/jni/java_types.cc Skipping presubmit to avoid changing moved code. Bug: webrtc:8769 Change-Id: I0ef0f6b297b5002322915660d26cca33e91ff05b No-Presubmit: true Reviewed-on: https://webrtc-review.googlesource.com/40800 Commit-Queue: Sami Kalliomäki Reviewed-by: Rasmus Brandt Reviewed-by: Anders Carlsson Cr-Commit-Position: refs/heads/master@{#21799} --- modules/video_coding/BUILD.gn | 4 +- .../codecs/test/android_test_initializer.cc | 8 +- .../test/videoprocessor_integrationtest.cc | 31 +- sdk/android/BUILD.gn | 128 ++++++- sdk/android/native_api/base/init.cc | 24 ++ sdk/android/native_api/base/init.h | 23 ++ sdk/android/native_api/codecs/wrapper.cc | 33 ++ sdk/android/native_api/codecs/wrapper.h | 36 ++ .../{src => native_api}/jni/class_loader.cc | 10 +- sdk/android/native_api/jni/class_loader.h | 40 ++ sdk/android/native_api/jni/java_types.cc | 259 +++++++++++++ sdk/android/native_api/jni/java_types.h | 253 +++++++++++++ sdk/android/native_api/jni/jvm.cc | 21 ++ sdk/android/native_api/jni/jvm.h | 21 ++ .../{src => native_api}/jni/scoped_java_ref.h | 11 +- sdk/android/src/jni/androidhistogram.cc | 1 + sdk/android/src/jni/androidmediadecoder.cc | 1 + sdk/android/src/jni/androidmediaencoder.cc | 1 + sdk/android/src/jni/androidmetrics.cc | 1 + sdk/android/src/jni/class_loader.h | 24 +- sdk/android/src/jni/classreferenceholder.h | 4 +- sdk/android/src/jni/encodedimage.cc | 1 + sdk/android/src/jni/encodedimage.h | 2 +- .../src/jni/hardwarevideoencoderfactory.cc | 1 + sdk/android/src/jni/jni_generator_helper.cc | 5 +- sdk/android/src/jni/jni_generator_helper.h | 8 +- sdk/android/src/jni/jni_helpers.cc | 351 +----------------- sdk/android/src/jni/jni_helpers.h | 243 +----------- sdk/android/src/jni/jvm.cc | 133 +++++++ sdk/android/src/jni/jvm.h | 32 ++ .../src/jni/pc/androidnetworkmonitor.cc | 1 + .../jni/pc/callsessionfilerotatinglogsink.cc | 1 + sdk/android/src/jni/pc/datachannel.cc | 1 + sdk/android/src/jni/pc/dtmfsender.cc | 1 + sdk/android/src/jni/pc/icecandidate.cc | 1 + sdk/android/src/jni/pc/logging.cc | 1 + sdk/android/src/jni/pc/mediaconstraints.cc | 1 + sdk/android/src/jni/pc/mediaconstraints.h | 2 +- sdk/android/src/jni/pc/mediastream.cc | 1 + sdk/android/src/jni/pc/mediastreamtrack.cc | 1 + sdk/android/src/jni/pc/mediastreamtrack.h | 2 +- sdk/android/src/jni/pc/peerconnection.cc | 1 + .../src/jni/pc/peerconnectionfactory.cc | 1 + .../pc/rtcstatscollectorcallbackwrapper.cc | 1 + sdk/android/src/jni/pc/rtpparameters.cc | 1 + sdk/android/src/jni/pc/rtpparameters.h | 2 +- sdk/android/src/jni/pc/rtpreceiver.cc | 1 + sdk/android/src/jni/pc/rtpreceiver.h | 2 +- sdk/android/src/jni/pc/rtpsender.cc | 1 + sdk/android/src/jni/pc/rtpsender.h | 2 +- sdk/android/src/jni/pc/sdpobserver.cc | 1 + sdk/android/src/jni/pc/sessiondescription.cc | 1 + sdk/android/src/jni/pc/sessiondescription.h | 2 +- sdk/android/src/jni/pc/statsobserver.cc | 1 + sdk/android/src/jni/pc/turncustomizer.cc | 1 + sdk/android/src/jni/pc/turncustomizer.h | 2 +- sdk/android/src/jni/pc/video.cc | 1 - sdk/android/src/jni/pc/video.h | 2 +- sdk/android/src/jni/surfacetexturehelper.cc | 1 + sdk/android/src/jni/videocodecinfo.cc | 1 + sdk/android/src/jni/videocodecstatus.h | 2 +- .../src/jni/videodecoderfactorywrapper.cc | 1 + sdk/android/src/jni/videodecoderwrapper.cc | 1 + .../src/jni/videoencoderfactorywrapper.cc | 3 +- sdk/android/src/jni/videoencoderwrapper.cc | 3 +- sdk/android/src/jni/videoframe.h | 3 + .../src/jni/wrapped_native_i420_buffer.h | 2 +- sdk/android/src/jni/wrappednativecodec.cc | 2 +- sdk/android/src/jni/wrappednativecodec.h | 2 +- 69 files changed, 1091 insertions(+), 676 deletions(-) create mode 100644 sdk/android/native_api/base/init.cc create mode 100644 sdk/android/native_api/base/init.h create mode 100644 sdk/android/native_api/codecs/wrapper.cc create mode 100644 sdk/android/native_api/codecs/wrapper.h rename sdk/android/{src => native_api}/jni/class_loader.cc (91%) create mode 100644 sdk/android/native_api/jni/class_loader.h create mode 100644 sdk/android/native_api/jni/java_types.cc create mode 100644 sdk/android/native_api/jni/java_types.h create mode 100644 sdk/android/native_api/jni/jvm.cc create mode 100644 sdk/android/native_api/jni/jvm.h rename sdk/android/{src => native_api}/jni/scoped_java_ref.h (96%) create mode 100644 sdk/android/src/jni/jvm.cc create mode 100644 sdk/android/src/jni/jvm.h diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index c467ea9ca2..a588bc6a33 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -598,7 +598,9 @@ if (rtc_include_tests) { ] deps += [ - "../../sdk/android:libjingle_peerconnection_jni", + "../../sdk/android:native_api_base", + "../../sdk/android:native_api_codecs", + "../../sdk/android:native_api_jni", "//base", ] } diff --git a/modules/video_coding/codecs/test/android_test_initializer.cc b/modules/video_coding/codecs/test/android_test_initializer.cc index 43cf22aceb..04a5f54395 100644 --- a/modules/video_coding/codecs/test/android_test_initializer.cc +++ b/modules/video_coding/codecs/test/android_test_initializer.cc @@ -12,8 +12,7 @@ #include "modules/video_coding/codecs/test/android_test_initializer.h" #include "rtc_base/ignore_wundef.h" -#include "sdk/android/src/jni/classreferenceholder.h" -#include "sdk/android/src/jni/jni_helpers.h" +#include "sdk/android/native_api/base/init.h" // Note: this dependency is dangerous since it reaches into Chromium's base. // There's a risk of e.g. macro clashes. This file may only be used in tests. @@ -40,10 +39,7 @@ void EnsureInitializedOnce() { JavaVM* jvm = NULL; RTC_CHECK_EQ(0, jni->GetJavaVM(&jvm)); - jint ret = jni::InitGlobalJniVariables(jvm); - RTC_DCHECK_GE(ret, 0); - - jni::LoadGlobalClassReferenceHolder(); + InitAndroid(jvm); } } // namespace diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index 2d92a50fcc..3673618cb2 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -15,9 +15,10 @@ #if defined(WEBRTC_ANDROID) #include "modules/video_coding/codecs/test/android_test_initializer.h" -#include "sdk/android/src/jni/class_loader.h" -#include "sdk/android/src/jni/videodecoderfactorywrapper.h" -#include "sdk/android/src/jni/videoencoderfactorywrapper.h" +#include "sdk/android/native_api/codecs/wrapper.h" +#include "sdk/android/native_api/jni/class_loader.h" +#include "sdk/android/native_api/jni/jvm.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" #elif defined(WEBRTC_IOS) #include "modules/video_coding/codecs/test/objc_codec_h264_test.h" #endif @@ -375,18 +376,18 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() { std::unique_ptr encoder_factory; if (config_.hw_encoder) { #if defined(WEBRTC_ANDROID) - JNIEnv* env = jni::AttachCurrentThreadIfNeeded(); - jni::ScopedJavaLocalRef factory_class = - jni::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory"); + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef factory_class = + GetClass(env, "org/webrtc/HardwareVideoEncoderFactory"); jmethodID factory_constructor = env->GetMethodID( factory_class.obj(), "", "(Lorg/webrtc/EglBase$Context;ZZ)V"); - jni::ScopedJavaLocalRef factory_object( + ScopedJavaLocalRef factory_object( env, env->NewObject(factory_class.obj(), factory_constructor, nullptr /* shared_context */, false /* enable_intel_vp8_encoder */, true /* enable_h264_high_profile */)); - encoder_factory = rtc::MakeUnique( - env, factory_object); + encoder_factory = + JavaToNativeVideoEncoderFactory(env, factory_object.obj()); #elif defined(WEBRTC_IOS) EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType) << "iOS HW codecs only support H264."; @@ -401,16 +402,16 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() { std::unique_ptr decoder_factory; if (config_.hw_decoder) { #if defined(WEBRTC_ANDROID) - JNIEnv* env = jni::AttachCurrentThreadIfNeeded(); - jni::ScopedJavaLocalRef factory_class = - jni::GetClass(env, "org/webrtc/HardwareVideoDecoderFactory"); + JNIEnv* env = AttachCurrentThreadIfNeeded(); + ScopedJavaLocalRef factory_class = + GetClass(env, "org/webrtc/HardwareVideoDecoderFactory"); jmethodID factory_constructor = env->GetMethodID( factory_class.obj(), "", "(Lorg/webrtc/EglBase$Context;)V"); - jni::ScopedJavaLocalRef factory_object( + ScopedJavaLocalRef factory_object( env, env->NewObject(factory_class.obj(), factory_constructor, nullptr /* shared_context */)); - decoder_factory = rtc::MakeUnique( - env, factory_object); + decoder_factory = + JavaToNativeVideoDecoderFactory(env, factory_object.obj()); #elif defined(WEBRTC_IOS) EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType) << "iOS HW codecs only support H264."; diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index d3dd583555..7d624f7225 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -17,6 +17,7 @@ group("android") { ":libjingle_peerconnection_jni", ":libjingle_peerconnection_so", ":libwebrtc", + ":native_api", ] } } @@ -37,8 +38,6 @@ generate_jni("generated_base_jni") { sources = [ "src/java/org/webrtc/Histogram.java", "src/java/org/webrtc/JniCommon.java", - "src/java/org/webrtc/JniHelper.java", - "src/java/org/webrtc/WebRtcClassLoader.java", ] jni_package = "" jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" @@ -62,27 +61,46 @@ generate_jar_jni("generated_external_classes_jni") { jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" } +# Internal code that is needed by native_api_jni. The code cannot be placed in +# base_jni because native_api_jni depends on the code (and base_jni depends on +# native_api_jni). +rtc_source_set("internal_jni") { + sources = [ + "src/jni/jvm.cc", + "src/jni/jvm.h", + ] + + deps = [ + "../../rtc_base:checks", + ] + + if (is_clang) { + # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163). + suppressed_configs += [ + "//build/config/clang:extra_warnings", + "//build/config/clang:find_bad_constructs", + ] + } +} + rtc_source_set("base_jni") { visibility = [ "*" ] sources = [ "src/jni/androidhistogram.cc", - "src/jni/class_loader.cc", "src/jni/class_loader.h", "src/jni/classreferenceholder.h", "src/jni/jni_common.cc", - "src/jni/jni_generator_helper.cc", - "src/jni/jni_generator_helper.h", "src/jni/jni_helpers.cc", "src/jni/jni_helpers.h", "src/jni/pc/audio.h", "src/jni/pc/media.h", "src/jni/pc/video.h", - "src/jni/scoped_java_ref.h", ] deps = [ ":generated_base_jni", - ":generated_external_classes_jni", + ":internal_jni", + ":native_api_jni", "../../api:libjingle_peerconnection_api", "../../api:optional", "../../rtc_base:checks", @@ -231,7 +249,7 @@ rtc_static_library("video_jni") { deps = [ ":base_jni", ":generated_video_jni", - ":peerconnection_jni", + ":native_api_jni", "../..:webrtc_common", "../../api:libjingle_peerconnection_api", "../../api:video_frame_api", @@ -415,6 +433,7 @@ rtc_static_library("peerconnection_jni") { ":base_jni", ":generated_external_classes_jni", ":generated_peerconnection_jni", + ":native_api_jni", "../..:webrtc_common", "../../api:libjingle_peerconnection_api", "../../api:peerconnection_and_implicit_call_api", @@ -464,6 +483,7 @@ rtc_static_library("libjingle_peerconnection_metrics_default_jni") { deps = [ ":base_jni", ":generated_metrics_jni", + ":native_api_jni", ":peerconnection_jni", "../../pc:peerconnection", "../../system_wrappers:field_trial_default", @@ -706,3 +726,95 @@ if (rtc_include_tests) { shared_libraries = [ "../../sdk/android:libjingle_peerconnection_so" ] } } + +# The native API is currently experimental and may change without notice. +group("native_api") { + deps = [ + ":native_api_base", + ":native_api_codecs", + ":native_api_jni", + ] +} + +rtc_static_library("native_api_base") { + visibility = [ "*" ] + sources = [ + "native_api/base/init.cc", + "native_api/base/init.h", + ] + + deps = [ + ":base_jni", + ":native_api_jni", + "//rtc_base:checks", + "//rtc_base:rtc_base", + ] +} + +generate_jni("generated_native_api_jni") { + sources = [ + "src/java/org/webrtc/JniHelper.java", + "src/java/org/webrtc/WebRtcClassLoader.java", + ] + jni_package = "" + jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h" +} + +# JNI helpers that are also needed from internal JNI code. Cannot depend on any +# other JNI targets than internal_jni. +rtc_static_library("native_api_jni") { + visibility = [ "*" ] + sources = [ + "native_api/jni/class_loader.cc", + "native_api/jni/class_loader.h", + "native_api/jni/java_types.cc", + "native_api/jni/java_types.h", + "native_api/jni/jvm.cc", + "native_api/jni/jvm.h", + "native_api/jni/scoped_java_ref.h", + "src/jni/jni_generator_helper.cc", + "src/jni/jni_generator_helper.h", + ] + + public = [ + "native_api/jni/class_loader.h", + "native_api/jni/java_types.h", + "native_api/jni/jvm.h", + "native_api/jni/scoped_java_ref.h", + ] + + deps = [ + ":generated_external_classes_jni", + ":generated_native_api_jni", + ":internal_jni", + "//api:optional", + "//rtc_base:checks", + "//rtc_base:rtc_base_approved", + ] +} + +# API for wrapping Java VideoDecoderFactory/VideoEncoderFactory classes to C++ +# objects. +rtc_static_library("native_api_codecs") { + visibility = [ "*" ] + sources = [ + "native_api/codecs/wrapper.cc", + "native_api/codecs/wrapper.h", + ] + + if (is_clang) { + # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163). + suppressed_configs += [ + "//build/config/clang:extra_warnings", + "//build/config/clang:find_bad_constructs", + ] + } + + deps = [ + ":base_jni", + ":video_jni", + "//api/video_codecs:video_codecs_api", + "//rtc_base:checks", + "//rtc_base:rtc_base_approved", + ] +} diff --git a/sdk/android/native_api/base/init.cc b/sdk/android/native_api/base/init.cc new file mode 100644 index 0000000000..176aa89ece --- /dev/null +++ b/sdk/android/native_api/base/init.cc @@ -0,0 +1,24 @@ +/* + * Copyright 2018 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/native_api/base/init.h" + +#include "rtc_base/checks.h" +#include "sdk/android/native_api/jni/class_loader.h" +#include "sdk/android/src/jni/jni_helpers.h" + +namespace webrtc { + +void InitAndroid(JavaVM* jvm) { + RTC_CHECK_GE(jni::InitGlobalJniVariables(jvm), 0); + InitClassLoader(jni::GetEnv()); +} + +} // namespace webrtc diff --git a/sdk/android/native_api/base/init.h b/sdk/android/native_api/base/init.h new file mode 100644 index 0000000000..d6a0ec1509 --- /dev/null +++ b/sdk/android/native_api/base/init.h @@ -0,0 +1,23 @@ +/* + * Copyright 2018 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_NATIVE_API_BASE_INIT_H_ +#define SDK_ANDROID_NATIVE_API_BASE_INIT_H_ + +#include + +namespace webrtc { + +// Initializes global state needed by WebRTC Android NDK. +void InitAndroid(JavaVM* jvm); + +} // namespace webrtc + +#endif // SDK_ANDROID_NATIVE_API_BASE_INIT_H_ diff --git a/sdk/android/native_api/codecs/wrapper.cc b/sdk/android/native_api/codecs/wrapper.cc new file mode 100644 index 0000000000..d7ff44d670 --- /dev/null +++ b/sdk/android/native_api/codecs/wrapper.cc @@ -0,0 +1,33 @@ +/* + * Copyright 2018 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/native_api/codecs/wrapper.h" + +#include "rtc_base/ptr_util.h" +#include "sdk/android/src/jni/videodecoderfactorywrapper.h" +#include "sdk/android/src/jni/videoencoderfactorywrapper.h" + +namespace webrtc { + +std::unique_ptr JavaToNativeVideoDecoderFactory( + JNIEnv* jni, + jobject decoder_factory) { + return rtc::MakeUnique( + jni, JavaParamRef(decoder_factory)); +} + +std::unique_ptr JavaToNativeVideoEncoderFactory( + JNIEnv* jni, + jobject en) { + return rtc::MakeUnique( + jni, JavaParamRef(en)); +} + +} // namespace webrtc diff --git a/sdk/android/native_api/codecs/wrapper.h b/sdk/android/native_api/codecs/wrapper.h new file mode 100644 index 0000000000..b13f2700be --- /dev/null +++ b/sdk/android/native_api/codecs/wrapper.h @@ -0,0 +1,36 @@ +/* + * Copyright 2018 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_NATIVE_API_CODECS_WRAPPER_H_ +#define SDK_ANDROID_NATIVE_API_CODECS_WRAPPER_H_ + +#include +#include + +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" + +namespace webrtc { + +// Creates an instance of webrtc::VideoDecoderFactory from Java +// VideoDecoderFactory. +std::unique_ptr JavaToNativeVideoDecoderFactory( + JNIEnv* jni, + jobject decoder_factory); + +// Creates an instance of webrtc::VideoEncoderFactory from Java +// VideoEncoderFactory. +std::unique_ptr JavaToNativeVideoEncoderFactory( + JNIEnv* jni, + jobject encoder_factory); + +} // namespace webrtc + +#endif // SDK_ANDROID_NATIVE_API_CODECS_WRAPPER_H_ diff --git a/sdk/android/src/jni/class_loader.cc b/sdk/android/native_api/jni/class_loader.cc similarity index 91% rename from sdk/android/src/jni/class_loader.cc rename to sdk/android/native_api/jni/class_loader.cc index d02318aa82..0b5a87fbb3 100644 --- a/sdk/android/src/jni/class_loader.cc +++ b/sdk/android/native_api/jni/class_loader.cc @@ -8,15 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "sdk/android/src/jni/class_loader.h" +#include "sdk/android/native_api/jni/class_loader.h" #include #include #include "rtc_base/checks.h" -#include "sdk/android/generated_base_jni/jni/WebRtcClassLoader_jni.h" -#include "sdk/android/src/jni/jni_helpers.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/generated_native_api_jni/jni/WebRtcClassLoader_jni.h" +#include "sdk/android/native_api/jni/java_types.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" // Abort the process if |jni| has a Java exception pending. This macros uses the // comma operator to execute ExceptionDescribe and ExceptionClear ignoring their @@ -26,7 +26,6 @@ << (jni->ExceptionDescribe(), jni->ExceptionClear(), "") namespace webrtc { -namespace jni { namespace { @@ -78,5 +77,4 @@ ScopedJavaLocalRef GetClass(JNIEnv* env, const char* name) { : g_class_loader->FindClass(env, name); } -} // namespace jni } // namespace webrtc diff --git a/sdk/android/native_api/jni/class_loader.h b/sdk/android/native_api/jni/class_loader.h new file mode 100644 index 0000000000..2d102fe4a2 --- /dev/null +++ b/sdk/android/native_api/jni/class_loader.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +// Android's FindClass() is tricky because the app-specific ClassLoader is not +// consulted when there is no app-specific frame on the stack (i.e. when called +// from a thread created from native C++ code). These helper functions provide a +// workaround for this. +// http://developer.android.com/training/articles/perf-jni.html#faq_FindClass + +#ifndef SDK_ANDROID_NATIVE_API_JNI_CLASS_LOADER_H_ +#define SDK_ANDROID_NATIVE_API_JNI_CLASS_LOADER_H_ + +#include + +#include "sdk/android/native_api/jni/scoped_java_ref.h" + +namespace webrtc { + +// This method should be called from JNI_OnLoad and before any calls to +// FindClass. This is normally called by InitAndroid. +void InitClassLoader(JNIEnv* env); + +// This function is identical to JNIEnv::FindClass except that it works from any +// thread. This function loads and returns a local reference to the class with +// the given name. The name argument is a fully-qualified class name. For +// example, the fully-qualified class name for the java.lang.String class is: +// "java/lang/String". This function will be used from the JNI generated code +// and should rarely be used manually. +ScopedJavaLocalRef GetClass(JNIEnv* env, const char* name); + +} // namespace webrtc + +#endif // SDK_ANDROID_NATIVE_API_JNI_CLASS_LOADER_H_ diff --git a/sdk/android/native_api/jni/java_types.cc b/sdk/android/native_api/jni/java_types.cc new file mode 100644 index 0000000000..74d1ddb3bc --- /dev/null +++ b/sdk/android/native_api/jni/java_types.cc @@ -0,0 +1,259 @@ +/* + * Copyright 2015 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/native_api/jni/java_types.h" + +#include +#include + +#include "sdk/android/generated_external_classes_jni/jni/ArrayList_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Boolean_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Double_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Enum_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Integer_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Iterable_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Iterator_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/LinkedHashMap_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Long_jni.h" +#include "sdk/android/generated_external_classes_jni/jni/Map_jni.h" +#include "sdk/android/generated_native_api_jni/jni/JniHelper_jni.h" + +namespace webrtc { + +bool IsNull(JNIEnv* jni, const JavaRef& obj) { + return jni->IsSameObject(obj.obj(), nullptr); +} + +// Given a jstring, reinterprets it to a new native string. +std::string JavaToStdString(JNIEnv* jni, const JavaRef& j_string) { + const ScopedJavaLocalRef j_byte_array = + Java_JniHelper_getStringBytes(jni, j_string); + + const size_t len = jni->GetArrayLength(j_byte_array.obj()); + CHECK_EXCEPTION(jni) << "error during GetArrayLength"; + std::string str(len, '\0'); + jni->GetByteArrayRegion(j_byte_array.obj(), 0, len, + reinterpret_cast(&str[0])); + CHECK_EXCEPTION(jni) << "error during GetByteArrayRegion"; + return str; +} + +// Given a list of jstrings, reinterprets it to a new vector of native strings. +std::vector JavaToStdVectorStrings(JNIEnv* jni, + const JavaRef& list) { + std::vector converted_list; + if (!list.is_null()) { + for (const JavaRef& str : Iterable(jni, list)) { + converted_list.push_back(JavaToStdString( + jni, JavaParamRef(static_cast(str.obj())))); + } + } + return converted_list; +} + +rtc::Optional JavaToNativeOptionalInt( + JNIEnv* jni, + const JavaRef& integer) { + if (IsNull(jni, integer)) + return rtc::nullopt; + return JNI_Integer::Java_Integer_intValue(jni, integer); +} + +rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, + const JavaRef& boolean) { + if (IsNull(jni, boolean)) + return rtc::nullopt; + return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean); +} + +int64_t JavaToNativeLong(JNIEnv* env, const JavaRef& j_long) { + return JNI_Long::Java_Long_longValue(env, j_long); +} + +ScopedJavaLocalRef NativeToJavaBoolean(JNIEnv* env, bool b) { + return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b); +} + +ScopedJavaLocalRef NativeToJavaInteger(JNIEnv* jni, int32_t i) { + return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i); +} + +ScopedJavaLocalRef NativeToJavaLong(JNIEnv* env, int64_t u) { + return JNI_Long::Java_Long_ConstructorJLLO_J(env, u); +} + +ScopedJavaLocalRef NativeToJavaDouble(JNIEnv* env, double d) { + return JNI_Double::Java_Double_ConstructorJLD_D(env, d); +} + +ScopedJavaLocalRef NativeToJavaString(JNIEnv* env, const char* str) { + jstring j_str = env->NewStringUTF(str); + CHECK_EXCEPTION(env) << "error during NewStringUTF"; + return ScopedJavaLocalRef(env, j_str); +} + +ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, + const std::string& str) { + return NativeToJavaString(jni, str.c_str()); +} + +ScopedJavaLocalRef NativeToJavaInteger( + JNIEnv* jni, + const rtc::Optional& optional_int) { + return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr; +} + +std::string GetJavaEnumName(JNIEnv* jni, const JavaRef& j_enum) { + return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum)); +} + +std::map JavaToStdMapStrings( + JNIEnv* jni, + const JavaRef& j_map) { + const JavaRef& j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map); + std::map result; + for (const JavaRef& j_entry : Iterable(jni, j_entry_set)) { + result.insert(std::make_pair( + JavaToStdString(jni, Java_JniHelper_getKey(jni, j_entry)), + JavaToStdString(jni, Java_JniHelper_getValue(jni, j_entry)))); + } + + return result; +} + +Iterable::Iterable(JNIEnv* jni, const JavaRef& iterable) + : jni_(jni), iterable_(jni, iterable) {} + +Iterable::~Iterable() = default; + +// Creates an iterator representing the end of any collection. +Iterable::Iterator::Iterator() = default; + +// Creates an iterator pointing to the beginning of the specified collection. +Iterable::Iterator::Iterator(JNIEnv* jni, const JavaRef& iterable) + : jni_(jni) { + iterator_ = JNI_Iterable::Java_Iterable_iterator(jni, iterable); + RTC_CHECK(!iterator_.is_null()); + // Start at the first element in the collection. + ++(*this); +} + +// Move constructor - necessary to be able to return iterator types from +// functions. +Iterable::Iterator::Iterator(Iterator&& other) + : jni_(std::move(other.jni_)), + iterator_(std::move(other.iterator_)), + value_(std::move(other.value_)), + thread_checker_(std::move(other.thread_checker_)) {} + +Iterable::Iterator::~Iterator() = default; + +// Advances the iterator one step. +Iterable::Iterator& Iterable::Iterator::operator++() { + RTC_CHECK(thread_checker_.CalledOnValidThread()); + if (AtEnd()) { + // Can't move past the end. + return *this; + } + bool has_next = JNI_Iterator::Java_Iterator_hasNext(jni_, iterator_); + if (!has_next) { + iterator_ = nullptr; + value_ = nullptr; + return *this; + } + + value_ = JNI_Iterator::Java_Iterator_next(jni_, iterator_); + return *this; +} + +void Iterable::Iterator::Remove() { + JNI_Iterator::Java_Iterator_remove(jni_, iterator_); +} + +// Provides a way to compare the iterator with itself and with the end iterator. +// Note: all other comparison results are undefined, just like for C++ input +// iterators. +bool Iterable::Iterator::operator==(const Iterable::Iterator& other) { + // Two different active iterators should never be compared. + RTC_DCHECK(this == &other || AtEnd() || other.AtEnd()); + return AtEnd() == other.AtEnd(); +} + +ScopedJavaLocalRef& Iterable::Iterator::operator*() { + RTC_CHECK(!AtEnd()); + return value_; +} + +bool Iterable::Iterator::AtEnd() const { + RTC_CHECK(thread_checker_.CalledOnValidThread()); + return jni_ == nullptr || IsNull(jni_, iterator_); +} + +ScopedJavaLocalRef NativeToJavaIntegerArray( + JNIEnv* env, + const std::vector& container) { + ScopedJavaLocalRef (*convert_function)(JNIEnv*, int32_t) = + &NativeToJavaInteger; + return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env), + convert_function); +} + +ScopedJavaLocalRef NativeToJavaBooleanArray( + JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env), + &NativeToJavaBoolean); +} + +ScopedJavaLocalRef NativeToJavaDoubleArray( + JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env), + &NativeToJavaDouble); +} + +ScopedJavaLocalRef NativeToJavaLongArray( + JNIEnv* env, + const std::vector& container) { + return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env), + &NativeToJavaLong); +} + +ScopedJavaLocalRef NativeToJavaStringArray( + JNIEnv* env, + const std::vector& container) { + ScopedJavaLocalRef (*convert)(JNIEnv*, const std::string&) = + &NativeToJavaString; + return NativeToJavaObjectArray( + env, container, + static_cast(Java_JniHelper_getStringClass(env).obj()), convert); +} + +JavaMapBuilder::JavaMapBuilder(JNIEnv* env) + : env_(env), + j_map_(JNI_LinkedHashMap::Java_LinkedHashMap_ConstructorJULIHM(env)) {} + +JavaMapBuilder::~JavaMapBuilder() = default; + +void JavaMapBuilder::put(const JavaRef& key, + const JavaRef& value) { + JNI_Map::Java_Map_put(env_, j_map_, key, value); +} + +JavaListBuilder::JavaListBuilder(JNIEnv* env) + : env_(env), j_list_(JNI_ArrayList::Java_ArrayList_ConstructorJUALI(env)) {} + +JavaListBuilder::~JavaListBuilder() = default; + +void JavaListBuilder::add(const JavaRef& element) { + JNI_ArrayList::Java_ArrayList_addZ_JUE(env_, j_list_, element); +} + +} // namespace webrtc diff --git a/sdk/android/native_api/jni/java_types.h b/sdk/android/native_api/jni/java_types.h new file mode 100644 index 0000000000..bd9e70008f --- /dev/null +++ b/sdk/android/native_api/jni/java_types.h @@ -0,0 +1,253 @@ +/* + * Copyright 2015 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. + */ + +// Android's FindClass() is tricky because the app-specific ClassLoader is not +// consulted when there is no app-specific frame on the stack (i.e. when called +// from a thread created from native C++ code). These helper functions provide a +// workaround for this. +// http://developer.android.com/training/articles/perf-jni.html#faq_FindClass + +#ifndef SDK_ANDROID_NATIVE_API_JNI_JAVA_TYPES_H_ +#define SDK_ANDROID_NATIVE_API_JNI_JAVA_TYPES_H_ + +#include +#include +#include +#include + +#include "api/optional.h" +#include "rtc_base/checks.h" +#include "rtc_base/thread_checker.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" + +// Abort the process if |jni| has a Java exception pending. +// This macros uses the comma operator to execute ExceptionDescribe +// and ExceptionClear ignoring their return values and sending "" +// to the error stream. +#define CHECK_EXCEPTION(jni) \ + RTC_CHECK(!jni->ExceptionCheck()) \ + << (jni->ExceptionDescribe(), jni->ExceptionClear(), "") + +namespace webrtc { + +// Returns true if |obj| == null in Java. +bool IsNull(JNIEnv* jni, const JavaRef& obj); + +// Given a (UTF-16) jstring return a new UTF-8 native string. +std::string JavaToStdString(JNIEnv* jni, const JavaRef& j_string); + +// Deprecated. Use scoped jobjects instead. +inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) { + return JavaToStdString(jni, JavaParamRef(j_string)); +} + +// Given a List of (UTF-16) jstrings +// return a new vector of UTF-8 native strings. +std::vector JavaToStdVectorStrings(JNIEnv* jni, + const JavaRef& list); + +rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, + const JavaRef& integer); +rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, + const JavaRef& boolean); +int64_t JavaToNativeLong(JNIEnv* env, const JavaRef& j_long); + +ScopedJavaLocalRef NativeToJavaBoolean(JNIEnv* env, bool b); +ScopedJavaLocalRef NativeToJavaInteger(JNIEnv* jni, int32_t i); +ScopedJavaLocalRef NativeToJavaLong(JNIEnv* env, int64_t u); +ScopedJavaLocalRef NativeToJavaDouble(JNIEnv* env, double d); +ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, const char* str); +ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, + const std::string& str); +ScopedJavaLocalRef NativeToJavaInteger( + JNIEnv* jni, + const rtc::Optional& optional_int); + +// Parses Map to std::map. +std::map JavaToStdMapStrings( + JNIEnv* jni, + const JavaRef& j_map); + +// Deprecated. Use scoped jobjects instead. +inline std::map JavaToStdMapStrings(JNIEnv* jni, + jobject j_map) { + return JavaToStdMapStrings(jni, JavaParamRef(j_map)); +} + +// Returns the name of a Java enum. +std::string GetJavaEnumName(JNIEnv* jni, const JavaRef& j_enum); + +// Provides a convenient way to iterate over a Java Iterable using the +// C++ range-for loop. +// E.g. for (jobject value : Iterable(jni, j_iterable)) { ... } +// Note: Since Java iterators cannot be duplicated, the iterator class is not +// copyable to prevent creating multiple C++ iterators that refer to the same +// Java iterator. +class Iterable { + public: + Iterable(JNIEnv* jni, const JavaRef& iterable); + ~Iterable(); + + class Iterator { + public: + // Creates an iterator representing the end of any collection. + Iterator(); + // Creates an iterator pointing to the beginning of the specified + // collection. + Iterator(JNIEnv* jni, const JavaRef& iterable); + + // Move constructor - necessary to be able to return iterator types from + // functions. + Iterator(Iterator&& other); + + ~Iterator(); + + // Move assignment should not be used. + Iterator& operator=(Iterator&&) = delete; + + // Advances the iterator one step. + Iterator& operator++(); + + // Removes the element the iterator is pointing to. Must still advance the + // iterator afterwards. + void Remove(); + + // Provides a way to compare the iterator with itself and with the end + // iterator. + // Note: all other comparison results are undefined, just like for C++ input + // iterators. + bool operator==(const Iterator& other); + bool operator!=(const Iterator& other) { return !(*this == other); } + ScopedJavaLocalRef& operator*(); + + private: + bool AtEnd() const; + + JNIEnv* jni_ = nullptr; + ScopedJavaLocalRef iterator_; + ScopedJavaLocalRef value_; + rtc::ThreadChecker thread_checker_; + + RTC_DISALLOW_COPY_AND_ASSIGN(Iterator); + }; + + Iterable::Iterator begin() { return Iterable::Iterator(jni_, iterable_); } + Iterable::Iterator end() { return Iterable::Iterator(); } + + private: + JNIEnv* jni_; + ScopedJavaLocalRef iterable_; + + RTC_DISALLOW_COPY_AND_ASSIGN(Iterable); +}; + +// Helper function for converting std::vector into a Java array. +template +ScopedJavaLocalRef NativeToJavaObjectArray( + JNIEnv* env, + const std::vector& container, + jclass clazz, + Convert convert) { + ScopedJavaLocalRef j_container( + env, env->NewObjectArray(container.size(), clazz, nullptr)); + int i = 0; + for (const T& element : container) { + env->SetObjectArrayElement(j_container.obj(), i, + convert(env, element).obj()); + ++i; + } + return j_container; +} + +ScopedJavaLocalRef NativeToJavaIntegerArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaBooleanArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaLongArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaDoubleArray( + JNIEnv* env, + const std::vector& container); +ScopedJavaLocalRef NativeToJavaStringArray( + JNIEnv* env, + const std::vector& container); + +template +std::vector JavaToNativeVector(JNIEnv* env, + const JavaRef& j_container, + Convert convert) { + std::vector container; + const size_t size = env->GetArrayLength(j_container.obj()); + container.reserve(size); + for (size_t i = 0; i < size; ++i) { + container.emplace_back(convert( + env, ScopedJavaLocalRef( + env, env->GetObjectArrayElement(j_container.obj(), i)))); + } + CHECK_EXCEPTION(env) << "Error during JavaToNativeVector"; + return container; +} + +// This is a helper class for NativeToJavaList(). Use that function instead of +// using this class directly. +class JavaListBuilder { + public: + explicit JavaListBuilder(JNIEnv* env); + ~JavaListBuilder(); + void add(const JavaRef& element); + ScopedJavaLocalRef java_list() { return j_list_; } + + private: + JNIEnv* env_; + ScopedJavaLocalRef j_list_; +}; + +template +ScopedJavaLocalRef NativeToJavaList(JNIEnv* env, + const C& container, + Convert convert) { + JavaListBuilder builder(env); + for (const auto& e : container) + builder.add(convert(env, e)); + return builder.java_list(); +} + +// This is a helper class for NativeToJavaMap(). Use that function instead of +// using this class directly. +class JavaMapBuilder { + public: + explicit JavaMapBuilder(JNIEnv* env); + ~JavaMapBuilder(); + void put(const JavaRef& key, const JavaRef& value); + ScopedJavaLocalRef GetJavaMap() { return j_map_; } + + private: + JNIEnv* env_; + ScopedJavaLocalRef j_map_; +}; + +template +ScopedJavaLocalRef NativeToJavaMap(JNIEnv* env, + const C& container, + Convert convert) { + JavaMapBuilder builder(env); + for (const auto& e : container) { + const auto key_value_pair = convert(env, e); + builder.put(key_value_pair.first, key_value_pair.second); + } + return builder.GetJavaMap(); +} + +} // namespace webrtc + +#endif // SDK_ANDROID_NATIVE_API_JNI_JAVA_TYPES_H_ diff --git a/sdk/android/native_api/jni/jvm.cc b/sdk/android/native_api/jni/jvm.cc new file mode 100644 index 0000000000..3356cbeb6f --- /dev/null +++ b/sdk/android/native_api/jni/jvm.cc @@ -0,0 +1,21 @@ +/* + * Copyright 2018 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/native_api/jni/jvm.h" + +#include "sdk/android/src/jni/jvm.h" + +namespace webrtc { + +JNIEnv* AttachCurrentThreadIfNeeded() { + return jni::AttachCurrentThreadIfNeeded(); +} + +} // namespace webrtc diff --git a/sdk/android/native_api/jni/jvm.h b/sdk/android/native_api/jni/jvm.h new file mode 100644 index 0000000000..00bce6734d --- /dev/null +++ b/sdk/android/native_api/jni/jvm.h @@ -0,0 +1,21 @@ +/* + * Copyright 2018 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_NATIVE_API_JNI_JVM_H_ +#define SDK_ANDROID_NATIVE_API_JNI_JVM_H_ + +#include + +namespace webrtc { +// Returns a JNI environment usable on this thread. +JNIEnv* AttachCurrentThreadIfNeeded(); +} // namespace webrtc + +#endif // SDK_ANDROID_NATIVE_API_JNI_JVM_H_ diff --git a/sdk/android/src/jni/scoped_java_ref.h b/sdk/android/native_api/jni/scoped_java_ref.h similarity index 96% rename from sdk/android/src/jni/scoped_java_ref.h rename to sdk/android/native_api/jni/scoped_java_ref.h index 8fac4b34f3..e3259f1d8a 100644 --- a/sdk/android/src/jni/scoped_java_ref.h +++ b/sdk/android/native_api/jni/scoped_java_ref.h @@ -11,18 +11,16 @@ // Originally these classes are from Chromium. // https://cs.chromium.org/chromium/src/base/android/scoped_java_ref.h. -#ifndef SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_ -#define SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_ +#ifndef SDK_ANDROID_NATIVE_API_JNI_SCOPED_JAVA_REF_H_ +#define SDK_ANDROID_NATIVE_API_JNI_SCOPED_JAVA_REF_H_ #include #include #include "rtc_base/constructormagic.h" +#include "sdk/android/native_api/jni/jvm.h" namespace webrtc { -namespace jni { - -JNIEnv* AttachCurrentThreadIfNeeded(); // Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful // for allowing functions to accept a reference without having to mandate @@ -199,7 +197,6 @@ class ScopedJavaGlobalRef : public JavaRef { RTC_DISALLOW_COPY_AND_ASSIGN(ScopedJavaGlobalRef); }; -} // namespace jni } // namespace webrtc -#endif // SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_ +#endif // SDK_ANDROID_NATIVE_API_JNI_SCOPED_JAVA_REF_H_ diff --git a/sdk/android/src/jni/androidhistogram.cc b/sdk/android/src/jni/androidhistogram.cc index 9ef15b3b75..d5f2a026ca 100644 --- a/sdk/android/src/jni/androidhistogram.cc +++ b/sdk/android/src/jni/androidhistogram.cc @@ -12,6 +12,7 @@ #include #include "sdk/android/generated_base_jni/jni/Histogram_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "system_wrappers/include/metrics.h" diff --git a/sdk/android/src/jni/androidmediadecoder.cc b/sdk/android/src/jni/androidmediadecoder.cc index 93f8f4672b..ca013dd0c6 100644 --- a/sdk/android/src/jni/androidmediadecoder.cc +++ b/sdk/android/src/jni/androidmediadecoder.cc @@ -28,6 +28,7 @@ #include "rtc_base/thread.h" #include "rtc_base/timeutils.h" #include "sdk/android/generated_video_jni/jni/MediaCodecVideoDecoder_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/androidmediacodeccommon.h" #include "sdk/android/src/jni/surfacetexturehelper.h" #include "sdk/android/src/jni/videoframe.h" diff --git a/sdk/android/src/jni/androidmediaencoder.cc b/sdk/android/src/jni/androidmediaencoder.cc index 43aa7f10b4..8908b8e4fc 100644 --- a/sdk/android/src/jni/androidmediaencoder.cc +++ b/sdk/android/src/jni/androidmediaencoder.cc @@ -38,6 +38,7 @@ #include "rtc_base/timeutils.h" #include "rtc_base/weak_ptr.h" #include "sdk/android/generated_video_jni/jni/MediaCodecVideoEncoder_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/androidmediacodeccommon.h" #include "sdk/android/src/jni/androidmediadecoder_jni.h" #include "sdk/android/src/jni/jni_helpers.h" diff --git a/sdk/android/src/jni/androidmetrics.cc b/sdk/android/src/jni/androidmetrics.cc index 68b1047538..3f96c0a832 100644 --- a/sdk/android/src/jni/androidmetrics.cc +++ b/sdk/android/src/jni/androidmetrics.cc @@ -12,6 +12,7 @@ #include #include "sdk/android/generated_metrics_jni/jni/Metrics_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "system_wrappers/include/metrics.h" #include "system_wrappers/include/metrics_default.h" diff --git a/sdk/android/src/jni/class_loader.h b/sdk/android/src/jni/class_loader.h index 90c46d71fe..4b255a4660 100644 --- a/sdk/android/src/jni/class_loader.h +++ b/sdk/android/src/jni/class_loader.h @@ -8,34 +8,16 @@ * be found in the AUTHORS file in the root of the source tree. */ -// Android's FindClass() is tricky because the app-specific ClassLoader is not -// consulted when there is no app-specific frame on the stack (i.e. when called -// from a thread created from native C++ code). These helper functions provide a -// workaround for this. -// http://developer.android.com/training/articles/perf-jni.html#faq_FindClass +// Deprecated: use sdk/android/native_api/jni/class_loader.h instead. #ifndef SDK_ANDROID_SRC_JNI_CLASS_LOADER_H_ #define SDK_ANDROID_SRC_JNI_CLASS_LOADER_H_ -#include - -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/class_loader.h" namespace webrtc { namespace jni { - -// This method should be called from JNI_OnLoad and before any calls to -// FindClass. -void InitClassLoader(JNIEnv* env); - -// This function is identical to JNIEnv::FindClass except that it works from any -// thread. This function loads and returns a local reference to the class with -// the given name. The name argument is a fully-qualified class name. For -// example, the fully-qualified class name for the java.lang.String class is: -// "java/lang/String". This function will be used from the JNI generated code -// and should rarely be used manually. -ScopedJavaLocalRef GetClass(JNIEnv* env, const char* name); - +using ::webrtc::InitClassLoader; } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/classreferenceholder.h b/sdk/android/src/jni/classreferenceholder.h index b51660d99e..51759fc95a 100644 --- a/sdk/android/src/jni/classreferenceholder.h +++ b/sdk/android/src/jni/classreferenceholder.h @@ -13,7 +13,7 @@ // TODO(magjed): Update external clients to call webrtc::jni::InitClassLoader // immediately instead. -#include "sdk/android/src/jni/class_loader.h" +#include "sdk/android/native_api/jni/class_loader.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { @@ -21,7 +21,7 @@ namespace jni { // Deprecated. Call webrtc::jni::InitClassLoader() immediately instead.. inline void LoadGlobalClassReferenceHolder() { - webrtc::jni::InitClassLoader(GetEnv()); + webrtc::InitClassLoader(GetEnv()); } // Deprecated. Do not call at all. diff --git a/sdk/android/src/jni/encodedimage.cc b/sdk/android/src/jni/encodedimage.cc index d24c25a3a0..82448710dc 100644 --- a/sdk/android/src/jni/encodedimage.cc +++ b/sdk/android/src/jni/encodedimage.cc @@ -13,6 +13,7 @@ #include "common_video/include/video_frame.h" #include "rtc_base/timeutils.h" #include "sdk/android/generated_video_jni/jni/EncodedImage_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/encodedimage.h b/sdk/android/src/jni/encodedimage.h index 3b4af7884a..66c226b1c9 100644 --- a/sdk/android/src/jni/encodedimage.h +++ b/sdk/android/src/jni/encodedimage.h @@ -14,7 +14,7 @@ #include #include "common_types.h" // NOLINT(build/include) -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { diff --git a/sdk/android/src/jni/hardwarevideoencoderfactory.cc b/sdk/android/src/jni/hardwarevideoencoderfactory.cc index 96e4691f65..ebd9b0afa6 100644 --- a/sdk/android/src/jni/hardwarevideoencoderfactory.cc +++ b/sdk/android/src/jni/hardwarevideoencoderfactory.cc @@ -12,6 +12,7 @@ #include "media/base/h264_profile_level_id.h" #include "sdk/android/generated_video_jni/jni/HardwareVideoEncoderFactory_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/jni_generator_helper.cc b/sdk/android/src/jni/jni_generator_helper.cc index 4db7201480..4cd9b43f5f 100644 --- a/sdk/android/src/jni/jni_generator_helper.cc +++ b/sdk/android/src/jni/jni_generator_helper.cc @@ -11,7 +11,7 @@ #include "sdk/android/src/jni/jni_generator_helper.h" #include "rtc_base/atomicops.h" -#include "sdk/android/src/jni/class_loader.h" +#include "sdk/android/native_api/jni/class_loader.h" namespace base { namespace android { @@ -28,8 +28,7 @@ jclass LazyGetClass(JNIEnv* env, rtc::AtomicOps::AcquireLoadPtr(atomic_class_id); if (value) return reinterpret_cast(value); - webrtc::jni::ScopedJavaGlobalRef clazz( - webrtc::jni::GetClass(env, class_name)); + webrtc::ScopedJavaGlobalRef clazz(webrtc::GetClass(env, class_name)); RTC_CHECK(!clazz.is_null()) << class_name; base::subtle::AtomicWord null_aw = nullptr; base::subtle::AtomicWord cas_result = rtc::AtomicOps::CompareAndSwapPtr( diff --git a/sdk/android/src/jni/jni_generator_helper.h b/sdk/android/src/jni/jni_generator_helper.h index 901ffb6cef..98ced609a2 100644 --- a/sdk/android/src/jni/jni_generator_helper.h +++ b/sdk/android/src/jni/jni_generator_helper.h @@ -19,7 +19,7 @@ #include #include "rtc_base/checks.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" // TODO(crbug.com/801260): Remove this macro definition as soon as // crrev.com/531028 will be reverted. @@ -61,9 +61,9 @@ typedef void* AtomicWord; namespace android { -using webrtc::jni::JavaRef; -using webrtc::jni::ScopedJavaLocalRef; -using webrtc::jni::JavaParamRef; +using webrtc::JavaRef; +using webrtc::ScopedJavaLocalRef; +using webrtc::JavaParamRef; // This function will initialize |atomic_class_id| to contain a global ref to // the given class, and will return that ref on subsequent calls. The caller is diff --git a/sdk/android/src/jni/jni_helpers.cc b/sdk/android/src/jni/jni_helpers.cc index 253683fd5f..bdcff9c67b 100644 --- a/sdk/android/src/jni/jni_helpers.cc +++ b/sdk/android/src/jni/jni_helpers.cc @@ -9,133 +9,13 @@ */ #include "sdk/android/src/jni/jni_helpers.h" -#include -#include -#include -#include #include -#include "sdk/android/generated_base_jni/jni/JniHelper_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/ArrayList_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Boolean_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Double_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Enum_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Integer_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Iterable_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Iterator_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/LinkedHashMap_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Long_jni.h" -#include "sdk/android/generated_external_classes_jni/jni/Map_jni.h" +#include "sdk/android/native_api/jni/java_types.h" namespace webrtc { namespace jni { -static JavaVM* g_jvm = nullptr; - -static pthread_once_t g_jni_ptr_once = PTHREAD_ONCE_INIT; - -// Key for per-thread JNIEnv* data. Non-NULL in threads attached to |g_jvm| by -// AttachCurrentThreadIfNeeded(), NULL in unattached threads and threads that -// were attached by the JVM because of a Java->native call. -static pthread_key_t g_jni_ptr; - -JavaVM *GetJVM() { - RTC_CHECK(g_jvm) << "JNI_OnLoad failed to run?"; - return g_jvm; -} - -// Return a |JNIEnv*| usable on this thread or NULL if this thread is detached. -JNIEnv* GetEnv() { - void* env = nullptr; - jint status = g_jvm->GetEnv(&env, JNI_VERSION_1_6); - RTC_CHECK(((env != nullptr) && (status == JNI_OK)) || - ((env == nullptr) && (status == JNI_EDETACHED))) - << "Unexpected GetEnv return: " << status << ":" << env; - return reinterpret_cast(env); -} - -static void ThreadDestructor(void* prev_jni_ptr) { - // This function only runs on threads where |g_jni_ptr| is non-NULL, meaning - // we were responsible for originally attaching the thread, so are responsible - // for detaching it now. However, because some JVM implementations (notably - // Oracle's http://goo.gl/eHApYT) also use the pthread_key_create mechanism, - // the JVMs accounting info for this thread may already be wiped out by the - // time this is called. Thus it may appear we are already detached even though - // it was our responsibility to detach! Oh well. - if (!GetEnv()) - return; - - RTC_CHECK(GetEnv() == prev_jni_ptr) - << "Detaching from another thread: " << prev_jni_ptr << ":" << GetEnv(); - jint status = g_jvm->DetachCurrentThread(); - RTC_CHECK(status == JNI_OK) << "Failed to detach thread: " << status; - RTC_CHECK(!GetEnv()) << "Detaching was a successful no-op???"; -} - -static void CreateJNIPtrKey() { - RTC_CHECK(!pthread_key_create(&g_jni_ptr, &ThreadDestructor)) - << "pthread_key_create"; -} - -jint InitGlobalJniVariables(JavaVM *jvm) { - RTC_CHECK(!g_jvm) << "InitGlobalJniVariables!"; - g_jvm = jvm; - RTC_CHECK(g_jvm) << "InitGlobalJniVariables handed NULL?"; - - RTC_CHECK(!pthread_once(&g_jni_ptr_once, &CreateJNIPtrKey)) << "pthread_once"; - - JNIEnv* jni = nullptr; - if (jvm->GetEnv(reinterpret_cast(&jni), JNI_VERSION_1_6) != JNI_OK) - return -1; - - return JNI_VERSION_1_6; -} - -// Return thread ID as a string. -static std::string GetThreadId() { - char buf[21]; // Big enough to hold a kuint64max plus terminating NULL. - RTC_CHECK_LT(snprintf(buf, sizeof(buf), "%ld", - static_cast(syscall(__NR_gettid))), - sizeof(buf)) - << "Thread id is bigger than uint64??"; - return std::string(buf); -} - -// Return the current thread's name. -static std::string GetThreadName() { - char name[17] = {0}; - if (prctl(PR_GET_NAME, name) != 0) - return std::string(""); - return std::string(name); -} - -// Return a |JNIEnv*| usable on this thread. Attaches to |g_jvm| if necessary. -JNIEnv* AttachCurrentThreadIfNeeded() { - JNIEnv* jni = GetEnv(); - if (jni) - return jni; - RTC_CHECK(!pthread_getspecific(g_jni_ptr)) - << "TLS has a JNIEnv* but not attached?"; - - std::string name(GetThreadName() + " - " + GetThreadId()); - JavaVMAttachArgs args; - args.version = JNI_VERSION_1_6; - args.name = &name[0]; - args.group = nullptr; - // Deal with difference in signatures between Oracle's jni.h and Android's. -#ifdef _JAVASOFT_JNI_H_ // Oracle's jni.h violates the JNI spec! - void* env = nullptr; -#else - JNIEnv* env = nullptr; -#endif - RTC_CHECK(!g_jvm->AttachCurrentThread(&env, &args)) - << "Failed to attach thread"; - RTC_CHECK(env) << "AttachCurrentThread handed back NULL!"; - jni = reinterpret_cast(env); - RTC_CHECK(!pthread_setspecific(g_jni_ptr, jni)) << "pthread_setspecific"; - return jni; -} - // Return a |jlong| that will correctly convert back to |ptr|. This is needed // because the alternative (of silently passing a 32-bit pointer to a vararg // function expecting a 64-bit param) picks up garbage in the high 32 bits. @@ -150,10 +30,6 @@ jlong jlongFromPointer(void* ptr) { return ret; } -bool IsNull(JNIEnv* jni, const JavaRef& obj) { - return jni->IsSameObject(obj.obj(), nullptr); -} - ScopedJavaLocalRef NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) { @@ -163,103 +39,6 @@ ScopedJavaLocalRef NewDirectByteBuffer(JNIEnv* env, return buffer; } -// Given a jstring, reinterprets it to a new native string. -std::string JavaToStdString(JNIEnv* jni, const JavaRef& j_string) { - const ScopedJavaLocalRef j_byte_array = - Java_JniHelper_getStringBytes(jni, j_string); - - const size_t len = jni->GetArrayLength(j_byte_array.obj()); - CHECK_EXCEPTION(jni) << "error during GetArrayLength"; - std::string str(len, '\0'); - jni->GetByteArrayRegion(j_byte_array.obj(), 0, len, - reinterpret_cast(&str[0])); - CHECK_EXCEPTION(jni) << "error during GetByteArrayRegion"; - return str; -} - -// Given a list of jstrings, reinterprets it to a new vector of native strings. -std::vector JavaToStdVectorStrings(JNIEnv* jni, - const JavaRef& list) { - std::vector converted_list; - if (!list.is_null()) { - for (const JavaRef& str : Iterable(jni, list)) { - converted_list.push_back(JavaToStdString( - jni, JavaParamRef(static_cast(str.obj())))); - } - } - return converted_list; -} - -rtc::Optional JavaToNativeOptionalInt( - JNIEnv* jni, - const JavaRef& integer) { - if (IsNull(jni, integer)) - return rtc::nullopt; - return JNI_Integer::Java_Integer_intValue(jni, integer); -} - -rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, - const JavaRef& boolean) { - if (IsNull(jni, boolean)) - return rtc::nullopt; - return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean); -} - -int64_t JavaToNativeLong(JNIEnv* env, const JavaRef& j_long) { - return JNI_Long::Java_Long_longValue(env, j_long); -} - -ScopedJavaLocalRef NativeToJavaBoolean(JNIEnv* env, bool b) { - return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b); -} - -ScopedJavaLocalRef NativeToJavaInteger(JNIEnv* jni, int32_t i) { - return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i); -} - -ScopedJavaLocalRef NativeToJavaLong(JNIEnv* env, int64_t u) { - return JNI_Long::Java_Long_ConstructorJLLO_J(env, u); -} - -ScopedJavaLocalRef NativeToJavaDouble(JNIEnv* env, double d) { - return JNI_Double::Java_Double_ConstructorJLD_D(env, d); -} - -ScopedJavaLocalRef NativeToJavaString(JNIEnv* env, const char* str) { - jstring j_str = env->NewStringUTF(str); - CHECK_EXCEPTION(env) << "error during NewStringUTF"; - return ScopedJavaLocalRef(env, j_str); -} - -ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, - const std::string& str) { - return NativeToJavaString(jni, str.c_str()); -} - -ScopedJavaLocalRef NativeToJavaInteger( - JNIEnv* jni, - const rtc::Optional& optional_int) { - return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr; -} - -std::string GetJavaEnumName(JNIEnv* jni, const JavaRef& j_enum) { - return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum)); -} - -std::map JavaToStdMapStrings( - JNIEnv* jni, - const JavaRef& j_map) { - const JavaRef& j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map); - std::map result; - for (const JavaRef& j_entry : Iterable(jni, j_entry_set)) { - result.insert(std::make_pair( - JavaToStdString(jni, Java_JniHelper_getKey(jni, j_entry)), - JavaToStdString(jni, Java_JniHelper_getValue(jni, j_entry)))); - } - - return result; -} - jobject NewGlobalRef(JNIEnv* jni, jobject o) { jobject ret = jni->NewGlobalRef(o); CHECK_EXCEPTION(jni) << "error during NewGlobalRef"; @@ -282,133 +61,5 @@ ScopedLocalRefFrame::~ScopedLocalRefFrame() { jni_->PopLocalFrame(nullptr); } -Iterable::Iterable(JNIEnv* jni, const JavaRef& iterable) - : jni_(jni), iterable_(jni, iterable) {} - -Iterable::~Iterable() = default; - -// Creates an iterator representing the end of any collection. -Iterable::Iterator::Iterator() = default; - -// Creates an iterator pointing to the beginning of the specified collection. -Iterable::Iterator::Iterator(JNIEnv* jni, const JavaRef& iterable) - : jni_(jni) { - iterator_ = JNI_Iterable::Java_Iterable_iterator(jni, iterable); - RTC_CHECK(!iterator_.is_null()); - // Start at the first element in the collection. - ++(*this); -} - -// Move constructor - necessary to be able to return iterator types from -// functions. -Iterable::Iterator::Iterator(Iterator&& other) - : jni_(std::move(other.jni_)), - iterator_(std::move(other.iterator_)), - value_(std::move(other.value_)), - thread_checker_(std::move(other.thread_checker_)){}; - -Iterable::Iterator::~Iterator() = default; - -// Advances the iterator one step. -Iterable::Iterator& Iterable::Iterator::operator++() { - RTC_CHECK(thread_checker_.CalledOnValidThread()); - if (AtEnd()) { - // Can't move past the end. - return *this; - } - bool has_next = JNI_Iterator::Java_Iterator_hasNext(jni_, iterator_); - if (!has_next) { - iterator_ = nullptr; - value_ = nullptr; - return *this; - } - - value_ = JNI_Iterator::Java_Iterator_next(jni_, iterator_); - return *this; -} - -void Iterable::Iterator::Remove() { - JNI_Iterator::Java_Iterator_remove(jni_, iterator_); -} - -// Provides a way to compare the iterator with itself and with the end iterator. -// Note: all other comparison results are undefined, just like for C++ input -// iterators. -bool Iterable::Iterator::operator==(const Iterable::Iterator& other) { - // Two different active iterators should never be compared. - RTC_DCHECK(this == &other || AtEnd() || other.AtEnd()); - return AtEnd() == other.AtEnd(); -} - -ScopedJavaLocalRef& Iterable::Iterator::operator*() { - RTC_CHECK(!AtEnd()); - return value_; -} - -bool Iterable::Iterator::AtEnd() const { - RTC_CHECK(thread_checker_.CalledOnValidThread()); - return jni_ == nullptr || IsNull(jni_, iterator_); -} - -ScopedJavaLocalRef NativeToJavaIntegerArray( - JNIEnv* env, - const std::vector& container) { - ScopedJavaLocalRef (*convert_function)(JNIEnv*, int32_t) = - &NativeToJavaInteger; - return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env), - convert_function); -} - -ScopedJavaLocalRef NativeToJavaBooleanArray( - JNIEnv* env, - const std::vector& container) { - return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env), - &NativeToJavaBoolean); -} - -ScopedJavaLocalRef NativeToJavaDoubleArray( - JNIEnv* env, - const std::vector& container) { - return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env), - &NativeToJavaDouble); -} - -ScopedJavaLocalRef NativeToJavaLongArray( - JNIEnv* env, - const std::vector& container) { - return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env), - &NativeToJavaLong); -} - -ScopedJavaLocalRef NativeToJavaStringArray( - JNIEnv* env, - const std::vector& container) { - ScopedJavaLocalRef (*convert)(JNIEnv*, const std::string&) = - &NativeToJavaString; - return NativeToJavaObjectArray( - env, container, - static_cast(Java_JniHelper_getStringClass(env).obj()), convert); -} - -JavaMapBuilder::JavaMapBuilder(JNIEnv* env) - : env_(env), - j_map_(JNI_LinkedHashMap::Java_LinkedHashMap_ConstructorJULIHM(env)) {} - -JavaMapBuilder::~JavaMapBuilder() = default; - -void JavaMapBuilder::put(const JavaRef& key, - const JavaRef& value) { - JNI_Map::Java_Map_put(env_, j_map_, key, value); -} - -JavaListBuilder::JavaListBuilder(JNIEnv* env) - : env_(env), j_list_(JNI_ArrayList::Java_ArrayList_ConstructorJUALI(env)) {} - -JavaListBuilder::~JavaListBuilder() = default; - -void JavaListBuilder::add(const JavaRef& element) { - JNI_ArrayList::Java_ArrayList_addZ_JUE(env_, j_list_, element); -} - } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/jni_helpers.h b/sdk/android/src/jni/jni_helpers.h index 898c47b6b0..7895a7802c 100644 --- a/sdk/android/src/jni/jni_helpers.h +++ b/sdk/android/src/jni/jni_helpers.h @@ -15,24 +15,11 @@ #define SDK_ANDROID_SRC_JNI_JNI_HELPERS_H_ #include -#include #include -#include -#include "api/optional.h" -#include "rtc_base/checks.h" -#include "rtc_base/constructormagic.h" -#include "rtc_base/refcount.h" -#include "rtc_base/thread_checker.h" -#include "sdk/android/src/jni/scoped_java_ref.h" - -// Abort the process if |jni| has a Java exception pending. -// This macros uses the comma operator to execute ExceptionDescribe -// and ExceptionClear ignoring their return values and sending "" -// to the error stream. -#define CHECK_EXCEPTION(jni) \ - RTC_CHECK(!jni->ExceptionCheck()) \ - << (jni->ExceptionDescribe(), jni->ExceptionClear(), "") +#include "sdk/android/native_api/jni/java_types.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" +#include "sdk/android/src/jni/jvm.h" // Convenience macro defining JNI-accessible methods in the org.webrtc package. // Eliminates unnecessary boilerplate and line-wraps, reducing visual clutter. @@ -42,70 +29,17 @@ namespace webrtc { namespace jni { -jint InitGlobalJniVariables(JavaVM *jvm); - -// Return a |JNIEnv*| usable on this thread or NULL if this thread is detached. -JNIEnv* GetEnv(); - -JavaVM *GetJVM(); - -// Return a |JNIEnv*| usable on this thread. Attaches to |g_jvm| if necessary. -JNIEnv* AttachCurrentThreadIfNeeded(); +// TODO(sakal): Remove once clients have migrated. +using ::webrtc::JavaToStdMapStrings; // Return a |jlong| that will correctly convert back to |ptr|. This is needed // because the alternative (of silently passing a 32-bit pointer to a vararg // function expecting a 64-bit param) picks up garbage in the high 32 bits. jlong jlongFromPointer(void* ptr); -// Returns true if |obj| == null in Java. -bool IsNull(JNIEnv* jni, const JavaRef& obj); - ScopedJavaLocalRef NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity); -// Given a (UTF-16) jstring return a new UTF-8 native string. -std::string JavaToStdString(JNIEnv* jni, const JavaRef& j_string); - -// Deprecated. Use scoped jobjects instead. -inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) { - return JavaToStdString(jni, JavaParamRef(j_string)); -} - -// Given a List of (UTF-16) jstrings -// return a new vector of UTF-8 native strings. -std::vector JavaToStdVectorStrings(JNIEnv* jni, - const JavaRef& list); - -rtc::Optional JavaToNativeOptionalInt(JNIEnv* jni, - const JavaRef& integer); -rtc::Optional JavaToNativeOptionalBool(JNIEnv* jni, - const JavaRef& boolean); -int64_t JavaToNativeLong(JNIEnv* env, const JavaRef& j_long); - -ScopedJavaLocalRef NativeToJavaBoolean(JNIEnv* env, bool b); -ScopedJavaLocalRef NativeToJavaInteger(JNIEnv* jni, int32_t i); -ScopedJavaLocalRef NativeToJavaLong(JNIEnv* env, int64_t u); -ScopedJavaLocalRef NativeToJavaDouble(JNIEnv* env, double d); -ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, const char* str); -ScopedJavaLocalRef NativeToJavaString(JNIEnv* jni, - const std::string& str); -ScopedJavaLocalRef NativeToJavaInteger( - JNIEnv* jni, - const rtc::Optional& optional_int); - -// Parses Map to std::map. -std::map JavaToStdMapStrings( - JNIEnv* jni, - const JavaRef& j_map); - -// Deprecated. Use scoped jobjects instead. -inline std::map JavaToStdMapStrings(JNIEnv* jni, - jobject j_map) { - return JavaToStdMapStrings(jni, JavaParamRef(j_map)); -} - -// Returns the name of a Java enum. -std::string GetJavaEnumName(JNIEnv* jni, const JavaRef& j_enum); jobject NewGlobalRef(JNIEnv* jni, jobject o); @@ -123,178 +57,13 @@ class ScopedLocalRefFrame { JNIEnv* jni_; }; -// Provides a convenient way to iterate over a Java Iterable using the -// C++ range-for loop. -// E.g. for (jobject value : Iterable(jni, j_iterable)) { ... } -// Note: Since Java iterators cannot be duplicated, the iterator class is not -// copyable to prevent creating multiple C++ iterators that refer to the same -// Java iterator. -class Iterable { - public: - Iterable(JNIEnv* jni, const JavaRef& iterable); - ~Iterable(); - - class Iterator { - public: - // Creates an iterator representing the end of any collection. - Iterator(); - // Creates an iterator pointing to the beginning of the specified - // collection. - Iterator(JNIEnv* jni, const JavaRef& iterable); - - // Move constructor - necessary to be able to return iterator types from - // functions. - Iterator(Iterator&& other); - - ~Iterator(); - - // Move assignment should not be used. - Iterator& operator=(Iterator&&) = delete; - - // Advances the iterator one step. - Iterator& operator++(); - - // Removes the element the iterator is pointing to. Must still advance the - // iterator afterwards. - void Remove(); - - // Provides a way to compare the iterator with itself and with the end - // iterator. - // Note: all other comparison results are undefined, just like for C++ input - // iterators. - bool operator==(const Iterator& other); - bool operator!=(const Iterator& other) { return !(*this == other); } - ScopedJavaLocalRef& operator*(); - - private: - bool AtEnd() const; - - JNIEnv* jni_ = nullptr; - ScopedJavaLocalRef iterator_; - ScopedJavaLocalRef value_; - rtc::ThreadChecker thread_checker_; - - RTC_DISALLOW_COPY_AND_ASSIGN(Iterator); - }; - - Iterable::Iterator begin() { return Iterable::Iterator(jni_, iterable_); } - Iterable::Iterator end() { return Iterable::Iterator(); } - - private: - JNIEnv* jni_; - ScopedJavaLocalRef iterable_; - - RTC_DISALLOW_COPY_AND_ASSIGN(Iterable); -}; - -// Helper function for converting std::vector into a Java array. -template -ScopedJavaLocalRef NativeToJavaObjectArray( - JNIEnv* env, - const std::vector& container, - jclass clazz, - Convert convert) { - ScopedJavaLocalRef j_container( - env, env->NewObjectArray(container.size(), clazz, nullptr)); - int i = 0; - for (const T& element : container) { - env->SetObjectArrayElement(j_container.obj(), i, - convert(env, element).obj()); - ++i; - } - return j_container; -} - -ScopedJavaLocalRef NativeToJavaIntegerArray( - JNIEnv* env, - const std::vector& container); -ScopedJavaLocalRef NativeToJavaBooleanArray( - JNIEnv* env, - const std::vector& container); -ScopedJavaLocalRef NativeToJavaLongArray( - JNIEnv* env, - const std::vector& container); -ScopedJavaLocalRef NativeToJavaDoubleArray( - JNIEnv* env, - const std::vector& container); -ScopedJavaLocalRef NativeToJavaStringArray( - JNIEnv* env, - const std::vector& container); - -template -std::vector JavaToNativeVector(JNIEnv* env, - const JavaRef& j_container, - Convert convert) { - std::vector container; - const size_t size = env->GetArrayLength(j_container.obj()); - container.reserve(size); - for (size_t i = 0; i < size; ++i) { - container.emplace_back(convert( - env, ScopedJavaLocalRef( - env, env->GetObjectArrayElement(j_container.obj(), i)))); - } - CHECK_EXCEPTION(env) << "Error during JavaToNativeVector"; - return container; -} - -// This is a helper class for NativeToJavaList(). Use that function instead of -// using this class directly. -class JavaListBuilder { - public: - explicit JavaListBuilder(JNIEnv* env); - ~JavaListBuilder(); - void add(const JavaRef& element); - ScopedJavaLocalRef java_list() { return j_list_; } - - private: - JNIEnv* env_; - ScopedJavaLocalRef j_list_; -}; - -template -ScopedJavaLocalRef NativeToJavaList(JNIEnv* env, - const C& container, - Convert convert) { - JavaListBuilder builder(env); - for (const auto& e : container) - builder.add(convert(env, e)); - return builder.java_list(); -} - -// This is a helper class for NativeToJavaMap(). Use that function instead of -// using this class directly. -class JavaMapBuilder { - public: - explicit JavaMapBuilder(JNIEnv* env); - ~JavaMapBuilder(); - void put(const JavaRef& key, const JavaRef& value); - ScopedJavaLocalRef GetJavaMap() { return j_map_; } - - private: - JNIEnv* env_; - ScopedJavaLocalRef j_map_; -}; - -template -ScopedJavaLocalRef NativeToJavaMap(JNIEnv* env, - const C& container, - Convert convert) { - JavaMapBuilder builder(env); - for (const auto& e : container) { - ScopedLocalRefFrame local_ref_frame(env); - const auto key_value_pair = convert(env, e); - builder.put(key_value_pair.first, key_value_pair.second); - } - return builder.GetJavaMap(); -} - } // namespace jni } // namespace webrtc // TODO(magjed): Remove once external clients are updated. namespace webrtc_jni { -using webrtc::jni::AttachCurrentThreadIfNeeded; +using webrtc::AttachCurrentThreadIfNeeded; using webrtc::jni::InitGlobalJniVariables; } // namespace webrtc_jni diff --git a/sdk/android/src/jni/jvm.cc b/sdk/android/src/jni/jvm.cc new file mode 100644 index 0000000000..eaa4f67212 --- /dev/null +++ b/sdk/android/src/jni/jvm.cc @@ -0,0 +1,133 @@ +/* + * Copyright 2018 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/jvm.h" + +#include +#include +#include +#include +#include + +#include + +#include "rtc_base/checks.h" + +namespace webrtc { +namespace jni { + +static JavaVM* g_jvm = nullptr; + +static pthread_once_t g_jni_ptr_once = PTHREAD_ONCE_INIT; + +// Key for per-thread JNIEnv* data. Non-NULL in threads attached to |g_jvm| by +// AttachCurrentThreadIfNeeded(), NULL in unattached threads and threads that +// were attached by the JVM because of a Java->native call. +static pthread_key_t g_jni_ptr; + +JavaVM* GetJVM() { + RTC_CHECK(g_jvm) << "JNI_OnLoad failed to run?"; + return g_jvm; +} + +// Return a |JNIEnv*| usable on this thread or NULL if this thread is detached. +JNIEnv* GetEnv() { + void* env = nullptr; + jint status = g_jvm->GetEnv(&env, JNI_VERSION_1_6); + RTC_CHECK(((env != nullptr) && (status == JNI_OK)) || + ((env == nullptr) && (status == JNI_EDETACHED))) + << "Unexpected GetEnv return: " << status << ":" << env; + return reinterpret_cast(env); +} + +static void ThreadDestructor(void* prev_jni_ptr) { + // This function only runs on threads where |g_jni_ptr| is non-NULL, meaning + // we were responsible for originally attaching the thread, so are responsible + // for detaching it now. However, because some JVM implementations (notably + // Oracle's http://goo.gl/eHApYT) also use the pthread_key_create mechanism, + // the JVMs accounting info for this thread may already be wiped out by the + // time this is called. Thus it may appear we are already detached even though + // it was our responsibility to detach! Oh well. + if (!GetEnv()) + return; + + RTC_CHECK(GetEnv() == prev_jni_ptr) + << "Detaching from another thread: " << prev_jni_ptr << ":" << GetEnv(); + jint status = g_jvm->DetachCurrentThread(); + RTC_CHECK(status == JNI_OK) << "Failed to detach thread: " << status; + RTC_CHECK(!GetEnv()) << "Detaching was a successful no-op???"; +} + +static void CreateJNIPtrKey() { + RTC_CHECK(!pthread_key_create(&g_jni_ptr, &ThreadDestructor)) + << "pthread_key_create"; +} + +jint InitGlobalJniVariables(JavaVM* jvm) { + RTC_CHECK(!g_jvm) << "InitGlobalJniVariables!"; + g_jvm = jvm; + RTC_CHECK(g_jvm) << "InitGlobalJniVariables handed NULL?"; + + RTC_CHECK(!pthread_once(&g_jni_ptr_once, &CreateJNIPtrKey)) << "pthread_once"; + + JNIEnv* jni = nullptr; + if (jvm->GetEnv(reinterpret_cast(&jni), JNI_VERSION_1_6) != JNI_OK) + return -1; + + return JNI_VERSION_1_6; +} + +// Return thread ID as a string. +static std::string GetThreadId() { + char buf[21]; // Big enough to hold a kuint64max plus terminating NULL. + RTC_CHECK_LT(snprintf(buf, sizeof(buf), "%ld", + static_cast(syscall(__NR_gettid))), + sizeof(buf)) + << "Thread id is bigger than uint64??"; + return std::string(buf); +} + +// Return the current thread's name. +static std::string GetThreadName() { + char name[17] = {0}; + if (prctl(PR_GET_NAME, name) != 0) + return std::string(""); + return std::string(name); +} + +// Return a |JNIEnv*| usable on this thread. Attaches to |g_jvm| if necessary. +JNIEnv* AttachCurrentThreadIfNeeded() { + JNIEnv* jni = GetEnv(); + if (jni) + return jni; + RTC_CHECK(!pthread_getspecific(g_jni_ptr)) + << "TLS has a JNIEnv* but not attached?"; + + std::string name(GetThreadName() + " - " + GetThreadId()); + JavaVMAttachArgs args; + args.version = JNI_VERSION_1_6; + args.name = &name[0]; + args.group = nullptr; +// Deal with difference in signatures between Oracle's jni.h and Android's. +#ifdef _JAVASOFT_JNI_H_ // Oracle's jni.h violates the JNI spec! + void* env = nullptr; +#else + JNIEnv* env = nullptr; +#endif + RTC_CHECK(!g_jvm->AttachCurrentThread(&env, &args)) + << "Failed to attach thread"; + RTC_CHECK(env) << "AttachCurrentThread handed back NULL!"; + jni = reinterpret_cast(env); + RTC_CHECK(!pthread_setspecific(g_jni_ptr, jni)) << "pthread_setspecific"; + return jni; +} + +} // namespace jni +} // namespace webrtc diff --git a/sdk/android/src/jni/jvm.h b/sdk/android/src/jni/jvm.h new file mode 100644 index 0000000000..069a19a445 --- /dev/null +++ b/sdk/android/src/jni/jvm.h @@ -0,0 +1,32 @@ +/* + * Copyright 2018 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_JVM_H_ +#define SDK_ANDROID_SRC_JNI_JVM_H_ + +#include + +namespace webrtc { +namespace jni { + +jint InitGlobalJniVariables(JavaVM* jvm); + +// Return a |JNIEnv*| usable on this thread or NULL if this thread is detached. +JNIEnv* GetEnv(); + +JavaVM* GetJVM(); + +// Return a |JNIEnv*| usable on this thread. Attaches to |g_jvm| if necessary. +JNIEnv* AttachCurrentThreadIfNeeded(); + +} // namespace jni +} // namespace webrtc + +#endif // SDK_ANDROID_SRC_JNI_JVM_H_ diff --git a/sdk/android/src/jni/pc/androidnetworkmonitor.cc b/sdk/android/src/jni/pc/androidnetworkmonitor.cc index c6efdc445f..742acc0e2d 100644 --- a/sdk/android/src/jni/pc/androidnetworkmonitor.cc +++ b/sdk/android/src/jni/pc/androidnetworkmonitor.cc @@ -21,6 +21,7 @@ #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/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc b/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc index 858c8a434d..da8d9b3c1e 100644 --- a/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc +++ b/sdk/android/src/jni/pc/callsessionfilerotatinglogsink.cc @@ -10,6 +10,7 @@ #include "rtc_base/logsinks.h" #include "sdk/android/generated_peerconnection_jni/jni/CallSessionFileRotatingLogSink_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/datachannel.cc b/sdk/android/src/jni/pc/datachannel.cc index 6dd2c8e2be..030ae2b71c 100644 --- a/sdk/android/src/jni/pc/datachannel.cc +++ b/sdk/android/src/jni/pc/datachannel.cc @@ -16,6 +16,7 @@ #include "rtc_base/logging.h" #include "rtc_base/ptr_util.h" #include "sdk/android/generated_peerconnection_jni/jni/DataChannel_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/datachannel.h" diff --git a/sdk/android/src/jni/pc/dtmfsender.cc b/sdk/android/src/jni/pc/dtmfsender.cc index 85c0861443..fbddc6b0bf 100644 --- a/sdk/android/src/jni/pc/dtmfsender.cc +++ b/sdk/android/src/jni/pc/dtmfsender.cc @@ -10,6 +10,7 @@ #include "api/dtmfsenderinterface.h" #include "sdk/android/generated_peerconnection_jni/jni/DtmfSender_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/icecandidate.cc b/sdk/android/src/jni/pc/icecandidate.cc index e13dc70c28..e6fad74b8b 100644 --- a/sdk/android/src/jni/pc/icecandidate.cc +++ b/sdk/android/src/jni/pc/icecandidate.cc @@ -14,6 +14,7 @@ #include "pc/webrtcsdp.h" #include "sdk/android/generated_peerconnection_jni/jni/IceCandidate_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/pc/mediastreamtrack.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/logging.cc b/sdk/android/src/jni/pc/logging.cc index 5b7511e5f5..48d400081c 100644 --- a/sdk/android/src/jni/pc/logging.cc +++ b/sdk/android/src/jni/pc/logging.cc @@ -11,6 +11,7 @@ #include #include "rtc_base/logging.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/mediaconstraints.cc b/sdk/android/src/jni/pc/mediaconstraints.cc index 5df7f5003e..868abc4879 100644 --- a/sdk/android/src/jni/pc/mediaconstraints.cc +++ b/sdk/android/src/jni/pc/mediaconstraints.cc @@ -12,6 +12,7 @@ #include "rtc_base/ptr_util.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaConstraints_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/mediaconstraints.h b/sdk/android/src/jni/pc/mediaconstraints.h index fea8d9fd43..2fbf34e74a 100644 --- a/sdk/android/src/jni/pc/mediaconstraints.h +++ b/sdk/android/src/jni/pc/mediaconstraints.h @@ -15,7 +15,7 @@ #include #include "api/mediaconstraintsinterface.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/mediastream.cc b/sdk/android/src/jni/pc/mediastream.cc index b45c93bed3..e733c8c6fb 100644 --- a/sdk/android/src/jni/pc/mediastream.cc +++ b/sdk/android/src/jni/pc/mediastream.cc @@ -12,6 +12,7 @@ #include "rtc_base/ptr_util.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaStream_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/mediastreamtrack.cc b/sdk/android/src/jni/pc/mediastreamtrack.cc index 06c21d3291..070b9d6852 100644 --- a/sdk/android/src/jni/pc/mediastreamtrack.cc +++ b/sdk/android/src/jni/pc/mediastreamtrack.cc @@ -12,6 +12,7 @@ #include "api/mediastreaminterface.h" #include "sdk/android/generated_peerconnection_jni/jni/MediaStreamTrack_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/mediastreamtrack.h b/sdk/android/src/jni/pc/mediastreamtrack.h index 22950dc687..8af425c9a4 100644 --- a/sdk/android/src/jni/pc/mediastreamtrack.h +++ b/sdk/android/src/jni/pc/mediastreamtrack.h @@ -14,7 +14,7 @@ #include #include "api/mediatypes.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/peerconnection.cc b/sdk/android/src/jni/pc/peerconnection.cc index 4a52a68b46..4055467b1f 100644 --- a/sdk/android/src/jni/pc/peerconnection.cc +++ b/sdk/android/src/jni/pc/peerconnection.cc @@ -40,6 +40,7 @@ #include "rtc_base/logging.h" #include "rtc_base/ptr_util.h" #include "sdk/android/generated_peerconnection_jni/jni/PeerConnection_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/datachannel.h" #include "sdk/android/src/jni/pc/icecandidate.h" diff --git a/sdk/android/src/jni/pc/peerconnectionfactory.cc b/sdk/android/src/jni/pc/peerconnectionfactory.cc index 8522999c56..33fa95945b 100644 --- a/sdk/android/src/jni/pc/peerconnectionfactory.cc +++ b/sdk/android/src/jni/pc/peerconnectionfactory.cc @@ -26,6 +26,7 @@ #include "rtc_base/stringutils.h" #include "rtc_base/thread.h" #include "sdk/android/generated_peerconnection_jni/jni/PeerConnectionFactory_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/androidnetworkmonitor.h" #include "sdk/android/src/jni/pc/audio.h" diff --git a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc index c61f37c4e4..4ca545da07 100644 --- a/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc +++ b/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.cc @@ -18,6 +18,7 @@ #include "sdk/android/generated_peerconnection_jni/jni/RTCStatsCollectorCallback_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStatsReport_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/RTCStats_jni.h" +#include "sdk/android/native_api/jni/java_types.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/rtpparameters.cc b/sdk/android/src/jni/pc/rtpparameters.cc index e9082e61cf..9630e1d6aa 100644 --- a/sdk/android/src/jni/pc/rtpparameters.cc +++ b/sdk/android/src/jni/pc/rtpparameters.cc @@ -11,6 +11,7 @@ #include "sdk/android/src/jni/pc/rtpparameters.h" #include "sdk/android/generated_peerconnection_jni/jni/RtpParameters_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/mediastreamtrack.h" diff --git a/sdk/android/src/jni/pc/rtpparameters.h b/sdk/android/src/jni/pc/rtpparameters.h index 7de4bde8f4..da7c995c03 100644 --- a/sdk/android/src/jni/pc/rtpparameters.h +++ b/sdk/android/src/jni/pc/rtpparameters.h @@ -14,7 +14,7 @@ #include #include "api/rtpparameters.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/rtpreceiver.cc b/sdk/android/src/jni/pc/rtpreceiver.cc index c96ac930d8..9487f404bd 100644 --- a/sdk/android/src/jni/pc/rtpreceiver.cc +++ b/sdk/android/src/jni/pc/rtpreceiver.cc @@ -11,6 +11,7 @@ #include "sdk/android/src/jni/pc/rtpreceiver.h" #include "sdk/android/generated_peerconnection_jni/jni/RtpReceiver_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/mediastreamtrack.h" #include "sdk/android/src/jni/pc/rtpparameters.h" diff --git a/sdk/android/src/jni/pc/rtpreceiver.h b/sdk/android/src/jni/pc/rtpreceiver.h index f7688ee066..c2e9c31aed 100644 --- a/sdk/android/src/jni/pc/rtpreceiver.h +++ b/sdk/android/src/jni/pc/rtpreceiver.h @@ -14,7 +14,7 @@ #include #include "api/rtpreceiverinterface.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/rtpsender.cc b/sdk/android/src/jni/pc/rtpsender.cc index 58053f97aa..3a00383753 100644 --- a/sdk/android/src/jni/pc/rtpsender.cc +++ b/sdk/android/src/jni/pc/rtpsender.cc @@ -11,6 +11,7 @@ #include "sdk/android/src/jni/pc/rtpsender.h" #include "sdk/android/generated_peerconnection_jni/jni/RtpSender_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/pc/rtpparameters.h" diff --git a/sdk/android/src/jni/pc/rtpsender.h b/sdk/android/src/jni/pc/rtpsender.h index a11c012f49..5d30ed52e4 100644 --- a/sdk/android/src/jni/pc/rtpsender.h +++ b/sdk/android/src/jni/pc/rtpsender.h @@ -14,7 +14,7 @@ #include #include "api/rtpsenderinterface.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/sdpobserver.cc b/sdk/android/src/jni/pc/sdpobserver.cc index 59d8eac591..a9fab94327 100644 --- a/sdk/android/src/jni/pc/sdpobserver.cc +++ b/sdk/android/src/jni/pc/sdpobserver.cc @@ -14,6 +14,7 @@ #include "api/mediaconstraintsinterface.h" #include "sdk/android/generated_peerconnection_jni/jni/SdpObserver_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/sessiondescription.cc b/sdk/android/src/jni/pc/sessiondescription.cc index 43354ce8c0..6bdbfa174d 100644 --- a/sdk/android/src/jni/pc/sessiondescription.cc +++ b/sdk/android/src/jni/pc/sessiondescription.cc @@ -14,6 +14,7 @@ #include "rtc_base/logging.h" #include "sdk/android/generated_peerconnection_jni/jni/SessionDescription_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/sessiondescription.h b/sdk/android/src/jni/pc/sessiondescription.h index 57d563e10e..a7ef667158 100644 --- a/sdk/android/src/jni/pc/sessiondescription.h +++ b/sdk/android/src/jni/pc/sessiondescription.h @@ -15,7 +15,7 @@ #include #include "api/jsep.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/statsobserver.cc b/sdk/android/src/jni/pc/statsobserver.cc index 56718de773..ef73c9bfbf 100644 --- a/sdk/android/src/jni/pc/statsobserver.cc +++ b/sdk/android/src/jni/pc/statsobserver.cc @@ -14,6 +14,7 @@ #include "sdk/android/generated_peerconnection_jni/jni/StatsObserver_jni.h" #include "sdk/android/generated_peerconnection_jni/jni/StatsReport_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/turncustomizer.cc b/sdk/android/src/jni/pc/turncustomizer.cc index 8d48e12a1f..3857a540ff 100644 --- a/sdk/android/src/jni/pc/turncustomizer.cc +++ b/sdk/android/src/jni/pc/turncustomizer.cc @@ -10,6 +10,7 @@ #include "api/turncustomizer.h" #include "sdk/android/generated_peerconnection_jni/jni/TurnCustomizer_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/pc/turncustomizer.h b/sdk/android/src/jni/pc/turncustomizer.h index ed4a3d5b7e..ea6997310f 100644 --- a/sdk/android/src/jni/pc/turncustomizer.h +++ b/sdk/android/src/jni/pc/turncustomizer.h @@ -12,7 +12,7 @@ #define SDK_ANDROID_SRC_JNI_PC_TURNCUSTOMIZER_H_ #include "api/turncustomizer.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/pc/video.cc b/sdk/android/src/jni/pc/video.cc index 55379f7944..d3eed5f8d9 100644 --- a/sdk/android/src/jni/pc/video.cc +++ b/sdk/android/src/jni/pc/video.cc @@ -24,7 +24,6 @@ #include "sdk/android/src/jni/androidmediadecoder_jni.h" #include "sdk/android/src/jni/androidmediaencoder_jni.h" #include "sdk/android/src/jni/androidvideotracksource.h" -#include "sdk/android/src/jni/pc/ownedfactoryandthreads.h" #include "sdk/android/src/jni/surfacetexturehelper.h" #include "sdk/android/src/jni/videodecoderfactorywrapper.h" #include "sdk/android/src/jni/videoencoderfactorywrapper.h" diff --git a/sdk/android/src/jni/pc/video.h b/sdk/android/src/jni/pc/video.h index 0fd7ac2939..4f9b48c874 100644 --- a/sdk/android/src/jni/pc/video.h +++ b/sdk/android/src/jni/pc/video.h @@ -15,7 +15,7 @@ #include "rtc_base/scoped_ref_ptr.h" #include "rtc_base/thread.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace cricket { class WebRtcVideoEncoderFactory; diff --git a/sdk/android/src/jni/surfacetexturehelper.cc b/sdk/android/src/jni/surfacetexturehelper.cc index 3c6b7c0d24..be8611848d 100644 --- a/sdk/android/src/jni/surfacetexturehelper.cc +++ b/sdk/android/src/jni/surfacetexturehelper.cc @@ -13,6 +13,7 @@ #include "rtc_base/bind.h" #include "rtc_base/logging.h" #include "sdk/android/generated_video_jni/jni/SurfaceTextureHelper_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/videoframe.h" namespace webrtc { diff --git a/sdk/android/src/jni/videocodecinfo.cc b/sdk/android/src/jni/videocodecinfo.cc index c21e38ea3c..0ddc3287f0 100644 --- a/sdk/android/src/jni/videocodecinfo.cc +++ b/sdk/android/src/jni/videocodecinfo.cc @@ -11,6 +11,7 @@ #include "sdk/android/src/jni/videocodecinfo.h" #include "sdk/android/generated_video_jni/jni/VideoCodecInfo_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" namespace webrtc { diff --git a/sdk/android/src/jni/videocodecstatus.h b/sdk/android/src/jni/videocodecstatus.h index bfcdbe5307..2804654e41 100644 --- a/sdk/android/src/jni/videocodecstatus.h +++ b/sdk/android/src/jni/videocodecstatus.h @@ -14,7 +14,7 @@ #include #include -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/videodecoderfactorywrapper.cc b/sdk/android/src/jni/videodecoderfactorywrapper.cc index f41ef40f55..47c136210b 100644 --- a/sdk/android/src/jni/videodecoderfactorywrapper.cc +++ b/sdk/android/src/jni/videodecoderfactorywrapper.cc @@ -15,6 +15,7 @@ #include "common_types.h" // NOLINT(build/include) #include "rtc_base/logging.h" #include "sdk/android/generated_video_jni/jni/VideoDecoderFactory_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/wrappednativecodec.h" namespace webrtc { diff --git a/sdk/android/src/jni/videodecoderwrapper.cc b/sdk/android/src/jni/videodecoderwrapper.cc index 85c62f944b..a153b65394 100644 --- a/sdk/android/src/jni/videodecoderwrapper.cc +++ b/sdk/android/src/jni/videodecoderwrapper.cc @@ -17,6 +17,7 @@ #include "rtc_base/logging.h" #include "sdk/android/generated_video_jni/jni/VideoDecoderWrapper_jni.h" #include "sdk/android/generated_video_jni/jni/VideoDecoder_jni.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/encodedimage.h" #include "sdk/android/src/jni/videocodecstatus.h" #include "sdk/android/src/jni/videoframe.h" diff --git a/sdk/android/src/jni/videoencoderfactorywrapper.cc b/sdk/android/src/jni/videoencoderfactorywrapper.cc index 328e6fdeb5..be2906856b 100644 --- a/sdk/android/src/jni/videoencoderfactorywrapper.cc +++ b/sdk/android/src/jni/videoencoderfactorywrapper.cc @@ -14,7 +14,8 @@ #include "common_types.h" // NOLINT(build/include) #include "rtc_base/logging.h" #include "sdk/android/generated_video_jni/jni/VideoEncoderFactory_jni.h" -#include "sdk/android/src/jni/class_loader.h" +#include "sdk/android/native_api/jni/class_loader.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/videocodecinfo.h" #include "sdk/android/src/jni/wrappednativecodec.h" diff --git a/sdk/android/src/jni/videoencoderwrapper.cc b/sdk/android/src/jni/videoencoderwrapper.cc index ea25eaec00..2de1a8ae0c 100644 --- a/sdk/android/src/jni/videoencoderwrapper.cc +++ b/sdk/android/src/jni/videoencoderwrapper.cc @@ -23,7 +23,8 @@ #include "rtc_base/timeutils.h" #include "sdk/android/generated_video_jni/jni/VideoEncoderWrapper_jni.h" #include "sdk/android/generated_video_jni/jni/VideoEncoder_jni.h" -#include "sdk/android/src/jni/class_loader.h" +#include "sdk/android/native_api/jni/class_loader.h" +#include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/encodedimage.h" #include "sdk/android/src/jni/videocodecstatus.h" diff --git a/sdk/android/src/jni/videoframe.h b/sdk/android/src/jni/videoframe.h index 66abced074..cd293cc6b2 100644 --- a/sdk/android/src/jni/videoframe.h +++ b/sdk/android/src/jni/videoframe.h @@ -23,6 +23,9 @@ namespace webrtc { namespace jni { +// TODO(sakal): Remove once clients have migrated. +using ::webrtc::JavaParamRef; + class SurfaceTextureHelper; // Open gl texture matrix, in column-major order. Operations are diff --git a/sdk/android/src/jni/wrapped_native_i420_buffer.h b/sdk/android/src/jni/wrapped_native_i420_buffer.h index b7e0fdec16..70ad062cc6 100644 --- a/sdk/android/src/jni/wrapped_native_i420_buffer.h +++ b/sdk/android/src/jni/wrapped_native_i420_buffer.h @@ -14,7 +14,7 @@ #include #include "api/video/video_frame_buffer.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni { diff --git a/sdk/android/src/jni/wrappednativecodec.cc b/sdk/android/src/jni/wrappednativecodec.cc index 36e3db2262..20a2a601c1 100644 --- a/sdk/android/src/jni/wrappednativecodec.cc +++ b/sdk/android/src/jni/wrappednativecodec.cc @@ -12,7 +12,7 @@ #include "sdk/android/generated_video_jni/jni/WrappedNativeVideoDecoder_jni.h" #include "sdk/android/generated_video_jni/jni/WrappedNativeVideoEncoder_jni.h" -#include "sdk/android/src/jni/class_loader.h" +#include "sdk/android/native_api/jni/class_loader.h" #include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/videodecoderwrapper.h" #include "sdk/android/src/jni/videoencoderwrapper.h" diff --git a/sdk/android/src/jni/wrappednativecodec.h b/sdk/android/src/jni/wrappednativecodec.h index 62d3aac692..1d24271865 100644 --- a/sdk/android/src/jni/wrappednativecodec.h +++ b/sdk/android/src/jni/wrappednativecodec.h @@ -16,7 +16,7 @@ #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_encoder.h" -#include "sdk/android/src/jni/scoped_java_ref.h" +#include "sdk/android/native_api/jni/scoped_java_ref.h" namespace webrtc { namespace jni {