Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "android_media_MicrophoneInfo.h"
     18 #include "android_media_AudioErrors.h"
     19 #include "core_jni_helpers.h"
     20 
     21 using namespace android;
     22 
     23 static jclass gArrayListClass;
     24 static jmethodID gArrayListCstor;
     25 static struct {
     26     jmethodID add;
     27 } gArrayListMethods;
     28 
     29 static jclass gFloatClass;
     30 static jmethodID gFloatCstor;
     31 
     32 static jclass gFloatArrayClass;
     33 
     34 static jclass gIntegerClass;
     35 static jmethodID gIntegerCstor;
     36 
     37 static jclass gMicrophoneInfoClass;
     38 static jmethodID gMicrophoneInfoCstor;
     39 
     40 static jclass gMicrophoneInfoCoordinateClass;
     41 static jmethodID gMicrophoneInfoCoordinateCstor;
     42 
     43 static jclass gPairClass;
     44 static jmethodID gPairCstor;
     45 
     46 namespace android {
     47 
     48 jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo,
     49         const media::MicrophoneInfo *microphoneInfo)
     50 {
     51     jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
     52     jstring jDeviceId = NULL;
     53     jstring jAddress = NULL;
     54     jobject jGeometricLocation = NULL;
     55     jobject jOrientation = NULL;
     56     jobject jFrequencyResponses = NULL;
     57     jobject jChannelMappings = NULL;
     58 
     59     jDeviceId = env->NewStringUTF(String8(microphoneInfo->getDeviceId()).string());
     60     jAddress = env->NewStringUTF(String8(microphoneInfo->getAddress()).string());
     61     if (microphoneInfo->getGeometricLocation().size() != 3 ||
     62             microphoneInfo->getOrientation().size() != 3) {
     63         jStatus = nativeToJavaStatus(BAD_VALUE);
     64         goto exit;
     65     }
     66     jGeometricLocation = env->NewObject(gMicrophoneInfoCoordinateClass,
     67                                         gMicrophoneInfoCoordinateCstor,
     68                                         microphoneInfo->getGeometricLocation()[0],
     69                                         microphoneInfo->getGeometricLocation()[1],
     70                                         microphoneInfo->getGeometricLocation()[2]);
     71     jOrientation = env->NewObject(gMicrophoneInfoCoordinateClass,
     72                                   gMicrophoneInfoCoordinateCstor,
     73                                   microphoneInfo->getOrientation()[0],
     74                                   microphoneInfo->getOrientation()[1],
     75                                   microphoneInfo->getOrientation()[2]);
     76     // Create a list of Pair for frequency response.
     77     if (microphoneInfo->getFrequencyResponses().size() != 2 ||
     78             microphoneInfo->getFrequencyResponses()[0].size() !=
     79                     microphoneInfo->getFrequencyResponses()[1].size()) {
     80         jStatus = nativeToJavaStatus(BAD_VALUE);
     81         goto exit;
     82     }
     83     jFrequencyResponses = env->NewObject(gArrayListClass, gArrayListCstor);
     84     for (size_t i = 0; i < microphoneInfo->getFrequencyResponses()[0].size(); i++) {
     85         jobject jFrequency = env->NewObject(gFloatClass, gFloatCstor,
     86                                             microphoneInfo->getFrequencyResponses()[0][i]);
     87         jobject jResponse = env->NewObject(gFloatClass, gFloatCstor,
     88                                           microphoneInfo->getFrequencyResponses()[1][i]);
     89         jobject jFrequencyResponse = env->NewObject(gPairClass, gPairCstor, jFrequency, jResponse);
     90         env->CallBooleanMethod(jFrequencyResponses, gArrayListMethods.add, jFrequencyResponse);
     91         env->DeleteLocalRef(jFrequency);
     92         env->DeleteLocalRef(jResponse);
     93         env->DeleteLocalRef(jFrequencyResponse);
     94     }
     95     // Create a list of Pair for channel mapping.
     96     if (microphoneInfo->getChannelMapping().size() != AUDIO_CHANNEL_COUNT_MAX) {
     97         jStatus = nativeToJavaStatus(BAD_VALUE);
     98         goto exit;
     99     }
    100     jChannelMappings = env->NewObject(gArrayListClass, gArrayListCstor);
    101     for (size_t i = 0; i < microphoneInfo->getChannelMapping().size(); i++) {
    102         int channelMappingType = microphoneInfo->getChannelMapping()[i];
    103         if (channelMappingType != AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) {
    104             jobject jChannelIndex = env->NewObject(gIntegerClass, gIntegerCstor, i);
    105             jobject jChannelMappingType = env->NewObject(gIntegerClass, gIntegerCstor,
    106                                                          channelMappingType);
    107             jobject jChannelMapping = env->NewObject(gPairClass, gPairCstor,
    108                                                      jChannelIndex, jChannelMappingType);
    109             env->CallBooleanMethod(jChannelMappings, gArrayListMethods.add, jChannelMapping);
    110             env->DeleteLocalRef(jChannelIndex);
    111             env->DeleteLocalRef(jChannelMappingType);
    112             env->DeleteLocalRef(jChannelMapping);
    113         }
    114     }
    115     *jMicrophoneInfo = env->NewObject(gMicrophoneInfoClass, gMicrophoneInfoCstor, jDeviceId,
    116                                       microphoneInfo->getType(), jAddress,
    117                                       microphoneInfo->getDeviceLocation(),
    118                                       microphoneInfo->getDeviceGroup(),
    119                                       microphoneInfo->getIndexInTheGroup(),
    120                                       jGeometricLocation, jOrientation,
    121                                       jFrequencyResponses, jChannelMappings,
    122                                       microphoneInfo->getSensitivity(),
    123                                       microphoneInfo->getMaxSpl(),
    124                                       microphoneInfo->getMinSpl(),
    125                                       microphoneInfo->getDirectionality());
    126 
    127 exit:
    128     if (jDeviceId != NULL) {
    129         env->DeleteLocalRef(jDeviceId);
    130     }
    131     if (jAddress != NULL) {
    132         env->DeleteLocalRef(jAddress);
    133     }
    134     if (jFrequencyResponses != NULL) {
    135         env->DeleteLocalRef(jFrequencyResponses);
    136     }
    137     if (jChannelMappings != NULL) {
    138         env->DeleteLocalRef(jChannelMappings);
    139     }
    140     if (jGeometricLocation != NULL) {
    141         env->DeleteLocalRef(jGeometricLocation);
    142     }
    143     if (jOrientation != NULL) {
    144         env->DeleteLocalRef(jOrientation);
    145     }
    146     return jStatus;
    147 }
    148 
    149 }
    150 
    151 int register_android_media_MicrophoneInfo(JNIEnv *env)
    152 {
    153     jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
    154     gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
    155     gArrayListCstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
    156     gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
    157 
    158     jclass floatClass = FindClassOrDie(env, "java/lang/Float");
    159     gFloatClass = MakeGlobalRefOrDie(env, floatClass);
    160     gFloatCstor = GetMethodIDOrDie(env, floatClass, "<init>", "(F)V");
    161 
    162     jclass floatArrayClass = FindClassOrDie(env, "[F");
    163     gFloatArrayClass = MakeGlobalRefOrDie(env, floatArrayClass);
    164 
    165     jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
    166     gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
    167     gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
    168 
    169     jclass microphoneInfoClass = FindClassOrDie(env, "android/media/MicrophoneInfo");
    170     gMicrophoneInfoClass = MakeGlobalRefOrDie(env, microphoneInfoClass);
    171     gMicrophoneInfoCstor = GetMethodIDOrDie(env, microphoneInfoClass, "<init>",
    172             "(Ljava/lang/String;ILjava/lang/String;IIILandroid/media/MicrophoneInfo$Coordinate3F;Landroid/media/MicrophoneInfo$Coordinate3F;Ljava/util/List;Ljava/util/List;FFFI)V");
    173 
    174     jclass microphoneInfoCoordinateClass = FindClassOrDie(
    175             env, "android/media/MicrophoneInfo$Coordinate3F");
    176     gMicrophoneInfoCoordinateClass = MakeGlobalRefOrDie(env, microphoneInfoCoordinateClass);
    177     gMicrophoneInfoCoordinateCstor = GetMethodIDOrDie(env, microphoneInfoCoordinateClass, "<init>",
    178            "(FFF)V");
    179 
    180     jclass pairClass = FindClassOrDie(env, "android/util/Pair");
    181     gPairClass = MakeGlobalRefOrDie(env, pairClass);
    182     gPairCstor = GetMethodIDOrDie(env, pairClass, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
    183 
    184     return 0;
    185 }
    186