Bug 866093 - Set Android Context Objects, use any-thread FindClass, compile AudioCapture classes. r=jesup f=blassey

This commit is contained in:
Gian-Carlo Pascutto 2013-05-02 08:42:53 +02:00
parent a48323893d
commit 1cc401dd5d
11 changed files with 103 additions and 34 deletions

View File

@ -178,6 +178,20 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
// We spawn threads to handle gUM runnables, so we must protect the member vars
MutexAutoLock lock(mMutex);
#ifdef MOZ_WIDGET_ANDROID
jobject context = mozilla::AndroidBridge::Bridge()->GetGlobalContextRef();
// get the JVM
JavaVM *jvm = mozilla::AndroidBridge::Bridge()->GetVM();
JNIEnv *env;
jvm->AttachCurrentThread(&env, NULL);
webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context);
env->DeleteGlobalRef(context);
#endif
if (!mVoiceEngine) {
mVoiceEngine = webrtc::VoiceEngine::Create();
if (!mVoiceEngine) {

View File

@ -15,6 +15,9 @@
#include "voice_engine/include/voe_errors.h"
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidJNIWrapper.h"
#endif
namespace mozilla {
@ -136,6 +139,24 @@ MediaConduitErrorCode WebrtcAudioConduit::Init(WebrtcAudioConduit *other)
MOZ_ASSERT(other->mVoiceEngine);
mVoiceEngine = other->mVoiceEngine;
} else {
#ifdef MOZ_WIDGET_ANDROID
jobject context = jsjni_GetGlobalContextRef();
// get the JVM
JavaVM *jvm = jsjni_GetVM();
JNIEnv* env;
if (jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
CSFLogError(logTag, "%s: could not get Java environment", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
jvm->AttachCurrentThread(&env, NULL);
webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context);
env->DeleteGlobalRef(context);
#endif
//Per WebRTC APIs below function calls return NULL on failure
if(!(mVoiceEngine = webrtc::VoiceEngine::Create()))
{

View File

@ -9,6 +9,10 @@
#include "AudioConduit.h"
#include "video_engine/include/vie_errors.h"
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidJNIWrapper.h"
#endif
namespace mozilla {
static const char* logTag ="WebrtcVideoSessionConduit";
@ -98,6 +102,24 @@ MediaConduitErrorCode WebrtcVideoConduit::Init()
CSFLogDebug(logTag, "%s ", __FUNCTION__);
#ifdef MOZ_WIDGET_ANDROID
jobject context = jsjni_GetGlobalContextRef();
// get the JVM
JavaVM *jvm = jsjni_GetVM();
JNIEnv* env;
if (jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
CSFLogError(logTag, "%s: could not get Java environment", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
jvm->AttachCurrentThread(&env, NULL);
webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context);
env->DeleteGlobalRef(context);
#endif
if( !(mVideoEngine = webrtc::VideoEngine::Create()) )
{
CSFLogError(logTag, "%s Unable to create video engine ", __FUNCTION__);

View File

@ -26,12 +26,14 @@
#include "thread_wrapper.h"
#include "event_wrapper.h"
#include "AndroidJNIWrapper.h"
namespace webrtc
{
// TODO(leozwang): Refactor jni and the following global variables, a
// good example is jni_helper in Chromium.
JavaVM* AudioDeviceAndroidJni::globalJvm = NULL;
JNIEnv* AudioDeviceAndroidJni::globalJNIEnv = NULL;
jobject AudioDeviceAndroidJni::globalContext = NULL;
jclass AudioDeviceAndroidJni::globalScClass = NULL;
@ -45,62 +47,54 @@ jclass AudioDeviceAndroidJni::globalScClass = NULL;
WebRtc_Word32 AudioDeviceAndroidJni::SetAndroidAudioDeviceObjects(
void* javaVM,
void* env,
void* context) {
__android_log_print(ANDROID_LOG_DEBUG, "WEBRTC", "JNI:%s", __FUNCTION__);
WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, -1,
"%s called", __FUNCTION__);
// TODO(leozwang): Make this function thread-safe.
globalJvm = reinterpret_cast<JavaVM*>(javaVM);
JNIEnv* env = NULL;
// Check if we already got a reference
if (globalJvm && !globalScClass) {
if (globalJvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioDevice, -1,
"%s: could not get Java environment", __FUNCTION__);
return -1;
}
globalJvm->AttachCurrentThread(&env, NULL);
if (env) {
globalJNIEnv = reinterpret_cast<JNIEnv*>(env);
// Get java class type (note path to class packet).
jclass javaScClassLocal = globalJNIEnv->FindClass(
"org/webrtc/voiceengine/WebRTCAudioDevice");
if (!javaScClassLocal) {
globalScClass = jsjni_GetGlobalClassRef(AudioCaptureClass);
if (!globalScClass) {
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;
}
globalContext = globalJNIEnv->NewGlobalRef(
globalContext = env->NewGlobalRef(
reinterpret_cast<jobject>(context));
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);
}
else { // User is resetting the env variable
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1,
"%s: env is NULL, assuming deinit", __FUNCTION__);
if (!globalJNIEnv) {
if (!env) {
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1,
"%s: saved env already NULL", __FUNCTION__);
return 0;
}
globalJNIEnv->DeleteGlobalRef(globalScClass);
env->DeleteGlobalRef(globalScClass);
globalScClass = reinterpret_cast<jclass>(NULL);
globalJNIEnv->DeleteGlobalRef(globalContext);
env->DeleteGlobalRef(globalContext);
globalContext = reinterpret_cast<jobject>(NULL);
globalJNIEnv = reinterpret_cast<JNIEnv*>(NULL);
}
return 0;
@ -2211,7 +2205,7 @@ WebRtc_Word32 AudioDeviceAndroidJni::InitJavaResources()
}
WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id,
"construct object", __FUNCTION__);
"%s: construct object", __FUNCTION__);
// construct the object
jobject javaScObjLocal = env->NewObject(_javaScClass, cid);

View File

@ -20,6 +20,8 @@
#include <jni.h> // For accessing AudioDeviceAndroid java class
#define AudioCaptureClass "org/webrtc/voiceengine/WebRTCAudioDevice"
namespace webrtc
{
class EventWrapper;
@ -32,7 +34,6 @@ class AudioDeviceAndroidJni : public AudioDeviceGeneric {
~AudioDeviceAndroidJni();
static WebRtc_Word32 SetAndroidAudioDeviceObjects(void* javaVM,
void* env,
void* context);
virtual WebRtc_Word32 ActiveAudioLayer(

View File

@ -67,6 +67,7 @@
}],
['OS=="android"', {
'include_dirs': [
'$(topsrcdir)/widget/android',
'android',
],
}], # OS==android

View File

@ -82,7 +82,7 @@ public:
// receives callbacks for generated trace messages.
static int SetTraceCallback(TraceCallback* callback);
static int SetAndroidObjects(void* javaVM, void* env, void* context);
static int SetAndroidObjects(void* javaVM, void* context);
protected:
VoiceEngine() {}

View File

@ -142,11 +142,11 @@ bool VoiceEngine::Delete(VoiceEngine*& voiceEngine)
return true;
}
int VoiceEngine::SetAndroidObjects(void* javaVM, void* env, void* context)
int VoiceEngine::SetAndroidObjects(void* javaVM, void* context)
{
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
return AudioDeviceAndroidJni::SetAndroidAudioDeviceObjects(
javaVM, env, context);
javaVM, context);
#else
return -1;
#endif

View File

@ -245,8 +245,13 @@ WEBRTC_VIDEO_CAPTURE_JAVA_FILES = \
VideoCaptureDeviceInfoAndroid.java \
$(NULL)
WEBRTC_AUDIO_CAPTURE_JAVA_FILES = \
WebRTCAudioDevice.java \
$(NULL)
WEBRTC_JAVA_FILES = \
$(addprefix $(DEPTH)/media/webrtc/trunk/webrtc/modules/video_capture/android/java/org/webrtc/videoengine/, $(WEBRTC_VIDEO_CAPTURE_JAVA_FILES)) \
$(addprefix $(DEPTH)/media/webrtc/trunk/webrtc/modules/audio_device/android/org/webrtc/voiceengine/, $(WEBRTC_AUDIO_CAPTURE_JAVA_FILES)) \
$(NULL)
endif

View File

@ -119,4 +119,14 @@ extern "C" {
mozilla::AutoLocalJNIFrame jniFrame(env);
return env->CallStaticIntMethodA(cls, method, values);
}
__attribute__ ((visibility("default")))
jobject jsjni_GetGlobalContextRef() {
return mozilla::AndroidBridge::Bridge()->GetGlobalContextRef();
}
__attribute__ ((visibility("default")))
JavaVM* jsjni_GetVM() {
return mozilla::AndroidBridge::GetVM();
}
}

View File

@ -26,6 +26,7 @@ extern "C" jmethodID jsjni_GetStaticMethodID(jclass methodClass,
extern "C" bool jsjni_ExceptionCheck();
extern "C" void jsjni_CallStaticVoidMethodA(jclass cls, jmethodID method, jvalue *values);
extern "C" int jsjni_CallStaticIntMethodA(jclass cls, jmethodID method, jvalue *values);
extern "C" jobject jsjni_GetGlobalContextRef();
extern "C" JavaVM* jsjni_GetVM();
#endif /* AndroidJNIWrapper_h__ */