Create an experimental Android NDK.

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 <sakal@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21799}
This commit is contained in:
Sami Kalliomäki
2018-01-29 13:18:57 +01:00
committed by Commit Bot
parent 4f6e4f0884
commit 82f96e6a56
69 changed files with 1091 additions and 676 deletions

View File

@ -12,6 +12,7 @@
#include <memory>
#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"

View File

@ -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"

View File

@ -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"

View File

@ -12,6 +12,7 @@
#include <memory>
#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"

View File

@ -1,82 +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/class_loader.h"
#include <algorithm>
#include <string>
#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"
// 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 {
namespace jni {
namespace {
class ClassLoader {
public:
explicit ClassLoader(JNIEnv* env)
: class_loader_(Java_WebRtcClassLoader_getClassLoader(env)) {
class_loader_class_ = reinterpret_cast<jclass>(
env->NewGlobalRef(env->FindClass("java/lang/ClassLoader")));
CHECK_EXCEPTION(env);
load_class_method_ =
env->GetMethodID(class_loader_class_, "loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;");
CHECK_EXCEPTION(env);
}
ScopedJavaLocalRef<jclass> FindClass(JNIEnv* env, const char* c_name) {
// ClassLoader.loadClass expects a classname with components separated by
// dots instead of the slashes that JNIEnv::FindClass expects.
std::string name(c_name);
std::replace(name.begin(), name.end(), '/', '.');
ScopedJavaLocalRef<jstring> j_name = NativeToJavaString(env, name);
const jclass clazz = static_cast<jclass>(env->CallObjectMethod(
class_loader_.obj(), load_class_method_, j_name.obj()));
CHECK_EXCEPTION(env);
return ScopedJavaLocalRef<jclass>(env, clazz);
}
private:
ScopedJavaGlobalRef<jobject> class_loader_;
jclass class_loader_class_;
jmethodID load_class_method_;
};
static ClassLoader* g_class_loader = nullptr;
} // namespace
void InitClassLoader(JNIEnv* env) {
RTC_CHECK(g_class_loader == nullptr);
g_class_loader = new ClassLoader(env);
}
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* name) {
// The class loader will be null in the JNI code called from the ClassLoader
// ctor when we are bootstrapping ourself.
return (g_class_loader == nullptr)
? ScopedJavaLocalRef<jclass>(env, env->FindClass(name))
: g_class_loader->FindClass(env, name);
}
} // namespace jni
} // namespace webrtc

View File

@ -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 <jni.h>
#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<jclass> GetClass(JNIEnv* env, const char* name);
using ::webrtc::InitClassLoader;
} // namespace jni
} // namespace webrtc

View File

@ -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.

View File

