mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Migrate webrtc to stop using its own JniZero mirror classes
Bug: chromium:325408567 Change-Id: I2eb33b077148bf89223f1f69b07339fc9f2d948e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/347921 Reviewed-by: Jeremy Leconte <jleconte@google.com> Commit-Queue: Jeremy Leconte <jleconte@google.com> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#42151}
This commit is contained in:
parent
454d65196e
commit
bc5c5e9d66
21 changed files with 75 additions and 492 deletions
|
@ -185,7 +185,8 @@ void AndroidVoipClient::GetSupportedCodecs(JNIEnv* env) {
|
||||||
webrtc::ScopedJavaLocalRef<jstring> (*convert_function)(
|
webrtc::ScopedJavaLocalRef<jstring> (*convert_function)(
|
||||||
JNIEnv*, const std::string&) = &webrtc::NativeToJavaString;
|
JNIEnv*, const std::string&) = &webrtc::NativeToJavaString;
|
||||||
Java_VoipClient_onGetSupportedCodecsCompleted(
|
Java_VoipClient_onGetSupportedCodecsCompleted(
|
||||||
env_, j_voip_client_, NativeToJavaList(env_, names, convert_function));
|
env_, j_voip_client_,
|
||||||
|
webrtc::NativeToJavaList(env_, names, convert_function));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVoipClient::GetLocalIPAddress(JNIEnv* env) {
|
void AndroidVoipClient::GetLocalIPAddress(JNIEnv* env) {
|
||||||
|
|
|
@ -141,6 +141,7 @@ if (is_android) {
|
||||||
":video_egl_jni",
|
":video_egl_jni",
|
||||||
"../../pc:libjingle_peerconnection",
|
"../../pc:libjingle_peerconnection",
|
||||||
"../../rtc_base:ssl",
|
"../../rtc_base:ssl",
|
||||||
|
"//third_party/jni_zero",
|
||||||
]
|
]
|
||||||
output_extension = "so"
|
output_extension = "so"
|
||||||
}
|
}
|
||||||
|
@ -936,7 +937,6 @@ if (current_os == "linux" || is_android) {
|
||||||
"native_api/jni/class_loader.cc",
|
"native_api/jni/class_loader.cc",
|
||||||
"native_api/jni/java_types.cc",
|
"native_api/jni/java_types.cc",
|
||||||
"native_api/jni/jvm.cc",
|
"native_api/jni/jvm.cc",
|
||||||
"src/jni/jni_generator_helper.cc",
|
|
||||||
"src/jni/jni_generator_helper.h",
|
"src/jni/jni_generator_helper.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -956,6 +956,7 @@ if (current_os == "linux" || is_android) {
|
||||||
"../../api:sequence_checker",
|
"../../api:sequence_checker",
|
||||||
"//api:array_view",
|
"//api:array_view",
|
||||||
"//rtc_base:checks",
|
"//rtc_base:checks",
|
||||||
|
"//third_party/jni_zero",
|
||||||
]
|
]
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1117,10 @@ if (current_os == "linux" || is_android) {
|
||||||
"src/jni/jvm.h",
|
"src/jni/jvm.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
deps = [ "../../rtc_base:checks" ]
|
deps = [
|
||||||
|
"../../rtc_base:checks",
|
||||||
|
"//third_party/jni_zero",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_library("videoframe_jni") {
|
rtc_library("videoframe_jni") {
|
||||||
|
|
|
@ -23,7 +23,7 @@ JNI_FUNCTION_DECLARATION(void,
|
||||||
jclass,
|
jclass,
|
||||||
jstring j_message) {
|
jstring j_message) {
|
||||||
std::string message =
|
std::string message =
|
||||||
JavaToNativeString(jni, JavaParamRef<jstring>(j_message));
|
JavaToNativeString(jni, JavaParamRef<jstring>(jni, j_message));
|
||||||
RTC_LOG(LS_INFO) << message;
|
RTC_LOG(LS_INFO) << message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ JNI_FUNCTION_DECLARATION(jint,
|
||||||
JNIEnv* jni,
|
JNIEnv* jni,
|
||||||
jclass,
|
jclass,
|
||||||
jobject video_frame_buffer) {
|
jobject video_frame_buffer) {
|
||||||
const JavaParamRef<jobject> j_video_frame_buffer(video_frame_buffer);
|
const JavaParamRef<jobject> j_video_frame_buffer(jni, video_frame_buffer);
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> buffer =
|
rtc::scoped_refptr<VideoFrameBuffer> buffer =
|
||||||
JavaToNativeFrameBuffer(jni, j_video_frame_buffer);
|
JavaToNativeFrameBuffer(jni, j_video_frame_buffer);
|
||||||
return static_cast<jint>(buffer->type());
|
return static_cast<jint>(buffer->type());
|
||||||
|
@ -32,7 +32,7 @@ JNI_FUNCTION_DECLARATION(jobject,
|
||||||
JNIEnv* jni,
|
JNIEnv* jni,
|
||||||
jclass,
|
jclass,
|
||||||
jobject i420_buffer) {
|
jobject i420_buffer) {
|
||||||
const JavaParamRef<jobject> j_i420_buffer(i420_buffer);
|
const JavaParamRef<jobject> j_i420_buffer(jni, i420_buffer);
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> buffer =
|
rtc::scoped_refptr<VideoFrameBuffer> buffer =
|
||||||
JavaToNativeFrameBuffer(jni, j_i420_buffer);
|
JavaToNativeFrameBuffer(jni, j_i420_buffer);
|
||||||
const I420BufferInterface* inputBuffer = buffer->GetI420();
|
const I420BufferInterface* inputBuffer = buffer->GetI420();
|
||||||
|
|
|
@ -2,4 +2,5 @@ include_rules = [
|
||||||
"+modules/audio_device/include/audio_device.h",
|
"+modules/audio_device/include/audio_device.h",
|
||||||
"+modules/utility/include/jvm_android.h",
|
"+modules/utility/include/jvm_android.h",
|
||||||
"+system_wrappers/include",
|
"+system_wrappers/include",
|
||||||
|
"+third_party/jni_zero",
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,7 +40,7 @@ void GetDefaultAudioParameters(JNIEnv* env,
|
||||||
jobject application_context,
|
jobject application_context,
|
||||||
AudioParameters* input_parameters,
|
AudioParameters* input_parameters,
|
||||||
AudioParameters* output_parameters) {
|
AudioParameters* output_parameters) {
|
||||||
const JavaParamRef<jobject> j_context(application_context);
|
const JavaParamRef<jobject> j_context(env, application_context);
|
||||||
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
||||||
jni::GetAudioManager(env, j_context);
|
jni::GetAudioManager(env, j_context);
|
||||||
const int input_sample_rate = jni::GetDefaultSampleRate(env, j_audio_manager);
|
const int input_sample_rate = jni::GetDefaultSampleRate(env, j_audio_manager);
|
||||||
|
@ -78,7 +78,7 @@ CreateJavaInputAndAAudioOutputAudioDeviceModule(JNIEnv* env,
|
||||||
jobject application_context) {
|
jobject application_context) {
|
||||||
RTC_DLOG(LS_INFO) << __FUNCTION__;
|
RTC_DLOG(LS_INFO) << __FUNCTION__;
|
||||||
// Get default audio input/output parameters.
|
// Get default audio input/output parameters.
|
||||||
const JavaParamRef<jobject> j_context(application_context);
|
const JavaParamRef<jobject> j_context(env, application_context);
|
||||||
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
||||||
jni::GetAudioManager(env, j_context);
|
jni::GetAudioManager(env, j_context);
|
||||||
AudioParameters input_parameters;
|
AudioParameters input_parameters;
|
||||||
|
@ -104,7 +104,7 @@ rtc::scoped_refptr<AudioDeviceModule> CreateJavaAudioDeviceModule(
|
||||||
jobject application_context) {
|
jobject application_context) {
|
||||||
RTC_DLOG(LS_INFO) << __FUNCTION__;
|
RTC_DLOG(LS_INFO) << __FUNCTION__;
|
||||||
// Get default audio input/output parameters.
|
// Get default audio input/output parameters.
|
||||||
const JavaParamRef<jobject> j_context(application_context);
|
const JavaParamRef<jobject> j_context(env, application_context);
|
||||||
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
||||||
jni::GetAudioManager(env, j_context);
|
jni::GetAudioManager(env, j_context);
|
||||||
AudioParameters input_parameters;
|
AudioParameters input_parameters;
|
||||||
|
@ -155,7 +155,7 @@ CreateJavaInputAndOpenSLESOutputAudioDeviceModule(JNIEnv* env,
|
||||||
jobject application_context) {
|
jobject application_context) {
|
||||||
RTC_DLOG(LS_INFO) << __FUNCTION__;
|
RTC_DLOG(LS_INFO) << __FUNCTION__;
|
||||||
// Get default audio input/output parameters.
|
// Get default audio input/output parameters.
|
||||||
const JavaParamRef<jobject> j_context(application_context);
|
const JavaParamRef<jobject> j_context(env, application_context);
|
||||||
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
const ScopedJavaLocalRef<jobject> j_audio_manager =
|
||||||
jni::GetAudioManager(env, j_context);
|
jni::GetAudioManager(env, j_context);
|
||||||
AudioParameters input_parameters;
|
AudioParameters input_parameters;
|
||||||
|
|
|
@ -21,29 +21,29 @@
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
SdpVideoFormat JavaToNativeVideoCodecInfo(JNIEnv* jni, jobject codec_info) {
|
SdpVideoFormat JavaToNativeVideoCodecInfo(JNIEnv* jni, jobject codec_info) {
|
||||||
return jni::VideoCodecInfoToSdpVideoFormat(jni,
|
return jni::VideoCodecInfoToSdpVideoFormat(
|
||||||
JavaParamRef<jobject>(codec_info));
|
jni, JavaParamRef<jobject>(jni, codec_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VideoDecoderFactory> JavaToNativeVideoDecoderFactory(
|
std::unique_ptr<VideoDecoderFactory> JavaToNativeVideoDecoderFactory(
|
||||||
JNIEnv* jni,
|
JNIEnv* jni,
|
||||||
jobject decoder_factory) {
|
jobject decoder_factory) {
|
||||||
return std::make_unique<jni::VideoDecoderFactoryWrapper>(
|
return std::make_unique<jni::VideoDecoderFactoryWrapper>(
|
||||||
jni, JavaParamRef<jobject>(decoder_factory));
|
jni, JavaParamRef<jobject>(jni, decoder_factory));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VideoEncoderFactory> JavaToNativeVideoEncoderFactory(
|
std::unique_ptr<VideoEncoderFactory> JavaToNativeVideoEncoderFactory(
|
||||||
JNIEnv* jni,
|
JNIEnv* jni,
|
||||||
jobject encoder_factory) {
|
jobject encoder_factory) {
|
||||||
return std::make_unique<jni::VideoEncoderFactoryWrapper>(
|
return std::make_unique<jni::VideoEncoderFactoryWrapper>(
|
||||||
jni, JavaParamRef<jobject>(encoder_factory));
|
jni, JavaParamRef<jobject>(jni, encoder_factory));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VideoEncoder::ResolutionBitrateLimits>
|
std::vector<VideoEncoder::ResolutionBitrateLimits>
|
||||||
JavaToNativeResolutionBitrateLimits(JNIEnv* jni,
|
JavaToNativeResolutionBitrateLimits(JNIEnv* jni,
|
||||||
const jobjectArray j_bitrate_limits_array) {
|
const jobjectArray j_bitrate_limits_array) {
|
||||||
return jni::JavaToNativeResolutionBitrateLimits(
|
return jni::JavaToNativeResolutionBitrateLimits(
|
||||||
jni, JavaParamRef<jobjectArray>(j_bitrate_limits_array));
|
jni, JavaParamRef<jobjectArray>(jni, j_bitrate_limits_array));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "sdk/android/generated_native_api_jni/WebRtcClassLoader_jni.h"
|
#include "sdk/android/generated_native_api_jni/WebRtcClassLoader_jni.h"
|
||||||
#include "sdk/android/native_api/jni/java_types.h"
|
#include "sdk/android/native_api/jni/java_types.h"
|
||||||
#include "sdk/android/native_api/jni/scoped_java_ref.h"
|
#include "third_party/jni_zero/jni_zero.h"
|
||||||
|
|
||||||
// Abort the process if `jni` has a Java exception pending. This macros uses the
|
// Abort the process if `jni` has a Java exception pending. This macros uses the
|
||||||
// comma operator to execute ExceptionDescribe and ExceptionClear ignoring their
|
// comma operator to execute ExceptionDescribe and ExceptionClear ignoring their
|
||||||
|
@ -62,11 +62,18 @@ class ClassLoader {
|
||||||
|
|
||||||
static ClassLoader* g_class_loader = nullptr;
|
static ClassLoader* g_class_loader = nullptr;
|
||||||
|
|
||||||
|
jclass GetClass(JNIEnv* env, const char* class_name, const char* unused) {
|
||||||
|
RTC_CHECK(g_class_loader);
|
||||||
|
return static_cast<jclass>(
|
||||||
|
g_class_loader->FindClass(env, class_name).Release());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void InitClassLoader(JNIEnv* env) {
|
void InitClassLoader(JNIEnv* env) {
|
||||||
RTC_CHECK(g_class_loader == nullptr);
|
RTC_CHECK(g_class_loader == nullptr);
|
||||||
g_class_loader = new ClassLoader(env);
|
g_class_loader = new ClassLoader(env);
|
||||||
|
jni_zero::SetClassResolver(&GetClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* c_name) {
|
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* c_name) {
|
||||||
|
|
|
@ -393,7 +393,7 @@ std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni,
|
||||||
if (!list.is_null()) {
|
if (!list.is_null()) {
|
||||||
for (const JavaRef<jobject>& str : Iterable(jni, list)) {
|
for (const JavaRef<jobject>& str : Iterable(jni, list)) {
|
||||||
converted_list.push_back(JavaToStdString(
|
converted_list.push_back(JavaToStdString(
|
||||||
jni, JavaParamRef<jstring>(static_cast<jstring>(str.obj()))));
|
jni, JavaParamRef<jstring>(jni, static_cast<jstring>(str.obj()))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return converted_list;
|
return converted_list;
|
||||||
|
|
|
@ -340,7 +340,7 @@ inline std::string JavaToStdString(JNIEnv* jni,
|
||||||
|
|
||||||
// Deprecated. Use scoped jobjects instead.
|
// Deprecated. Use scoped jobjects instead.
|
||||||
inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) {
|
inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) {
|
||||||
return JavaToStdString(jni, JavaParamRef<jstring>(j_string));
|
return JavaToStdString(jni, JavaParamRef<jstring>(jni, j_string));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated. Use JavaListToNativeVector<std::string, jstring> instead.
|
// Deprecated. Use JavaListToNativeVector<std::string, jstring> instead.
|
||||||
|
@ -360,7 +360,7 @@ inline std::map<std::string, std::string> JavaToStdMapStrings(
|
||||||
// Deprecated. Use scoped jobjects instead.
|
// Deprecated. Use scoped jobjects instead.
|
||||||
inline std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
|
inline std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
|
||||||
jobject j_map) {
|
jobject j_map) {
|
||||||
return JavaToStdMapStrings(jni, JavaParamRef<jobject>(j_map));
|
return JavaToStdMapStrings(jni, JavaParamRef<jobject>(jni, j_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -8,56 +8,10 @@
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Originally this class is from Chromium.
|
|
||||||
// https://cs.chromium.org/chromium/src/base/android/jni_int_wrapper.h.
|
|
||||||
|
|
||||||
#ifndef SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
#ifndef SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
||||||
#define SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
#define SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
||||||
|
|
||||||
#include <jni.h>
|
#include "third_party/jni_zero/jni_zero.h"
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
// Wrapper used to receive int when calling Java from native. The wrapper
|
|
||||||
// disallows automatic conversion of anything besides int32_t to a jint.
|
|
||||||
// Checking is only done in debugging builds.
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
|
|
||||||
typedef jint JniIntWrapper;
|
|
||||||
|
|
||||||
// This inline is sufficiently trivial that it does not change the
|
|
||||||
// final code generated by g++.
|
|
||||||
inline jint as_jint(JniIntWrapper wrapper) {
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
class JniIntWrapper {
|
|
||||||
public:
|
|
||||||
JniIntWrapper() : i_(0) {}
|
|
||||||
JniIntWrapper(int32_t i) : i_(i) {} // NOLINT(runtime/explicit)
|
|
||||||
explicit JniIntWrapper(const JniIntWrapper& ji) : i_(ji.i_) {}
|
|
||||||
|
|
||||||
jint as_jint() const { return i_; }
|
|
||||||
|
|
||||||
// If you get an "invokes a deleted function" error at the lines below it is
|
|
||||||
// because you used an implicit conversion to convert e.g. a long to an
|
|
||||||
// int32_t when calling Java. We disallow this. If you want a lossy
|
|
||||||
// conversion, please use an explicit conversion in your C++ code.
|
|
||||||
JniIntWrapper(uint32_t) = delete; // NOLINT(runtime/explicit)
|
|
||||||
JniIntWrapper(uint64_t) = delete; // NOLINT(runtime/explicit)
|
|
||||||
JniIntWrapper(int64_t) = delete; // NOLINT(runtime/explicit)
|
|
||||||
|
|
||||||
private:
|
|
||||||
const jint i_;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline jint as_jint(const JniIntWrapper& wrapper) {
|
|
||||||
return wrapper.as_jint();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NDEBUG
|
|
||||||
|
|
||||||
#endif // SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
#endif // SDK_ANDROID_NATIVE_API_JNI_JNI_INT_WRAPPER_H_
|
||||||
|
|
|
@ -19,200 +19,13 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "sdk/android/native_api/jni/jvm.h"
|
#include "sdk/android/native_api/jni/jvm.h"
|
||||||
|
#include "third_party/jni_zero/jni_zero.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
using jni_zero::JavaParamRef;
|
||||||
// Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful
|
using jni_zero::JavaRef;
|
||||||
// for allowing functions to accept a reference without having to mandate
|
using jni_zero::ScopedJavaGlobalRef;
|
||||||
// whether it is a local or global type.
|
using jni_zero::ScopedJavaLocalRef;
|
||||||
template <typename T>
|
|
||||||
class JavaRef;
|
|
||||||
|
|
||||||
// Template specialization of JavaRef, which acts as the base class for all
|
|
||||||
// other JavaRef<> template types. This allows you to e.g. pass JavaRef<jstring>
|
|
||||||
// into a function taking const JavaRef<jobject>&.
|
|
||||||
template <>
|
|
||||||
class JavaRef<jobject> {
|
|
||||||
public:
|
|
||||||
JavaRef(const JavaRef&) = delete;
|
|
||||||
JavaRef& operator=(const JavaRef&) = delete;
|
|
||||||
|
|
||||||
jobject obj() const { return obj_; }
|
|
||||||
bool is_null() const {
|
|
||||||
// This is not valid for weak references. For weak references you need to
|
|
||||||
// use env->IsSameObject(objc_, nullptr), but that should be avoided anyway
|
|
||||||
// since it does not prevent the object from being freed immediately
|
|
||||||
// thereafter. Consequently, programmers should not use this check on weak
|
|
||||||
// references anyway and should first make a ScopedJavaLocalRef or
|
|
||||||
// ScopedJavaGlobalRef before checking if it is null.
|
|
||||||
return obj_ == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
constexpr JavaRef() : obj_(nullptr) {}
|
|
||||||
explicit JavaRef(jobject obj) : obj_(obj) {}
|
|
||||||
jobject obj_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class JavaRef : public JavaRef<jobject> {
|
|
||||||
public:
|
|
||||||
JavaRef(const JavaRef&) = delete;
|
|
||||||
JavaRef& operator=(const JavaRef&) = delete;
|
|
||||||
|
|
||||||
T obj() const { return static_cast<T>(obj_); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
JavaRef() : JavaRef<jobject>(nullptr) {}
|
|
||||||
explicit JavaRef(T obj) : JavaRef<jobject>(obj) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Holds a local reference to a JNI method parameter.
|
|
||||||
// Method parameters should not be deleted, and so this class exists purely to
|
|
||||||
// wrap them as a JavaRef<T> in the JNI binding generator. Do not create
|
|
||||||
// instances manually.
|
|
||||||
template <typename T>
|
|
||||||
class JavaParamRef : public JavaRef<T> {
|
|
||||||
public:
|
|
||||||
// Assumes that `obj` is a parameter passed to a JNI method from Java.
|
|
||||||
// Does not assume ownership as parameters should not be deleted.
|
|
||||||
explicit JavaParamRef(T obj) : JavaRef<T>(obj) {}
|
|
||||||
JavaParamRef(JNIEnv*, T obj) : JavaRef<T>(obj) {}
|
|
||||||
|
|
||||||
JavaParamRef(const JavaParamRef&) = delete;
|
|
||||||
JavaParamRef& operator=(const JavaParamRef&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Holds a local reference to a Java object. The local reference is scoped
|
|
||||||
// to the lifetime of this object.
|
|
||||||
// Instances of this class may hold onto any JNIEnv passed into it until
|
|
||||||
// destroyed. Therefore, since a JNIEnv is only suitable for use on a single
|
|
||||||
// thread, objects of this class must be created, used, and destroyed, on a
|
|
||||||
// single thread.
|
|
||||||
// Therefore, this class should only be used as a stack-based object and from a
|
|
||||||
// single thread. If you wish to have the reference outlive the current
|
|
||||||
// callstack (e.g. as a class member) or you wish to pass it across threads,
|
|
||||||
// use a ScopedJavaGlobalRef instead.
|
|
||||||
template <typename T>
|
|
||||||
class ScopedJavaLocalRef : public JavaRef<T> {
|
|
||||||
public:
|
|
||||||
ScopedJavaLocalRef() = default;
|
|
||||||
ScopedJavaLocalRef(std::nullptr_t) {} // NOLINT(runtime/explicit)
|
|
||||||
|
|
||||||
ScopedJavaLocalRef(JNIEnv* env, const JavaRef<T>& other) : env_(env) {
|
|
||||||
Reset(other.obj(), OwnershipPolicy::RETAIN);
|
|
||||||
}
|
|
||||||
// Allow constructing e.g. ScopedJavaLocalRef<jobject> from
|
|
||||||
// ScopedJavaLocalRef<jstring>.
|
|
||||||
template <typename G>
|
|
||||||
ScopedJavaLocalRef(ScopedJavaLocalRef<G>&& other) : env_(other.env()) {
|
|
||||||
Reset(other.Release(), OwnershipPolicy::ADOPT);
|
|
||||||
}
|
|
||||||
ScopedJavaLocalRef(const ScopedJavaLocalRef& other) : env_(other.env_) {
|
|
||||||
Reset(other.obj(), OwnershipPolicy::RETAIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assumes that `obj` is a reference to a Java object and takes
|
|
||||||
// ownership of this reference. This should preferably not be used
|
|
||||||
// outside of JNI helper functions.
|
|
||||||
ScopedJavaLocalRef(JNIEnv* env, T obj) : JavaRef<T>(obj), env_(env) {}
|
|
||||||
|
|
||||||
~ScopedJavaLocalRef() {
|
|
||||||
if (obj_ != nullptr)
|
|
||||||
env_->DeleteLocalRef(obj_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(const ScopedJavaLocalRef& other) {
|
|
||||||
Reset(other.obj(), OwnershipPolicy::RETAIN);
|
|
||||||
}
|
|
||||||
void operator=(ScopedJavaLocalRef&& other) {
|
|
||||||
Reset(other.Release(), OwnershipPolicy::ADOPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Releases the reference to the caller. The caller *must* delete the
|
|
||||||
// reference when it is done with it. Note that calling a Java method
|
|
||||||
// is *not* a transfer of ownership and Release() should not be used.
|
|
||||||
T Release() {
|
|
||||||
T obj = static_cast<T>(obj_);
|
|
||||||
obj_ = nullptr;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEnv* env() const { return env_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
using JavaRef<T>::obj_;
|
|
||||||
|
|
||||||
enum OwnershipPolicy {
|
|
||||||
// The scoped object takes ownership of an object by taking over an existing
|
|
||||||
// ownership claim.
|
|
||||||
ADOPT,
|
|
||||||
// The scoped object will retain the the object and any initial ownership is
|
|
||||||
// not changed.
|
|
||||||
RETAIN
|
|
||||||
};
|
|
||||||
|
|
||||||
void Reset(T obj, OwnershipPolicy policy) {
|
|
||||||
if (obj_ != nullptr)
|
|
||||||
env_->DeleteLocalRef(obj_);
|
|
||||||
obj_ = (obj != nullptr && policy == OwnershipPolicy::RETAIN)
|
|
||||||
? env_->NewLocalRef(obj)
|
|
||||||
: obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEnv* const env_ = AttachCurrentThreadIfNeeded();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Holds a global reference to a Java object. The global reference is scoped
|
|
||||||
// to the lifetime of this object. This class does not hold onto any JNIEnv*
|
|
||||||
// passed to it, hence it is safe to use across threads (within the constraints
|
|
||||||
// imposed by the underlying Java object that it references).
|
|
||||||
template <typename T>
|
|
||||||
class ScopedJavaGlobalRef : public JavaRef<T> {
|
|
||||||
public:
|
|
||||||
using JavaRef<T>::obj_;
|
|
||||||
|
|
||||||
ScopedJavaGlobalRef() = default;
|
|
||||||
explicit constexpr ScopedJavaGlobalRef(std::nullptr_t) {}
|
|
||||||
ScopedJavaGlobalRef(JNIEnv* env, const JavaRef<T>& other)
|
|
||||||
: JavaRef<T>(static_cast<T>(env->NewGlobalRef(other.obj()))) {}
|
|
||||||
explicit ScopedJavaGlobalRef(const ScopedJavaLocalRef<T>& other)
|
|
||||||
: ScopedJavaGlobalRef(other.env(), other) {}
|
|
||||||
ScopedJavaGlobalRef(ScopedJavaGlobalRef&& other)
|
|
||||||
: JavaRef<T>(other.Release()) {}
|
|
||||||
|
|
||||||
~ScopedJavaGlobalRef() {
|
|
||||||
if (obj_ != nullptr)
|
|
||||||
AttachCurrentThreadIfNeeded()->DeleteGlobalRef(obj_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedJavaGlobalRef(const ScopedJavaGlobalRef&) = delete;
|
|
||||||
ScopedJavaGlobalRef& operator=(const ScopedJavaGlobalRef&) = delete;
|
|
||||||
|
|
||||||
void operator=(const JavaRef<T>& other) {
|
|
||||||
JNIEnv* env = AttachCurrentThreadIfNeeded();
|
|
||||||
if (obj_ != nullptr) {
|
|
||||||
env->DeleteGlobalRef(obj_);
|
|
||||||
}
|
|
||||||
obj_ = other.is_null() ? nullptr : env->NewGlobalRef(other.obj());
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(std::nullptr_t) {
|
|
||||||
if (obj_ != nullptr) {
|
|
||||||
AttachCurrentThreadIfNeeded()->DeleteGlobalRef(obj_);
|
|
||||||
}
|
|
||||||
obj_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Releases the reference to the caller. The caller *must* delete the
|
|
||||||
// reference when it is done with it. Note that calling a Java method
|
|
||||||
// is *not* a transfer of ownership and Release() should not be used.
|
|
||||||
T Release() {
|
|
||||||
T obj = static_cast<T>(obj_);
|
|
||||||
obj_ = nullptr;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline ScopedJavaLocalRef<T> static_java_ref_cast(JNIEnv* env,
|
inline ScopedJavaLocalRef<T> static_java_ref_cast(JNIEnv* env,
|
||||||
|
|
|
@ -20,7 +20,7 @@ std::unique_ptr<rtc::NetworkMonitorFactory> CreateAndroidNetworkMonitorFactory(
|
||||||
JNIEnv* env,
|
JNIEnv* env,
|
||||||
jobject application_context) {
|
jobject application_context) {
|
||||||
return std::make_unique<jni::AndroidNetworkMonitorFactory>(
|
return std::make_unique<jni::AndroidNetworkMonitorFactory>(
|
||||||
env, JavaParamRef<jobject>(application_context));
|
env, JavaParamRef<jobject>(env, application_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<rtc::NetworkMonitorFactory>
|
std::unique_ptr<rtc::NetworkMonitorFactory>
|
||||||
|
|
|
@ -22,7 +22,7 @@ std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> JavaToNativeVideoSink(
|
||||||
JNIEnv* jni,
|
JNIEnv* jni,
|
||||||
jobject video_sink) {
|
jobject video_sink) {
|
||||||
return std::make_unique<jni::VideoSinkWrapper>(
|
return std::make_unique<jni::VideoSinkWrapper>(
|
||||||
jni, JavaParamRef<jobject>(video_sink));
|
jni, JavaParamRef<jobject>(jni, video_sink));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedJavaLocalRef<jobject> NativeToJavaVideoFrame(JNIEnv* jni,
|
ScopedJavaLocalRef<jobject> NativeToJavaVideoFrame(JNIEnv* jni,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
include_rules = [
|
include_rules = [
|
||||||
"+third_party/libyuv",
|
"+third_party/libyuv",
|
||||||
|
"+third_party/jni_zero",
|
||||||
"+call/callfactoryinterface.h",
|
"+call/callfactoryinterface.h",
|
||||||
"+common_video",
|
"+common_video",
|
||||||
"+logging/rtc_event_log/rtc_event_log_factory.h",
|
"+logging/rtc_event_log/rtc_event_log_factory.h",
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "rtc_base/checks.h"
|
||||||
#include "sdk/android/generated_video_jni/JavaI420Buffer_jni.h"
|
#include "sdk/android/generated_video_jni/JavaI420Buffer_jni.h"
|
||||||
#include "third_party/libyuv/include/libyuv/scale.h"
|
#include "third_party/libyuv/include/libyuv/scale.h"
|
||||||
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sdk/android/src/jni/jni_generator_helper.h"
|
|
||||||
|
|
||||||
#include "sdk/android/native_api/jni/class_loader.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
// If `atomic_class_id` set, it'll return immediately. Otherwise, it will look
|
|
||||||
// up the class and store it. If there's a race, we take care to only store one
|
|
||||||
// global reference (and the duplicated effort will happen only once).
|
|
||||||
jclass LazyGetClass(JNIEnv* env,
|
|
||||||
const char* class_name,
|
|
||||||
std::atomic<jclass>* atomic_class_id) {
|
|
||||||
const jclass value = std::atomic_load(atomic_class_id);
|
|
||||||
if (value)
|
|
||||||
return value;
|
|
||||||
webrtc::ScopedJavaGlobalRef<jclass> clazz(webrtc::GetClass(env, class_name));
|
|
||||||
RTC_CHECK(!clazz.is_null()) << class_name;
|
|
||||||
jclass cas_result = nullptr;
|
|
||||||
if (std::atomic_compare_exchange_strong(atomic_class_id, &cas_result,
|
|
||||||
clazz.obj())) {
|
|
||||||
// We sucessfully stored `clazz` in `atomic_class_id`, so we are
|
|
||||||
// intentionally leaking the global ref since it's now stored there.
|
|
||||||
return clazz.Release();
|
|
||||||
} else {
|
|
||||||
// Some other thread came before us and stored a global pointer in
|
|
||||||
// `atomic_class_id`. Relase our global ref and return the ref from the
|
|
||||||
// other thread.
|
|
||||||
return cas_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If `atomic_method_id` set, it'll return immediately. Otherwise, it will look
|
|
||||||
// up the method id and store it. If there's a race, it's ok since the values
|
|
||||||
// are the same (and the duplicated effort will happen only once).
|
|
||||||
template <MethodID::Type type>
|
|
||||||
jmethodID MethodID::LazyGet(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
const char* method_name,
|
|
||||||
const char* jni_signature,
|
|
||||||
std::atomic<jmethodID>* atomic_method_id) {
|
|
||||||
const jmethodID value = std::atomic_load(atomic_method_id);
|
|
||||||
if (value)
|
|
||||||
return value;
|
|
||||||
auto get_method_ptr = type == MethodID::TYPE_STATIC
|
|
||||||
? &JNIEnv::GetStaticMethodID
|
|
||||||
: &JNIEnv::GetMethodID;
|
|
||||||
jmethodID id = (env->*get_method_ptr)(clazz, method_name, jni_signature);
|
|
||||||
CHECK_EXCEPTION(env) << "error during GetMethodID: " << method_name << ", "
|
|
||||||
<< jni_signature;
|
|
||||||
RTC_CHECK(id) << method_name << ", " << jni_signature;
|
|
||||||
std::atomic_store(atomic_method_id, id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Various template instantiations.
|
|
||||||
template jmethodID MethodID::LazyGet<MethodID::TYPE_STATIC>(
|
|
||||||
JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
const char* method_name,
|
|
||||||
const char* jni_signature,
|
|
||||||
std::atomic<jmethodID>* atomic_method_id);
|
|
||||||
|
|
||||||
template jmethodID MethodID::LazyGet<MethodID::TYPE_INSTANCE>(
|
|
||||||
JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
const char* method_name,
|
|
||||||
const char* jni_signature,
|
|
||||||
std::atomic<jmethodID>* atomic_method_id);
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
|
@ -18,15 +18,8 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include "rtc_base/checks.h"
|
#include "third_party/jni_zero/jni_zero_internal.h"
|
||||||
#include "sdk/android/native_api/jni/jni_int_wrapper.h"
|
|
||||||
#include "sdk/android/native_api/jni/scoped_java_ref.h"
|
|
||||||
|
|
||||||
#define CHECK_CLAZZ(env, jcaller, clazz, ...) RTC_DCHECK(clazz);
|
|
||||||
#define CHECK_NATIVE_PTR(env, jcaller, native_ptr, method_name, ...) \
|
|
||||||
RTC_DCHECK(native_ptr) << method_name;
|
|
||||||
|
|
||||||
#define BASE_EXPORT
|
|
||||||
#define JNI_REGISTRATION_EXPORT __attribute__((visibility("default")))
|
#define JNI_REGISTRATION_EXPORT __attribute__((visibility("default")))
|
||||||
|
|
||||||
#if defined(WEBRTC_ARCH_X86)
|
#if defined(WEBRTC_ARCH_X86)
|
||||||
|
@ -39,130 +32,22 @@
|
||||||
#define JNI_GENERATOR_EXPORT extern "C" JNIEXPORT JNICALL
|
#define JNI_GENERATOR_EXPORT extern "C" JNIEXPORT JNICALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBRTC_ARCH_X86)
|
|
||||||
// Dalvik JIT generated code doesn't guarantee 16-byte stack alignment on
|
|
||||||
// x86 - use force_align_arg_pointer to realign the stack at the JNI
|
|
||||||
// boundary. crbug.com/655248
|
|
||||||
#define JNI_BOUNDARY_EXPORT \
|
|
||||||
extern "C" __attribute__((visibility("default"), force_align_arg_pointer))
|
|
||||||
#else
|
|
||||||
#define JNI_BOUNDARY_EXPORT extern "C" __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(COMPONENT_BUILD)
|
|
||||||
#define JNI_ZERO_COMPONENT_BUILD_EXPORT __attribute__((visibility("default")))
|
|
||||||
#else
|
|
||||||
#define JNI_ZERO_COMPONENT_BUILD_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHECK_EXCEPTION(jni) \
|
|
||||||
RTC_CHECK(!jni->ExceptionCheck()) \
|
|
||||||
<< (jni->ExceptionDescribe(), jni->ExceptionClear(), "")
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
using jni_zero::JavaParamRef;
|
||||||
// This function will initialize `atomic_class_id` to contain a global ref to
|
using jni_zero::JavaRef;
|
||||||
// the given class, and will return that ref on subsequent calls. The caller is
|
using jni_zero::ScopedJavaGlobalRef;
|
||||||
// responsible to zero-initialize `atomic_class_id`. It's fine to
|
using jni_zero::ScopedJavaLocalRef;
|
||||||
// simultaneously call this on multiple threads referencing the same
|
|
||||||
// `atomic_method_id`.
|
|
||||||
jclass LazyGetClass(JNIEnv* env,
|
|
||||||
const char* class_name,
|
|
||||||
std::atomic<jclass>* atomic_class_id);
|
|
||||||
|
|
||||||
// This class is a wrapper for JNIEnv Get(Static)MethodID.
|
|
||||||
class MethodID {
|
|
||||||
public:
|
|
||||||
enum Type {
|
|
||||||
TYPE_STATIC,
|
|
||||||
TYPE_INSTANCE,
|
|
||||||
};
|
|
||||||
|
|
||||||
// This function will initialize `atomic_method_id` to contain a ref to
|
|
||||||
// the given method, and will return that ref on subsequent calls. The caller
|
|
||||||
// is responsible to zero-initialize `atomic_method_id`. It's fine to
|
|
||||||
// simultaneously call this on multiple threads referencing the same
|
|
||||||
// `atomic_method_id`.
|
|
||||||
template <Type type>
|
|
||||||
static jmethodID LazyGet(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
const char* method_name,
|
|
||||||
const char* jni_signature,
|
|
||||||
std::atomic<jmethodID>* atomic_method_id);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
namespace jni_zero {
|
// Re-export helpers in the old jni_generator namespace.
|
||||||
// Re-export relevant classes into the namespaces the script expects.
|
// TODO(b/319078685): Remove once all uses of the jni_generator has been
|
||||||
using webrtc::JavaParamRef;
|
// updated.
|
||||||
using webrtc::JavaRef;
|
namespace jni_generator {
|
||||||
using webrtc::LazyGetClass;
|
using jni_zero::internal::kJniStackMarkerValue;
|
||||||
using webrtc::MethodID;
|
|
||||||
using webrtc::ScopedJavaLocalRef;
|
|
||||||
|
|
||||||
inline void CheckException(JNIEnv* env) {
|
|
||||||
CHECK_EXCEPTION(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
// A 32 bit number could be an address on stack. Random 64 bit marker on the
|
|
||||||
// stack is much less likely to be present on stack.
|
|
||||||
constexpr uint64_t kJniStackMarkerValue = 0xbdbdef1bebcade1b;
|
|
||||||
|
|
||||||
// Context about the JNI call with exception checked to be stored in stack.
|
|
||||||
template <bool checked>
|
|
||||||
struct BASE_EXPORT JniJavaCallContext {
|
|
||||||
public:
|
|
||||||
inline JniJavaCallContext() {
|
|
||||||
// TODO(ssid): Implement for other architectures.
|
|
||||||
#if defined(__arm__) || defined(__aarch64__)
|
|
||||||
// This assumes that this method does not increment the stack pointer.
|
|
||||||
asm volatile("mov %0, sp" : "=r"(sp));
|
|
||||||
#else
|
|
||||||
sp = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force no inline to reduce code size.
|
|
||||||
template <jni_zero::MethodID::Type type>
|
|
||||||
void Init(JNIEnv* env,
|
|
||||||
jclass clazz,
|
|
||||||
const char* method_name,
|
|
||||||
const char* jni_signature,
|
|
||||||
std::atomic<jmethodID>* atomic_method_id) {
|
|
||||||
env_ = env;
|
|
||||||
|
|
||||||
// Make sure compiler doesn't optimize out the assignment.
|
|
||||||
memcpy(&marker, &kJniStackMarkerValue, sizeof(kJniStackMarkerValue));
|
|
||||||
// Gets PC of the calling function.
|
|
||||||
pc = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
|
|
||||||
|
|
||||||
method_id_ = jni_zero::MethodID::LazyGet<type>(
|
|
||||||
env, clazz, method_name, jni_signature, atomic_method_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
~JniJavaCallContext() {
|
|
||||||
// Reset so that spurious marker finds are avoided.
|
|
||||||
memset(&marker, 0, sizeof(marker));
|
|
||||||
if (checked) {
|
|
||||||
jni_zero::CheckException(env_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID method_id() { return method_id_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t marker;
|
|
||||||
uintptr_t sp;
|
|
||||||
uintptr_t pc;
|
|
||||||
|
|
||||||
JNIEnv* env_;
|
|
||||||
jmethodID method_id_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(b/319078685): Remove JniJavaCallContextUnchecked once all uses of the
|
// TODO(b/319078685): Remove JniJavaCallContextUnchecked once all uses of the
|
||||||
// jni_generator has been updated.
|
// jni_generator has been updated.
|
||||||
struct BASE_EXPORT JniJavaCallContextUnchecked {
|
struct JniJavaCallContextUnchecked {
|
||||||
inline JniJavaCallContextUnchecked() {
|
inline JniJavaCallContextUnchecked() {
|
||||||
// TODO(ssid): Implement for other architectures.
|
// TODO(ssid): Implement for other architectures.
|
||||||
#if defined(__arm__) || defined(__aarch64__)
|
#if defined(__arm__) || defined(__aarch64__)
|
||||||
|
@ -207,7 +92,7 @@ struct BASE_EXPORT JniJavaCallContextUnchecked {
|
||||||
// TODO(b/319078685): Remove JniJavaCallContextChecked once all uses of the
|
// TODO(b/319078685): Remove JniJavaCallContextChecked once all uses of the
|
||||||
// jni_generator has been updated.
|
// jni_generator has been updated.
|
||||||
// Context about the JNI call with exception unchecked to be stored in stack.
|
// Context about the JNI call with exception unchecked to be stored in stack.
|
||||||
struct BASE_EXPORT JniJavaCallContextChecked {
|
struct JniJavaCallContextChecked {
|
||||||
// Force no inline to reduce code size.
|
// Force no inline to reduce code size.
|
||||||
template <jni_zero::MethodID::Type type>
|
template <jni_zero::MethodID::Type type>
|
||||||
void Init(JNIEnv* env,
|
void Init(JNIEnv* env,
|
||||||
|
@ -229,24 +114,6 @@ static_assert(sizeof(JniJavaCallContextChecked) ==
|
||||||
sizeof(JniJavaCallContextUnchecked),
|
sizeof(JniJavaCallContextUnchecked),
|
||||||
"Stack unwinder cannot work with structs of different sizes.");
|
"Stack unwinder cannot work with structs of different sizes.");
|
||||||
|
|
||||||
} // namespace jni_zero
|
|
||||||
|
|
||||||
namespace jni_zero {
|
|
||||||
namespace internal {
|
|
||||||
using jni_zero::JniJavaCallContext;
|
|
||||||
using jni_zero::JniJavaCallContextChecked;
|
|
||||||
using jni_zero::JniJavaCallContextUnchecked;
|
|
||||||
using webrtc::LazyGetClass;
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace jni_zero
|
|
||||||
|
|
||||||
// Re-export helpers in the old jni_generator namespace.
|
|
||||||
// TODO(b/319078685): Remove once all uses of the jni_generator has been
|
|
||||||
// updated.
|
|
||||||
namespace jni_generator {
|
|
||||||
using jni_zero::JniJavaCallContext;
|
|
||||||
using jni_zero::JniJavaCallContextChecked;
|
|
||||||
using jni_zero::JniJavaCallContextUnchecked;
|
|
||||||
} // namespace jni_generator
|
} // namespace jni_generator
|
||||||
|
|
||||||
// Re-export helpers in the namespaces that the old jni_generator script
|
// Re-export helpers in the namespaces that the old jni_generator script
|
||||||
|
@ -255,11 +122,11 @@ using jni_zero::JniJavaCallContextUnchecked;
|
||||||
// updated.
|
// updated.
|
||||||
namespace base {
|
namespace base {
|
||||||
namespace android {
|
namespace android {
|
||||||
using webrtc::JavaParamRef;
|
using jni_zero::JavaParamRef;
|
||||||
using webrtc::JavaRef;
|
using jni_zero::JavaRef;
|
||||||
using webrtc::LazyGetClass;
|
using jni_zero::MethodID;
|
||||||
using webrtc::MethodID;
|
using jni_zero::ScopedJavaLocalRef;
|
||||||
using webrtc::ScopedJavaLocalRef;
|
using jni_zero::internal::LazyGetClass;
|
||||||
} // namespace android
|
} // namespace android
|
||||||
} // namespace base
|
} // namespace base
|
||||||
#endif // SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
|
#endif // SDK_ANDROID_SRC_JNI_JNI_GENERATOR_HELPER_H_
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "third_party/jni_zero/jni_zero.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace jni {
|
namespace jni {
|
||||||
|
@ -70,11 +71,18 @@ static void CreateJNIPtrKey() {
|
||||||
<< "pthread_key_create";
|
<< "pthread_key_create";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleException(JNIEnv* env) {
|
||||||
|
RTC_CHECK(false) << (env->ExceptionDescribe(), env->ExceptionClear(), "");
|
||||||
|
}
|
||||||
|
|
||||||
jint InitGlobalJniVariables(JavaVM* jvm) {
|
jint InitGlobalJniVariables(JavaVM* jvm) {
|
||||||
RTC_CHECK(!g_jvm) << "InitGlobalJniVariables!";
|
RTC_CHECK(!g_jvm) << "InitGlobalJniVariables!";
|
||||||
g_jvm = jvm;
|
g_jvm = jvm;
|
||||||
RTC_CHECK(g_jvm) << "InitGlobalJniVariables handed NULL?";
|
RTC_CHECK(g_jvm) << "InitGlobalJniVariables handed NULL?";
|
||||||
|
|
||||||
|
jni_zero::SetExceptionHandler(&HandleException);
|
||||||
|
jni_zero::InitVM(jvm);
|
||||||
|
|
||||||
RTC_CHECK(!pthread_once(&g_jni_ptr_once, &CreateJNIPtrKey)) << "pthread_once";
|
RTC_CHECK(!pthread_once(&g_jni_ptr_once, &CreateJNIPtrKey)) << "pthread_once";
|
||||||
|
|
||||||
JNIEnv* jni = nullptr;
|
JNIEnv* jni = nullptr;
|
||||||
|
|
|
@ -50,8 +50,9 @@ JNI_FUNCTION_DECLARATION(void,
|
||||||
jint j_severity,
|
jint j_severity,
|
||||||
jstring j_tag,
|
jstring j_tag,
|
||||||
jstring j_message) {
|
jstring j_message) {
|
||||||
std::string message = JavaToStdString(jni, JavaParamRef<jstring>(j_message));
|
std::string message =
|
||||||
std::string tag = JavaToStdString(jni, JavaParamRef<jstring>(j_tag));
|
JavaToStdString(jni, JavaParamRef<jstring>(jni, j_message));
|
||||||
|
std::string tag = JavaToStdString(jni, JavaParamRef<jstring>(jni, j_tag));
|
||||||
RTC_LOG_TAG(static_cast<rtc::LoggingSeverity>(j_severity), tag.c_str())
|
RTC_LOG_TAG(static_cast<rtc::LoggingSeverity>(j_severity), tag.c_str())
|
||||||
<< message;
|
<< message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,13 @@
|
||||||
|
|
||||||
#include "sdk/android/src/jni/scoped_java_ref_counted.h"
|
#include "sdk/android/src/jni/scoped_java_ref_counted.h"
|
||||||
|
|
||||||
|
#include "rtc_base/checks.h"
|
||||||
#include "sdk/android/generated_base_jni/RefCounted_jni.h"
|
#include "sdk/android/generated_base_jni/RefCounted_jni.h"
|
||||||
|
|
||||||
|
#define CHECK_EXCEPTION(jni) \
|
||||||
|
RTC_CHECK(!jni->ExceptionCheck()) \
|
||||||
|
<< (jni->ExceptionDescribe(), jni->ExceptionClear(), "")
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace jni {
|
namespace jni {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue