OSDN Git Service

fix problem in AudioEffect JNI setup.
authorEric Laurent <elaurent@google.com>
Fri, 24 Sep 2010 19:03:36 +0000 (12:03 -0700)
committerEric Laurent <elaurent@google.com>
Fri, 24 Sep 2010 20:18:14 +0000 (13:18 -0700)
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
media/jni/audioeffect/android_media_AudioEffect.cpp
media/jni/audioeffect/android_media_Visualizer.cpp

index 9d215b7..8409adc 100644 (file)
@@ -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;
 
index b16372d..cb2f0f9 100644 (file)
@@ -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;
 
index 7b271ce..57cafd4 100644 (file)
@@ -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;
 }