@ -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 {

View File

@ -14,7 +14,7 @@
#include <jni.h>
#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 {

View File

@ -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 {

View File

@ -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<jclass>(value);
webrtc::jni::ScopedJavaGlobalRef<jclass> clazz(
webrtc::jni::GetClass(env, class_name));
webrtc::ScopedJavaGlobalRef<jclass> 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(

View File

@ -19,7 +19,7 @@
#include <jni.h>
#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

View File

@ -9,133 +9,13 @@
*/
#include "sdk/android/src/jni/jni_helpers.h"
#include <asm/unistd.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <vector>
#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<JNIEnv*>(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<void**>(&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<long>(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("<noname>");
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<JNIEnv*>(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<jobject>& obj) {
return jni->IsSameObject(obj.obj(), nullptr);
}
ScopedJavaLocalRef<jobject> NewDirectByteBuffer(JNIEnv* env,
void* address,
jlong capacity) {
@ -163,103 +39,6 @@ ScopedJavaLocalRef<jobject> NewDirectByteBuffer(JNIEnv* env,
return buffer;
}
// Given a jstring, reinterprets it to a new native string.
std::string JavaToStdString(JNIEnv* jni, const JavaRef<jstring>& j_string) {
const ScopedJavaLocalRef<jbyteArray> 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<jbyte*>(&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<std::string> JavaToStdVectorStrings(JNIEnv* jni,
const JavaRef<jobject>& list) {
std::vector<std::string> converted_list;
if (!list.is_null()) {
for (const JavaRef<jobject>& str : Iterable(jni, list)) {
converted_list.push_back(JavaToStdString(
jni, JavaParamRef<jstring>(static_cast<jstring>(str.obj()))));
}
}
return converted_list;
}
rtc::Optional<int32_t> JavaToNativeOptionalInt(
JNIEnv* jni,
const JavaRef<jobject>& integer) {
if (IsNull(jni, integer))
return rtc::nullopt;
return JNI_Integer::Java_Integer_intValue(jni, integer);
}
rtc::Optional<bool> JavaToNativeOptionalBool(JNIEnv* jni,
const JavaRef<jobject>& boolean) {
if (IsNull(jni, boolean))
return rtc::nullopt;
return JNI_Boolean::Java_Boolean_booleanValue(jni, boolean);
}
int64_t JavaToNativeLong(JNIEnv* env, const JavaRef<jobject>& j_long) {
return JNI_Long::Java_Long_longValue(env, j_long);
}
ScopedJavaLocalRef<jobject> NativeToJavaBoolean(JNIEnv* env, bool b) {
return JNI_Boolean::Java_Boolean_ConstructorJLB_Z(env, b);
}
ScopedJavaLocalRef<jobject> NativeToJavaInteger(JNIEnv* jni, int32_t i) {
return JNI_Integer::Java_Integer_ConstructorJLI_I(jni, i);
}
ScopedJavaLocalRef<jobject> NativeToJavaLong(JNIEnv* env, int64_t u) {
return JNI_Long::Java_Long_ConstructorJLLO_J(env, u);
}
ScopedJavaLocalRef<jobject> NativeToJavaDouble(JNIEnv* env, double d) {
return JNI_Double::Java_Double_ConstructorJLD_D(env, d);
}
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* env, const char* str) {
jstring j_str = env->NewStringUTF(str);
CHECK_EXCEPTION(env) << "error during NewStringUTF";
return ScopedJavaLocalRef<jstring>(env, j_str);
}
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni,
const std::string& str) {
return NativeToJavaString(jni, str.c_str());
}
ScopedJavaLocalRef<jobject> NativeToJavaInteger(
JNIEnv* jni,
const rtc::Optional<int32_t>& optional_int) {
return optional_int ? NativeToJavaInteger(jni, *optional_int) : nullptr;
}
std::string GetJavaEnumName(JNIEnv* jni, const JavaRef<jobject>& j_enum) {
return JavaToStdString(jni, JNI_Enum::Java_Enum_name(jni, j_enum));
}
std::map<std::string, std::string> JavaToStdMapStrings(
JNIEnv* jni,
const JavaRef<jobject>& j_map) {
const JavaRef<jobject>& j_entry_set = JNI_Map::Java_Map_entrySet(jni, j_map);
std::map<std::string, std::string> result;
for (const JavaRef<jobject>& 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<jobject>& 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<jobject>& 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<jobject>& 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<jobjectArray> NativeToJavaIntegerArray(
JNIEnv* env,
const std::vector<int32_t>& container) {
ScopedJavaLocalRef<jobject> (*convert_function)(JNIEnv*, int32_t) =
&NativeToJavaInteger;
return NativeToJavaObjectArray(env, container, java_lang_Integer_clazz(env),
convert_function);
}
ScopedJavaLocalRef<jobjectArray> NativeToJavaBooleanArray(
JNIEnv* env,
const std::vector<bool>& container) {
return NativeToJavaObjectArray(env, container, java_lang_Boolean_clazz(env),
&NativeToJavaBoolean);
}
ScopedJavaLocalRef<jobjectArray> NativeToJavaDoubleArray(
JNIEnv* env,
const std::vector<double>& container) {
return NativeToJavaObjectArray(env, container, java_lang_Double_clazz(env),
&NativeToJavaDouble);
}
ScopedJavaLocalRef<jobjectArray> NativeToJavaLongArray(
JNIEnv* env,
const std::vector<int64_t>& container) {
return NativeToJavaObjectArray(env, container, java_lang_Long_clazz(env),
&NativeToJavaLong);
}
ScopedJavaLocalRef<jobjectArray> NativeToJavaStringArray(
JNIEnv* env,
const std::vector<std::string>& container) {
ScopedJavaLocalRef<jstring> (*convert)(JNIEnv*, const std::string&) =
&NativeToJavaString;
return NativeToJavaObjectArray(
env, container,
static_cast<jclass>(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<jobject>& key,
const JavaRef<jobject>& 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<jobject>& element) {
JNI_ArrayList::Java_ArrayList_addZ_JUE(env_, j_list_, element);
}
} // namespace jni
} // namespace webrtc

View File

@ -15,24 +15,11 @@
#define SDK_ANDROID_SRC_JNI_JNI_HELPERS_H_
#include <jni.h>
#include <map>
#include <string>
#include <vector>
#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<jobject>& obj);
ScopedJavaLocalRef<jobject> 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<jstring>& j_string);
// Deprecated. Use scoped jobjects instead.
inline std::string JavaToStdString(JNIEnv* jni, jstring j_string) {
return JavaToStdString(jni, JavaParamRef<jstring>(j_string));
}
// Given a List of (UTF-16) jstrings
// return a new vector of UTF-8 native strings.
std::vector<std::string> JavaToStdVectorStrings(JNIEnv* jni,
const JavaRef<jobject>& list);
rtc::Optional<int32_t> JavaToNativeOptionalInt(JNIEnv* jni,
const JavaRef<jobject>& integer);
rtc::Optional<bool> JavaToNativeOptionalBool(JNIEnv* jni,
const JavaRef<jobject>& boolean);
int64_t JavaToNativeLong(JNIEnv* env, const JavaRef<jobject>& j_long);
ScopedJavaLocalRef<jobject> NativeToJavaBoolean(JNIEnv* env, bool b);
ScopedJavaLocalRef<jobject> NativeToJavaInteger(JNIEnv* jni, int32_t i);
ScopedJavaLocalRef<jobject> NativeToJavaLong(JNIEnv* env, int64_t u);
ScopedJavaLocalRef<jobject> NativeToJavaDouble(JNIEnv* env, double d);
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni, const char* str);
ScopedJavaLocalRef<jstring> NativeToJavaString(JNIEnv* jni,
const std::string& str);
ScopedJavaLocalRef<jobject> NativeToJavaInteger(
JNIEnv* jni,
const rtc::Optional<int32_t>& optional_int);
// Parses Map<String, String> to std::map<std::string, std::string>.
std::map<std::string, std::string> JavaToStdMapStrings(
JNIEnv* jni,
const JavaRef<jobject>& j_map);
// Deprecated. Use scoped jobjects instead.
inline std::map<std::string, std::string> JavaToStdMapStrings(JNIEnv* jni,
jobject j_map) {
return JavaToStdMapStrings(jni, JavaParamRef<jobject>(j_map));
}
// Returns the name of a Java enum.
std::string GetJavaEnumName(JNIEnv* jni, const JavaRef<jobject>& 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<jobject>& 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<jobject>& 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<jobject>& operator*();
private:
bool AtEnd() const;
JNIEnv* jni_ = nullptr;
ScopedJavaLocalRef<jobject> iterator_;
ScopedJavaLocalRef<jobject> 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<jobject> iterable_;
RTC_DISALLOW_COPY_AND_ASSIGN(Iterable);
};
// Helper function for converting std::vector<T> into a Java array.
template <typename T, typename Convert>
ScopedJavaLocalRef<jobjectArray> NativeToJavaObjectArray(
JNIEnv* env,
const std::vector<T>& container,
jclass clazz,
Convert convert) {
ScopedJavaLocalRef<jobjectArray> 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<jobjectArray> NativeToJavaIntegerArray(
JNIEnv* env,
const std::vector<int32_t>& container);
ScopedJavaLocalRef<jobjectArray> NativeToJavaBooleanArray(
JNIEnv* env,
const std::vector<bool>& container);
ScopedJavaLocalRef<jobjectArray> NativeToJavaLongArray(
JNIEnv* env,
const std::vector<int64_t>& container);
ScopedJavaLocalRef<jobjectArray> NativeToJavaDoubleArray(
JNIEnv* env,
const std::vector<double>& container);
ScopedJavaLocalRef<jobjectArray> NativeToJavaStringArray(
JNIEnv* env,
const std::vector<std::string>& container);
template <typename T, typename Convert>
std::vector<T> JavaToNativeVector(JNIEnv* env,
const JavaRef<jobjectArray>& j_container,
Convert convert) {
std::vector<T> 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<jobject>(
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<jobject>& element);
ScopedJavaLocalRef<jobject> java_list() { return j_list_; }
private:
JNIEnv* env_;
ScopedJavaLocalRef<jobject> j_list_;
};
template <typename C, typename Convert>
ScopedJavaLocalRef<jobject> 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<jobject>& key, const JavaRef<jobject>& value);
ScopedJavaLocalRef<jobject> GetJavaMap() { return j_map_; }
private:
JNIEnv* env_;
ScopedJavaLocalRef<jobject> j_map_;
};
template <typename C, typename Convert>
ScopedJavaLocalRef<jobject> 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

133
sdk/android/src/jni/jvm.cc Normal file
View File

@ -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 <asm/unistd.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <string>
#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<JNIEnv*>(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<void**>(&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<long>(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("<noname>");
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<JNIEnv*>(env);
RTC_CHECK(!pthread_setspecific(g_jni_ptr, jni)) << "pthread_setspecific";
return jni;
}
} // namespace jni
} // namespace webrtc

32
sdk/android/src/jni/jvm.h Normal file
View File

@ -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 <jni.h>
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_

View File

@ -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 {

View File

@ -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 {

View File

@ -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"

View File

@ -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 {

View File

@ -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 {

View File

@ -11,6 +11,7 @@
#include <memory>
#include "rtc_base/logging.h"
#include "sdk/android/native_api/jni/java_types.h"
#include "sdk/android/src/jni/jni_helpers.h"
namespace webrtc {

View File

@ -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 {

View File

@ -15,7 +15,7 @@
#include <memory>
#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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -14,7 +14,7 @@
#include <jni.h>
#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 {

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -14,7 +14,7 @@
#include <jni.h>
#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 {

View File

@ -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"

View File

@ -14,7 +14,7 @@
#include <jni.h>
#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 {

View File

@ -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"

View File

@ -14,7 +14,7 @@
#include <jni.h>
#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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -15,7 +15,7 @@
#include <memory>
#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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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"

View File

@ -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;

View File

@ -1,205 +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.
*/
// 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_
#include <jni.h>
#include <utility>
#include "rtc_base/constructormagic.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
// whether it is a local or global type.
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:
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:
JavaRef() : obj_(nullptr) {}
explicit JavaRef(jobject obj) : obj_(obj) {}
jobject obj_;
private:
RTC_DISALLOW_COPY_AND_ASSIGN(JavaRef);
};
template <typename T>
class JavaRef : public JavaRef<jobject> {
public:
T obj() const { return static_cast<T>(obj_); }
protected:
JavaRef() : JavaRef<jobject>(nullptr) {}
explicit JavaRef(T obj) : JavaRef<jobject>(obj) {}
private:
RTC_DISALLOW_COPY_AND_ASSIGN(JavaRef);
};
// 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) {}
private:
RTC_DISALLOW_COPY_AND_ASSIGN(JavaParamRef);
};
// 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(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_);
}
// 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;
}
private:
RTC_DISALLOW_COPY_AND_ASSIGN(ScopedJavaGlobalRef);
};
} // namespace jni
} // namespace webrtc
#endif // SDK_ANDROID_SRC_JNI_SCOPED_JAVA_REF_H_

View File

@ -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 {

View File

@ -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 {

View File

@ -14,7 +14,7 @@
#include <jni.h>
#include <stdint.h>
#include "sdk/android/src/jni/scoped_java_ref.h"
#include "sdk/android/native_api/jni/scoped_java_ref.h"
namespace webrtc {
namespace jni {

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -14,7 +14,7 @@
#include <jni.h>
#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 {

View File

@ -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"

View File

@ -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 {