Bug 987979: Patch 9 - Use Android JNI Wrappers for off-thread FindClass and Global Context. r=blassey

This commit is contained in:
Randell Jesup 2014-05-29 17:05:15 -04:00
Родитель 3b05d7cae8
Коммит 07bd430f23
4 изменённых файлов: 45 добавлений и 54 удалений

Просмотреть файл

@ -41,35 +41,25 @@ int32_t AudioRecordJni::SetAndroidAudioDeviceObjects(void* javaVM, void* env,
globalJvm = reinterpret_cast<JavaVM*>(javaVM);
globalJNIEnv = reinterpret_cast<JNIEnv*>(env);
// Get java class type (note path to class packet).
jclass javaScClassLocal = globalJNIEnv->FindClass(
"org/webrtc/voiceengine/WebRtcAudioRecord");
if (!javaScClassLocal) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not find java class", __FUNCTION__);
return -1; // exception thrown
}
// Create a global reference to the class (to tell JNI that we are
// referencing it after this function has returned).
globalScClass = reinterpret_cast<jclass> (
globalJNIEnv->NewGlobalRef(javaScClassLocal));
if (!globalScClass) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create reference", __FUNCTION__);
return -1;
globalScClass = jsjni_GetGlobalClassRef(
"org/webrtc/voiceengine/WebRtcAudioRecord");
if (!globalScClass) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not find java class", __FUNCTION__);
return -1; // exception thrown
}
}
globalContext = globalJNIEnv->NewGlobalRef(
reinterpret_cast<jobject>(context));
if (!globalContext) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create context reference", __FUNCTION__);
return -1;
globalContext = jsjni_GetGlobalContextRef();
if (!globalContext) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create context reference", __FUNCTION__);
return -1;
}
}
// Delete local class ref, we only use the global ref
globalJNIEnv->DeleteLocalRef(javaScClassLocal);
return 0;
}
@ -77,14 +67,13 @@ void AudioRecordJni::ClearAndroidAudioDeviceObjects() {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1,
"%s: env is NULL, assuming deinit", __FUNCTION__);
globalJvm = NULL;;
globalJvm = NULL;
if (!globalJNIEnv) {
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1,
"%s: saved env already NULL", __FUNCTION__);
return;
}
globalJNIEnv->DeleteGlobalRef(globalContext);
globalContext = reinterpret_cast<jobject>(NULL);
globalJNIEnv->DeleteGlobalRef(globalScClass);

Просмотреть файл

@ -27,6 +27,8 @@
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "AndroidJNIWrapper.h"
namespace webrtc {
JavaVM* AudioTrackJni::globalJvm = NULL;
@ -39,35 +41,26 @@ int32_t AudioTrackJni::SetAndroidAudioDeviceObjects(void* javaVM, void* env,
assert(env);
globalJvm = reinterpret_cast<JavaVM*>(javaVM);
globalJNIEnv = reinterpret_cast<JNIEnv*>(env);
// Get java class type (note path to class packet).
jclass javaScClassLocal = globalJNIEnv->FindClass(
"org/webrtc/voiceengine/WebRtcAudioTrack");
if (!javaScClassLocal) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not find java class", __FUNCTION__);
return -1; // exception thrown
}
// Create a global reference to the class (to tell JNI that we are
// referencing it after this function has returned).
globalScClass = reinterpret_cast<jclass> (
globalJNIEnv->NewGlobalRef(javaScClassLocal));
// Check if we already got a reference
if (!globalScClass) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create reference", __FUNCTION__);
return -1;
// Get java class type (note path to class packet).
globalScClass = jsjni_GetGlobalClassRef("org/webrtc/voiceengine/WebRtcAudioTrack");
if (!globalScClass) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not find java class", __FUNCTION__);
return -1; // exception thrown
}
}
globalContext = globalJNIEnv->NewGlobalRef(
reinterpret_cast<jobject>(context));
if (!globalContext) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create context reference", __FUNCTION__);
return -1;
globalContext = jsjni_GetGlobalContextRef();
if (!globalContext) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create context reference", __FUNCTION__);
return -1;
}
}
// Delete local class ref, we only use the global ref
globalJNIEnv->DeleteLocalRef(javaScClassLocal);
return 0;
}
@ -82,7 +75,8 @@ void AudioTrackJni::ClearAndroidAudioDeviceObjects() {
return;
}
globalJNIEnv->DeleteGlobalRef(globalContext);
// No need to delete the shared global context ref.
// globalJNIEnv->DeleteGlobalRef(globalContext);
globalContext = reinterpret_cast<jobject>(NULL);
globalJNIEnv->DeleteGlobalRef(globalScClass);

Просмотреть файл

@ -20,6 +20,8 @@
#include "webrtc/system_wrappers/interface/ref_count.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "AndroidJNIWrapper.h"
namespace webrtc
{
@ -92,8 +94,11 @@ void DeviceInfoAndroid::Initialize(JNIEnv* jni) {
g_camera_info = new std::vector<AndroidCameraInfo>();
jclass j_info_class =
jni->FindClass("org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid");
jsjni_GetGlobalClassRef("org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid");
jclass j_cap_class =
jsjni_GetGlobalClassRef("org/webrtc/videoengine/CaptureCapabilityAndroid");
assert(j_info_class);
assert(j_cap_class);
jmethodID j_initialize = jni->GetStaticMethodID(
j_info_class, "getDeviceInfo",
"()[Lorg/webrtc/videoengine/CaptureCapabilityAndroid;");
@ -157,6 +162,9 @@ void DeviceInfoAndroid::Initialize(JNIEnv* jni) {
jni->ReleaseIntArrayElements(widthResArray, widths, JNI_ABORT);
jni->ReleaseIntArrayElements(heightResArray, heights, JNI_ABORT);
}
jni->DeleteGlobalRef(j_info_class);
jni->DeleteGlobalRef(j_cap_class);
}
VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo(

Просмотреть файл

@ -45,16 +45,16 @@ void JNICALL ProvideCameraFrame(
}
int32_t SetCaptureAndroidVM(JavaVM* javaVM) {
if (g_java_capturer_class)
return 0;
g_jvm = javaVM;
AttachThreadScoped ats(g_jvm);
videocapturemodule::DeviceInfoAndroid::Initialize(ats.env());
jclass j_capture_class =
ats.env()->FindClass("org/webrtc/videoengine/VideoCaptureAndroid");
assert(j_capture_class);
g_java_capturer_class =
reinterpret_cast<jclass>(ats.env()->NewGlobalRef(j_capture_class));
jsjni_GetGlobalClassRef("org/webrtc/videoengine/VideoCaptureAndroid");
assert(g_java_capturer_class);
JNINativeMethod native_method = {