C++程序  |  186行  |  8.15 KB

/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "android_media_MicrophoneInfo.h"
#include "android_media_AudioErrors.h"
#include "core_jni_helpers.h"

using namespace android;

static jclass gArrayListClass;
static jmethodID gArrayListCstor;
static struct {
    jmethodID add;
} gArrayListMethods;

static jclass gFloatClass;
static jmethodID gFloatCstor;

static jclass gFloatArrayClass;

static jclass gIntegerClass;
static jmethodID gIntegerCstor;

static jclass gMicrophoneInfoClass;
static jmethodID gMicrophoneInfoCstor;

static jclass gMicrophoneInfoCoordinateClass;
static jmethodID gMicrophoneInfoCoordinateCstor;

static jclass gPairClass;
static jmethodID gPairCstor;

namespace android {

jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo,
        const media::MicrophoneInfo *microphoneInfo)
{
    jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
    jstring jDeviceId = NULL;
    jstring jAddress = NULL;
    jobject jGeometricLocation = NULL;
    jobject jOrientation = NULL;
    jobject jFrequencyResponses = NULL;
    jobject jChannelMappings = NULL;

    jDeviceId = env->NewStringUTF(String8(microphoneInfo->getDeviceId()).string());
    jAddress = env->NewStringUTF(String8(microphoneInfo->getAddress()).string());
    if (microphoneInfo->getGeometricLocation().size() != 3 ||
            microphoneInfo->getOrientation().size() != 3) {
        jStatus = nativeToJavaStatus(BAD_VALUE);
        goto exit;
    }
    jGeometricLocation = env->NewObject(gMicrophoneInfoCoordinateClass,
                                        gMicrophoneInfoCoordinateCstor,
                                        microphoneInfo->getGeometricLocation()[0],
                                        microphoneInfo->getGeometricLocation()[1],
                                        microphoneInfo->getGeometricLocation()[2]);
    jOrientation = env->NewObject(gMicrophoneInfoCoordinateClass,
                                  gMicrophoneInfoCoordinateCstor,
                                  microphoneInfo->getOrientation()[0],
                                  microphoneInfo->getOrientation()[1],
                                  microphoneInfo->getOrientation()[2]);
    // Create a list of Pair for frequency response.
    if (microphoneInfo->getFrequencyResponses().size() != 2 ||
            microphoneInfo->getFrequencyResponses()[0].size() !=
                    microphoneInfo->getFrequencyResponses()[1].size()) {
        jStatus = nativeToJavaStatus(BAD_VALUE);
        goto exit;
    }
    jFrequencyResponses = env->NewObject(gArrayListClass, gArrayListCstor);
    for (size_t i = 0; i < microphoneInfo->getFrequencyResponses()[0].size(); i++) {
        jobject jFrequency = env->NewObject(gFloatClass, gFloatCstor,
                                            microphoneInfo->getFrequencyResponses()[0][i]);
        jobject jResponse = env->NewObject(gFloatClass, gFloatCstor,
                                          microphoneInfo->getFrequencyResponses()[1][i]);
        jobject jFrequencyResponse = env->NewObject(gPairClass, gPairCstor, jFrequency, jResponse);
        env->CallBooleanMethod(jFrequencyResponses, gArrayListMethods.add, jFrequencyResponse);
        env->DeleteLocalRef(jFrequency);
        env->DeleteLocalRef(jResponse);
        env->DeleteLocalRef(jFrequencyResponse);
    }
    // Create a list of Pair for channel mapping.
    if (microphoneInfo->getChannelMapping().size() != AUDIO_CHANNEL_COUNT_MAX) {
        jStatus = nativeToJavaStatus(BAD_VALUE);
        goto exit;
    }
    jChannelMappings = env->NewObject(gArrayListClass, gArrayListCstor);
    for (size_t i = 0; i < microphoneInfo->getChannelMapping().size(); i++) {
        int channelMappingType = microphoneInfo->getChannelMapping()[i];
        if (channelMappingType != AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) {
            jobject jChannelIndex = env->NewObject(gIntegerClass, gIntegerCstor, i);
            jobject jChannelMappingType = env->NewObject(gIntegerClass, gIntegerCstor,
                                                         channelMappingType);
            jobject jChannelMapping = env->NewObject(gPairClass, gPairCstor,
                                                     jChannelIndex, jChannelMappingType);
            env->CallBooleanMethod(jChannelMappings, gArrayListMethods.add, jChannelMapping);
            env->DeleteLocalRef(jChannelIndex);
            env->DeleteLocalRef(jChannelMappingType);
            env->DeleteLocalRef(jChannelMapping);
        }
    }
    *jMicrophoneInfo = env->NewObject(gMicrophoneInfoClass, gMicrophoneInfoCstor, jDeviceId,
                                      microphoneInfo->getType(), jAddress,
                                      microphoneInfo->getDeviceLocation(),
                                      microphoneInfo->getDeviceGroup(),
                                      microphoneInfo->getIndexInTheGroup(),
                                      jGeometricLocation, jOrientation,
                                      jFrequencyResponses, jChannelMappings,
                                      microphoneInfo->getSensitivity(),
                                      microphoneInfo->getMaxSpl(),
                                      microphoneInfo->getMinSpl(),
                                      microphoneInfo->getDirectionality());

exit:
    if (jDeviceId != NULL) {
        env->DeleteLocalRef(jDeviceId);
    }
    if (jAddress != NULL) {
        env->DeleteLocalRef(jAddress);
    }
    if (jFrequencyResponses != NULL) {
        env->DeleteLocalRef(jFrequencyResponses);
    }
    if (jChannelMappings != NULL) {
        env->DeleteLocalRef(jChannelMappings);
    }
    if (jGeometricLocation != NULL) {
        env->DeleteLocalRef(jGeometricLocation);
    }
    if (jOrientation != NULL) {
        env->DeleteLocalRef(jOrientation);
    }
    return jStatus;
}

}

