• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
convertMicrophoneInfoFromNative(JNIEnv * env,jobject * jMicrophoneInfo,const media::MicrophoneInfo * microphoneInfo)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 
register_android_media_MicrophoneInfo(JNIEnv * env)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