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
This commit is contained in:
Atneya Nair
2022-05-18 18:23:44 -04:00
parent 1a70b927fa
commit 0d68bc11dd
5 changed files with 30 additions and 29 deletions

View File

@@ -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<AudioRecord> lpRecorder;
@@ -288,14 +288,14 @@ static jint android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject w
// callbackData = sp<AudioRecordJNIStorage>::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;
{

View File

@@ -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<AudioTrack>{}, 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<jlong>(timestamp.mPosition);
nTimestamp[1] = static_cast<jlong>((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<float *>(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<audio_dual_mono_mode_t *>(nativeDualMonoMode));
env->ReleasePrimitiveArrayCritical(dualMonoMode, nativeDualMonoMode, 0 /* mode */);
env->ReleaseIntArrayElements(dualMonoMode, nativeDualMonoMode, 0 /* mode */);
return nativeToJavaStatus(status);
}

View File

@@ -72,7 +72,7 @@ static jint android_media_SourceDefaultEffect_native_setup(JNIEnv *env,
goto setup_exit;
}
nId = reinterpret_cast<jint *>(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;
}

View File

@@ -72,7 +72,7 @@ static jint android_media_StreamDefaultEffect_native_setup(JNIEnv *env,
goto setup_exit;
}
nId = reinterpret_cast<jint *>(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);

View File

@@ -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;
}