From 0d68bc11dde560e6b67ec066c829f5c0bd02fba4 Mon Sep 17 00:00:00 2001 From: Atneya Nair Date: Wed, 18 May 2022 18:23:44 -0400 Subject: [PATCH] Replace locking JNI array methods GetPrimitiveArrayCritical takes a global lock within the runtime to avoid a copy. This restricts what type of calls can be made in the critical section. Since we utilize array read methods primarily for extremely small sized arrays (usually one element), the copy is cheap. Test: Compiles Bug: 231038541 Change-Id: I5bc53d8ca46677fefb3b52b0cd54d90776edcf83 --- core/jni/android_media_AudioRecord.cpp | 8 +++--- core/jni/android_media_AudioTrack.cpp | 27 ++++++++++--------- .../android_media_SourceDefaultEffect.cpp | 4 +-- .../android_media_StreamDefaultEffect.cpp | 6 ++--- .../audioeffect/android_media_Visualizer.cpp | 14 +++++----- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 8012e0c5ac572..30333d20d7759 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -161,13 +161,13 @@ static jint android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject w return (jint) AUDIO_JAVA_ERROR; } - jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); + jint* nSession = env->GetIntArrayElements(jSession, nullptr /* isCopy */); if (nSession == NULL) { ALOGE("Error creating AudioRecord: Error retrieving session id pointer"); return (jint) AUDIO_JAVA_ERROR; } audio_session_t sessionId = (audio_session_t) nSession[0]; - env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); + env->ReleaseIntArrayElements(jSession, nSession, 0 /* mode */); nSession = NULL; sp lpRecorder; @@ -288,14 +288,14 @@ static jint android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject w // callbackData = sp::make(clazz, weak_this); } - nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); + nSession = env->GetIntArrayElements(jSession, nullptr /* isCopy */); if (nSession == NULL) { ALOGE("Error creating AudioRecord: Error retrieving session id pointer"); goto native_init_failure; } // read the audio session ID back from AudioRecord in case a new session was created during set() nSession[0] = lpRecorder->getSessionId(); - env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); + env->ReleaseIntArrayElements(jSession, nSession, 0 /* mode */); nSession = NULL; { diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 1afd2effef08e..ae45a0e7763fa 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -260,13 +260,13 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we const TunerConfigurationHelper tunerHelper(env, tunerConfiguration); - jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); + jint* nSession = env->GetIntArrayElements(jSession, nullptr /* isCopy */); if (nSession == NULL) { ALOGE("Error creating AudioTrack: Error retrieving session id pointer"); return (jint) AUDIO_JAVA_ERROR; } audio_session_t sessionId = (audio_session_t) nSession[0]; - env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); + env->ReleaseIntArrayElements(jSession, nSession, 0 /* mode */); nSession = NULL; @@ -458,14 +458,14 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we javaAudioTrackFields.postNativeEventInJava); lpTrack->setAudioTrackCallback(lpJniStorage->mAudioTrackCallback); - nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL); + nSession = env->GetIntArrayElements(jSession, nullptr /* isCopy */); if (nSession == NULL) { ALOGE("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); + env->ReleaseIntArrayElements(jSession, nSession, 0 /* mode */); nSession = NULL; { @@ -490,7 +490,7 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we // failures: native_init_failure: if (nSession != NULL) { - env->ReleasePrimitiveArrayCritical(jSession, nSession, 0); + env->ReleaseIntArrayElements(jSession, nSession, 0 /* mode */); } setFieldSp(env, thiz, sp{}, javaAudioTrackFields.nativeTrackInJavaObj); @@ -1022,14 +1022,15 @@ static jint android_media_AudioTrack_get_timestamp(JNIEnv *env, jobject thiz, j AudioTimestamp timestamp; status_t status = lpTrack->getTimestamp(timestamp); if (status == OK) { - jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL); + jlong* nTimestamp = env->GetLongArrayElements(jTimestamp, nullptr /* isCopy */); if (nTimestamp == NULL) { ALOGE("Unable to get array for getTimestamp()"); return (jint)AUDIO_JAVA_ERROR; } - nTimestamp[0] = (jlong) timestamp.mPosition; - nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec); - env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0); + nTimestamp[0] = static_cast(timestamp.mPosition); + nTimestamp[1] = static_cast((timestamp.mTime.tv_sec * 1000000000LL) + + timestamp.mTime.tv_nsec); + env->ReleaseLongArrayElements(jTimestamp, nTimestamp, 0 /* mode */); } return (jint) nativeToJavaStatus(status); } @@ -1338,14 +1339,14 @@ static jint android_media_AudioTrack_getAudioDescriptionMixLeveldB(JNIEnv *env, ALOGE("%s: AudioTrack not initialized", __func__); return (jint)AUDIO_JAVA_ERROR; } - jfloat *nativeLevel = (jfloat *)env->GetPrimitiveArrayCritical(level, NULL); + jfloat *nativeLevel = env->GetFloatArrayElements(level, nullptr /* isCopy */); if (nativeLevel == nullptr) { ALOGE("%s: Cannot retrieve level pointer", __func__); return (jint)AUDIO_JAVA_ERROR; } status_t status = lpTrack->getAudioDescriptionMixLevel(reinterpret_cast(nativeLevel)); - env->ReleasePrimitiveArrayCritical(level, nativeLevel, 0 /* mode */); + env->ReleaseFloatArrayElements(level, nativeLevel, 0 /* mode */); return nativeToJavaStatus(status); } @@ -1368,7 +1369,7 @@ static jint android_media_AudioTrack_getDualMonoMode(JNIEnv *env, jobject thiz, ALOGE("%s: AudioTrack not initialized", __func__); return (jint)AUDIO_JAVA_ERROR; } - jint *nativeDualMonoMode = (jint *)env->GetPrimitiveArrayCritical(dualMonoMode, NULL); + jint *nativeDualMonoMode = env->GetIntArrayElements(dualMonoMode, nullptr /* isCopy */); if (nativeDualMonoMode == nullptr) { ALOGE("%s: Cannot retrieve dualMonoMode pointer", __func__); return (jint)AUDIO_JAVA_ERROR; @@ -1376,7 +1377,7 @@ static jint android_media_AudioTrack_getDualMonoMode(JNIEnv *env, jobject thiz, status_t status = lpTrack->getDualMonoMode( reinterpret_cast(nativeDualMonoMode)); - env->ReleasePrimitiveArrayCritical(dualMonoMode, nativeDualMonoMode, 0 /* mode */); + env->ReleaseIntArrayElements(dualMonoMode, nativeDualMonoMode, 0 /* mode */); return nativeToJavaStatus(status); } diff --git a/media/jni/audioeffect/android_media_SourceDefaultEffect.cpp b/media/jni/audioeffect/android_media_SourceDefaultEffect.cpp index d244bcb71c624..e568db1283fc1 100644 --- a/media/jni/audioeffect/android_media_SourceDefaultEffect.cpp +++ b/media/jni/audioeffect/android_media_SourceDefaultEffect.cpp @@ -72,7 +72,7 @@ static jint android_media_SourceDefaultEffect_native_setup(JNIEnv *env, goto setup_exit; } - nId = reinterpret_cast(env->GetPrimitiveArrayCritical(jId, NULL)); + nId = env->GetIntArrayElements(jId, nullptr /* isCopy */); if (nId == NULL) { ALOGE("setup: Error retrieving id pointer"); lStatus = BAD_VALUE; @@ -98,7 +98,7 @@ setup_exit: // Final cleanup and return. if (nId != NULL) { - env->ReleasePrimitiveArrayCritical(jId, nId, 0); + env->ReleaseIntArrayElements(jId, nId, 0 /* mode */); nId = NULL; } diff --git a/media/jni/audioeffect/android_media_StreamDefaultEffect.cpp b/media/jni/audioeffect/android_media_StreamDefaultEffect.cpp index accdddbc97eb0..f276f48315d9a 100644 --- a/media/jni/audioeffect/android_media_StreamDefaultEffect.cpp +++ b/media/jni/audioeffect/android_media_StreamDefaultEffect.cpp @@ -72,7 +72,7 @@ static jint android_media_StreamDefaultEffect_native_setup(JNIEnv *env, goto setup_exit; } - nId = reinterpret_cast(env->GetPrimitiveArrayCritical(jId, NULL)); + nId = env->GetIntArrayElements(jId, nullptr /* isCopy */); if (nId == NULL) { ALOGE("setup: Error retrieving id pointer"); lStatus = BAD_VALUE; @@ -98,7 +98,7 @@ setup_exit: // Final cleanup and return. if (nId != NULL) { - env->ReleasePrimitiveArrayCritical(jId, nId, 0); + env->ReleaseIntArrayElements(jId, nId, 0 /* mode */); nId = NULL; } @@ -115,7 +115,7 @@ setup_exit: return AudioEffectJni::translateNativeErrorToJava(lStatus); } -static void android_media_StreamDefaultEffect_native_release(JNIEnv */*env*/, +static void android_media_StreamDefaultEffect_native_release(JNIEnv* /*env*/, jobject /*thiz*/, jint id) { status_t lStatus = AudioEffect::removeStreamDefaultEffect(id); diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp index 7b00f9392395d..fac32e02cccd9 100644 --- a/media/jni/audioeffect/android_media_Visualizer.cpp +++ b/media/jni/audioeffect/android_media_Visualizer.cpp @@ -443,14 +443,14 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th goto setup_failure; } - nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL); + nId = env->GetIntArrayElements(jId, nullptr /* isCopy */); if (nId == NULL) { ALOGE("setup: Error retrieving id pointer"); lStatus = VISUALIZER_ERROR_BAD_VALUE; goto setup_failure; } nId[0] = lpVisualizer->id(); - env->ReleasePrimitiveArrayCritical(jId, nId, 0); + env->ReleaseIntArrayElements(jId, nId, 0 /* mode */); nId = NULL; setVisualizer(env, thiz, lpVisualizer); @@ -467,7 +467,7 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th setup_failure: if (nId != NULL) { - env->ReleasePrimitiveArrayCritical(jId, nId, 0); + env->ReleaseIntArrayElements(jId, nId, 0 /* mode */); } if (lpJniStorage) { @@ -660,13 +660,13 @@ android_media_visualizer_native_getWaveForm(JNIEnv *env, jobject thiz, jbyteArra return VISUALIZER_ERROR_NO_INIT; } - jbyte* nWaveform = (jbyte *) env->GetPrimitiveArrayCritical(jWaveform, NULL); + jbyte* nWaveform = env->GetByteArrayElements(jWaveform, nullptr /* isCopy */); if (nWaveform == NULL) { return VISUALIZER_ERROR_NO_MEMORY; } jint status = translateError(lpVisualizer->getWaveForm((uint8_t *)nWaveform)); - env->ReleasePrimitiveArrayCritical(jWaveform, nWaveform, 0); + env->ReleaseByteArrayElements(jWaveform, nWaveform, 0 /* mode */); return status; } @@ -678,13 +678,13 @@ android_media_visualizer_native_getFft(JNIEnv *env, jobject thiz, jbyteArray jFf return VISUALIZER_ERROR_NO_INIT; } - jbyte* nFft = (jbyte *) env->GetPrimitiveArrayCritical(jFft, NULL); + jbyte* nFft = env->GetByteArrayElements(jFft, nullptr /* isCopy */); if (nFft == NULL) { return VISUALIZER_ERROR_NO_MEMORY; } jint status = translateError(lpVisualizer->getFft((uint8_t *)nFft)); - env->ReleasePrimitiveArrayCritical(jFft, nFft, 0); + env->ReleaseByteArrayElements(jFft, nFft, 0 /* mode */); return status; }