/* * 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, "", "()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, "", "(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, "", "(I)V"); jclass microphoneInfoClass = FindClassOrDie(env, "android/media/MicrophoneInfo"); gMicrophoneInfoClass = MakeGlobalRefOrDie(env, microphoneInfoClass); gMicrophoneInfoCstor = GetMethodIDOrDie(env, microphoneInfoClass, "", "(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, "", "(FFF)V"); jclass pairClass = FindClassOrDie(env, "android/util/Pair"); gPairClass = MakeGlobalRefOrDie(env, pairClass); gPairCstor = GetMethodIDOrDie(env, pairClass, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); return 0; }