Android: Fixes crash when exiting WebRTCDemo.

BUG=2738
R=fischman@webrtc.org, niklas.enbom@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/6179004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5365 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrike@webrtc.org 2014-01-10 22:58:06 +00:00
parent 7cc64b3747
commit 573a1b45b5
10 changed files with 124 additions and 103 deletions

View File

@ -30,6 +30,12 @@ class AudioDeviceTemplate : public AudioDeviceGeneric {
}
return InputType::SetAndroidAudioDeviceObjects(javaVM, env, context);
}
static void ClearAndroidAudioDeviceObjects() {
OutputType::ClearAndroidAudioDeviceObjects();
InputType::ClearAndroidAudioDeviceObjects();
}
explicit AudioDeviceTemplate(const int32_t id)
: output_(id),
input_(id, &output_) {

View File

@ -37,62 +37,62 @@ jclass AudioRecordJni::globalScClass = NULL;
int32_t AudioRecordJni::SetAndroidAudioDeviceObjects(void* javaVM, void* env,
void* context) {
assert(env);
globalJvm = reinterpret_cast<JavaVM*>(javaVM);
if (env) {
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;
}
globalContext = globalJNIEnv->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);
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
}
else { // User is resetting the env variable
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1,
"%s: env is NULL, assuming deinit", __FUNCTION__);
if (!globalJNIEnv) {
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1,
"%s: saved env already NULL", __FUNCTION__);
return 0;
}
globalJNIEnv->DeleteGlobalRef(globalScClass);
globalScClass = reinterpret_cast<jclass>(NULL);
globalJNIEnv->DeleteGlobalRef(globalContext);
globalContext = reinterpret_cast<jobject>(NULL);
globalJNIEnv = reinterpret_cast<JNIEnv*>(NULL);
// 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(
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);
return 0;
}
void AudioRecordJni::ClearAndroidAudioDeviceObjects() {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1,
"%s: env is NULL, assuming deinit", __FUNCTION__);
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);
globalScClass = reinterpret_cast<jclass>(NULL);
globalJNIEnv = reinterpret_cast<JNIEnv*>(NULL);
}
AudioRecordJni::AudioRecordJni(
const int32_t id, PlayoutDelayProvider* delay_provider)
: _javaVM(NULL),

View File

@ -31,6 +31,7 @@ class AudioRecordJni {
public:
static int32_t SetAndroidAudioDeviceObjects(void* javaVM, void* env,
void* context);
static void ClearAndroidAudioDeviceObjects();
AudioRecordJni(const int32_t id, PlayoutDelayProvider* delay_provider);
~AudioRecordJni();

View File

@ -36,62 +36,61 @@ jclass AudioTrackJni::globalScClass = NULL;
int32_t AudioTrackJni::SetAndroidAudioDeviceObjects(void* javaVM, void* env,
void* context) {
assert(env);
globalJvm = reinterpret_cast<JavaVM*>(javaVM);
if (env) {
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));
if (!globalScClass) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create reference", __FUNCTION__);
return -1;
}
globalContext = globalJNIEnv->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) {
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1,
"%s: saved env already NULL", __FUNCTION__);
return 0;
}
globalJNIEnv->DeleteGlobalRef(globalScClass);
globalScClass = reinterpret_cast<jclass>(NULL);
globalJNIEnv->DeleteGlobalRef(globalContext);
globalContext = reinterpret_cast<jobject>(NULL);
globalJNIEnv = reinterpret_cast<JNIEnv*>(NULL);
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));
if (!globalScClass) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
"%s: could not create reference", __FUNCTION__);
return -1;
}
globalContext = globalJNIEnv->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);
return 0;
}
void AudioTrackJni::ClearAndroidAudioDeviceObjects() {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1,
"%s: env is NULL, assuming deinit", __FUNCTION__);
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);
globalScClass = reinterpret_cast<jclass>(NULL);
globalJNIEnv = reinterpret_cast<JNIEnv*>(NULL);
}
AudioTrackJni::AudioTrackJni(const int32_t id)
: _javaVM(NULL),
_jniEnvPlay(NULL),

View File

@ -30,7 +30,7 @@ class AudioTrackJni : public PlayoutDelayProvider {
public:
static int32_t SetAndroidAudioDeviceObjects(void* javaVM, void* env,
void* context);
static void ClearAndroidAudioDeviceObjects();
explicit AudioTrackJni(const int32_t id);
virtual ~AudioTrackJni();

View File

@ -75,6 +75,9 @@ int32_t OpenSlesInput::SetAndroidAudioDeviceObjects(void* javaVM,
return 0;
}
void OpenSlesInput::ClearAndroidAudioDeviceObjects() {
}
int32_t OpenSlesInput::Init() {
assert(!initialized_);

View File

@ -41,6 +41,7 @@ class OpenSlesInput {
static int32_t SetAndroidAudioDeviceObjects(void* javaVM,
void* env,
void* context);
static void ClearAndroidAudioDeviceObjects();
// Main initializaton and termination
int32_t Init();

View File

@ -76,6 +76,10 @@ int32_t OpenSlesOutput::SetAndroidAudioDeviceObjects(void* javaVM,
return 0;
}
void OpenSlesOutput::ClearAndroidAudioDeviceObjects() {
AudioManagerJni::ClearAndroidAudioDeviceObjects();
}
int32_t OpenSlesOutput::Init() {
assert(!initialized_);

View File

@ -41,6 +41,7 @@ class OpenSlesOutput : public PlayoutDelayProvider {
static int32_t SetAndroidAudioDeviceObjects(void* javaVM,
void* env,
void* context);
static void ClearAndroidAudioDeviceObjects();
// Main initializaton and termination
int32_t Init();

View File

@ -149,12 +149,18 @@ int VoiceEngine::SetAndroidObjects(void* javaVM, void* env, void* context)
{
#ifdef WEBRTC_ANDROID
#ifdef WEBRTC_ANDROID_OPENSLES
return AudioDeviceTemplate<OpenSlesInput, OpenSlesOutput>::
SetAndroidAudioDeviceObjects(javaVM, env, context);
typedef AudioDeviceTemplate<OpenSlesInput, OpenSlesOutput>
AudioDeviceInstance;
#else
return AudioDeviceTemplate<AudioRecordJni, AudioTrackJni>::
SetAndroidAudioDeviceObjects(javaVM, env, context);
typedef AudioDeviceTemplate<AudioRecordJni, AudioTrackJni>
AudioDeviceInstance;
#endif
if (javaVM && env && context) {
AudioDeviceInstance::SetAndroidAudioDeviceObjects(javaVM, env, context);
} else {
AudioDeviceInstance::ClearAndroidAudioDeviceObjects();
}
return 0;
#else
return -1;
#endif