From 2fb43ef8c0b922c1bd0d7cb6867e30d702d4bdb8 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 24 Sep 2010 12:03:36 -0700 Subject: [PATCH] fix problem in AudioEffect JNI setup. There is a problem in AudioEffect and Visualizer native_setup() methods that causes a crash in the application after the mediaserver process has crashed and restarted. The problem is that the native AudioEffect/Visualizer constructor is called while the JNI is in critical state after calling GetPrimitiveArrayCritical(). As the mediaserver process just restarted, the first call to AudioSystem will cause the binder IAudioflinger interface to be reteived and a callback send to AudioSystem JNI to clear the mediaserver error state. This will call env->FindClass() and crash due to the JNI being in critical state. Also fixed a similar problem in AudioTrack JNI Change-Id: I4a9026a3e26c7f78d9b4b4bec1aac90fbee2ab62 --- core/jni/android_media_AudioTrack.cpp | 32 +++++++++++-------- .../audioeffect/android_media_AudioEffect.cpp | 16 ++++------ .../audioeffect/android_media_Visualizer.cpp | 17 ++++------ 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 9d215b72d8bec..8409adc9862d6 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -252,21 +252,23 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this); lpJniStorage->mStreamType = atStreamType; - - jint* nSession = NULL; - if (jSession) { - nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); - if (nSession == NULL) { - LOGE("Error creating AudioTrack: Error retrieving session id pointer"); - delete lpJniStorage; - return AUDIOTRACK_ERROR; - } - } else { + + if (jSession == NULL) { LOGE("Error creating AudioTrack: invalid session ID pointer"); delete lpJniStorage; return AUDIOTRACK_ERROR; } + jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); + if (nSession == NULL) { + LOGE("Error creating AudioTrack: Error retrieving session id pointer"); + delete lpJniStorage; + return AUDIOTRACK_ERROR; + } + int sessionId = nSession[0]; + env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); + nSession = NULL; + // create the native AudioTrack object AudioTrack* lpTrack = new AudioTrack(); if (lpTrack == NULL) { @@ -288,7 +290,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack 0,// shared mem true,// thread can call Java - nSession[0]);// audio session ID + sessionId);// audio session ID } else if (memoryMode == javaAudioTrackFields.MODE_STATIC) { // AudioTrack is using shared memory @@ -309,7 +311,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack lpJniStorage->mMemBase,// shared mem true,// thread can call Java - nSession[0]);// audio session ID + sessionId);// audio session ID } if (lpTrack->initCheck() != NO_ERROR) { @@ -317,9 +319,13 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th goto native_init_failure; } + nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); + if (nSession == NULL) { + LOGE("Error creating AudioTrack: Error retrieving session id pointer"); + goto native_init_failure; + } // read the audio session ID back from AudioTrack in case we create a new session nSession[0] = lpTrack->getSessionId(); - env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); nSession = NULL; diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp index b16372d54de55..cb2f0f90286b7 100644 --- a/media/jni/audioeffect/android_media_AudioEffect.cpp +++ b/media/jni/audioeffect/android_media_AudioEffect.cpp @@ -304,14 +304,7 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t lpJniStorage->mCallbackData.audioEffect_class, &lpJniStorage->mCallbackData); - if (jId) { - nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL); - if (nId == NULL) { - LOGE("setup: Error retrieving id pointer"); - lStatus = AUDIOEFFECT_ERROR_BAD_VALUE; - goto setup_failure; - } - } else { + if (jId == NULL) { LOGE("setup: NULL java array for id pointer"); lStatus = AUDIOEFFECT_ERROR_BAD_VALUE; goto setup_failure; @@ -336,8 +329,13 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t goto setup_failure; } + nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL); + if (nId == NULL) { + LOGE("setup: Error retrieving id pointer"); + lStatus = AUDIOEFFECT_ERROR_BAD_VALUE; + goto setup_failure; + } nId[0] = lpAudioEffect->id(); - env->ReleasePrimitiveArrayCritical(jId, nId, 0); nId = NULL; diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp index 7b271cec448d5..57cafd458fdd9 100644 --- a/media/jni/audioeffect/android_media_Visualizer.cpp +++ b/media/jni/audioeffect/android_media_Visualizer.cpp @@ -246,14 +246,7 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th lpJniStorage->mCallbackData.visualizer_class, &lpJniStorage->mCallbackData); - if (jId) { - nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL); - if (nId == NULL) { - LOGE("setup: Error retrieving id pointer"); - lStatus = VISUALIZER_ERROR_BAD_VALUE; - goto setup_failure; - } - } else { + if (jId == NULL) { LOGE("setup: NULL java array for id pointer"); lStatus = VISUALIZER_ERROR_BAD_VALUE; goto setup_failure; @@ -275,8 +268,13 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th goto setup_failure; } + nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL); + if (nId == NULL) { + LOGE("setup: Error retrieving id pointer"); + lStatus = VISUALIZER_ERROR_BAD_VALUE; + goto setup_failure; + } nId[0] = lpVisualizer->id(); - env->ReleasePrimitiveArrayCritical(jId, nId, 0); nId = NULL; @@ -424,7 +422,6 @@ android_media_visualizer_native_getWaveForm(JNIEnv *env, jobject thiz, jbyteArra jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform)); env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0); - return status; }