int register_android_media_MicrophoneInfo(JNIEnv *env)
{
    jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
    gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
    gArrayListCstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
    gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");

    jclass floatClass = FindClassOrDie(env, "java/lang/Float");
    gFloatClass = MakeGlobalRefOrDie(env, floatClass);
    gFloatCstor = GetMethodIDOrDie(env, floatClass, "<init>", "(F)V");

    jclass floatArrayClass = FindClassOrDie(env, "[F");
    gFloatArrayClass = MakeGlobalRefOrDie(env, floatArrayClass);

    jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
    gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
    gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");

    jclass microphoneInfoClass = FindClassOrDie(env, "android/media/MicrophoneInfo");
    gMicrophoneInfoClass = MakeGlobalRefOrDie(env, microphoneInfoClass);
    gMicrophoneInfoCstor = GetMethodIDOrDie(env, microphoneInfoClass, "<init>",
            "(Ljava/lang/String;ILjava/lang/String;IIILandroid/media/MicrophoneInfo$Coordinate3F;Landroid/media/MicrophoneInfo$Coordinate3F;Ljava/util/List;Ljava/util/List;FFFI)V");

    jclass microphoneInfoCoordinateClass = FindClassOrDie(
            env, "android/media/MicrophoneInfo$Coordinate3F");
    gMicrophoneInfoCoordinateClass = MakeGlobalRefOrDie(env, microphoneInfoCoordinateClass);
    gMicrophoneInfoCoordinateCstor = GetMethodIDOrDie(env, microphoneInfoCoordinateClass, "<init>",
           "(FFF)V");

    jclass pairClass = FindClassOrDie(env, "android/util/Pair");
    gPairClass = MakeGlobalRefOrDie(env, pairClass);
    gPairCstor = GetMethodIDOrDie(env, pairClass, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");

    return 0;
}