Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d68bc11 authored by Atneya Nair's avatar Atneya Nair
Browse files

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
parent 1a70b927
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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;

    {
+14 −13
Original line number Diff line number Diff line
@@ -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);
}
+2 −2
Original line number Diff line number Diff line
@@ -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;
    }

+3 −3
Original line number Diff line number Diff line
@@ -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;
    }

+7 −7
Original line number Diff line number Diff line
@@ -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;
}