1 /*
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 //#define LOG_NDEBUG 0
19
20 #define LOG_TAG "AudioSystem-JNI"
21 #include <utils/Log.h>
22
23 #include <sstream>
24 #include <vector>
25 #include <jni.h>
26 #include <nativehelper/JNIHelp.h>
27 #include "core_jni_helpers.h"
28
29 #include <android/media/AudioVibratorInfo.h>
30 #include <audiomanager/AudioManager.h>
31 #include <media/AudioPolicy.h>
32 #include <media/AudioSystem.h>
33 #include <media/MicrophoneInfo.h>
34 #include <nativehelper/ScopedLocalRef.h>
35 #include <system/audio.h>
36 #include <system/audio_policy.h>
37 #include "android_media_AudioAttributes.h"
38 #include "android_media_AudioDescriptor.h"
39 #include "android_media_AudioDeviceAttributes.h"
40 #include "android_media_AudioEffectDescriptor.h"
41 #include "android_media_AudioErrors.h"
42 #include "android_media_AudioFormat.h"
43 #include "android_media_AudioProfile.h"
44 #include "android_media_MicrophoneInfo.h"
45 #include "android_util_Binder.h"
46
47 // ----------------------------------------------------------------------------
48
49 using namespace android;
50
51 static const char* const kClassPathName = "android/media/AudioSystem";
52
53 static jclass gArrayListClass;
54 static struct {
55 jmethodID cstor;
56 jmethodID add;
57 jmethodID toArray;
58 } gArrayListMethods;
59
60 static jclass gBooleanClass;
61 static jmethodID gBooleanCstor;
62
63 static jclass gIntegerClass;
64 static jmethodID gIntegerCstor;
65
66 static jclass gMapClass;
67 static jmethodID gMapPut;
68
69 static jclass gAudioHandleClass;
70 static jmethodID gAudioHandleCstor;
71 static struct {
72 jfieldID mId;
73 } gAudioHandleFields;
74
75 static jclass gAudioPortClass;
76 static jmethodID gAudioPortCstor;
77 static struct {
78 jfieldID mHandle;
79 jfieldID mRole;
80 jfieldID mGains;
81 jfieldID mActiveConfig;
82 // Valid only if an AudioDevicePort
83 jfieldID mType;
84 jfieldID mAddress;
85 // other fields unused by JNI
86 } gAudioPortFields;
87
88 static jclass gAudioPortConfigClass;
89 static jmethodID gAudioPortConfigCstor;
90 static struct {
91 jfieldID mPort;
92 jfieldID mSamplingRate;
93 jfieldID mChannelMask;
94 jfieldID mFormat;
95 jfieldID mGain;
96 jfieldID mConfigMask;
97 } gAudioPortConfigFields;
98
99 static jclass gAudioDevicePortClass;
100 static jmethodID gAudioDevicePortCstor;
101
102 static jclass gAudioDevicePortConfigClass;
103 static jmethodID gAudioDevicePortConfigCstor;
104
105 static jclass gAudioMixPortClass;
106 static jmethodID gAudioMixPortCstor;
107
108 static jclass gAudioMixPortConfigClass;
109 static jmethodID gAudioMixPortConfigCstor;
110
111 static jclass gAudioGainClass;
112 static jmethodID gAudioGainCstor;
113
114 static jclass gAudioGainConfigClass;
115 static jmethodID gAudioGainConfigCstor;
116 static struct {
117 jfieldID mIndex;
118 jfieldID mMode;
119 jfieldID mChannelMask;
120 jfieldID mValues;
121 jfieldID mRampDurationMs;
122 // other fields unused by JNI
123 } gAudioGainConfigFields;
124
125 static jclass gAudioPatchClass;
126 static jmethodID gAudioPatchCstor;
127 static struct {
128 jfieldID mHandle;
129 // other fields unused by JNI
130 } gAudioPatchFields;
131
132 static jclass gAudioMixClass;
133 static struct {
134 jfieldID mRule;
135 jfieldID mFormat;
136 jfieldID mRouteFlags;
137 jfieldID mDeviceType;
138 jfieldID mDeviceAddress;
139 jfieldID mMixType;
140 jfieldID mCallbackFlags;
141 } gAudioMixFields;
142
143 static jclass gAudioFormatClass;
144 static struct {
145 jfieldID mEncoding;
146 jfieldID mSampleRate;
147 jfieldID mChannelMask;
148 // other fields unused by JNI
149 } gAudioFormatFields;
150
151 static jclass gAudioMixingRuleClass;
152 static struct {
153 jfieldID mCriteria;
154 jfieldID mAllowPrivilegedPlaybackCapture;
155 jfieldID mVoiceCommunicationCaptureAllowed;
156 // other fields unused by JNI
157 } gAudioMixingRuleFields;
158
159 static jclass gAudioMixMatchCriterionClass;
160 static struct {
161 jfieldID mAttr;
162 jfieldID mIntProp;
163 jfieldID mRule;
164 } gAudioMixMatchCriterionFields;
165
166 static const char* const kEventHandlerClassPathName =
167 "android/media/AudioPortEventHandler";
168 static struct {
169 jfieldID mJniCallback;
170 } gEventHandlerFields;
171 static struct {
172 jmethodID postEventFromNative;
173 } gAudioPortEventHandlerMethods;
174
175 static struct {
176 jmethodID postDynPolicyEventFromNative;
177 jmethodID postRecordConfigEventFromNative;
178 jmethodID postRoutingUpdatedFromNative;
179 } gAudioPolicyEventHandlerMethods;
180
181 jclass gListClass;
182 static struct {
183 jmethodID add;
184 jmethodID get;
185 jmethodID size;
186 } gListMethods;
187
188 static jclass gAudioDescriptorClass;
189 static jmethodID gAudioDescriptorCstor;
190
191 //
192 // JNI Initialization for OpenSLES routing
193 //
194 jmethodID gMidAudioTrackRoutingProxy_ctor;
195 jmethodID gMidAudioTrackRoutingProxy_release;
196 jmethodID gMidAudioRecordRoutingProxy_ctor;
197 jmethodID gMidAudioRecordRoutingProxy_release;
198
199 jclass gClsAudioTrackRoutingProxy;
200 jclass gClsAudioRecordRoutingProxy;
201
202 jclass gAudioProfileClass;
203 jmethodID gAudioProfileCstor;
204
205 jclass gVibratorClass;
206 static struct {
207 jmethodID getId;
208 jmethodID getResonantFrequency;
209 jmethodID getQFactor;
210 } gVibratorMethods;
211
212 static Mutex gLock;
213
214 enum AudioError {
215 kAudioStatusOk = 0,
216 kAudioStatusError = 1,
217 kAudioStatusMediaServerDied = 100
218 };
219
220 enum {
221 AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1,
222 AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2,
223 AUDIOPORT_EVENT_SERVICE_DIED = 3,
224 };
225
226 #define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
227
228 // ----------------------------------------------------------------------------
229 // ref-counted object for audio port callbacks
230 class JNIAudioPortCallback: public AudioSystem::AudioPortCallback
231 {
232 public:
233 JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
234 ~JNIAudioPortCallback();
235
236 virtual void onAudioPortListUpdate();
237 virtual void onAudioPatchListUpdate();
238 virtual void onServiceDied();
239
240 private:
241 void sendEvent(int event);
242
243 jclass mClass; // Reference to AudioPortEventHandler class
244 jobject mObject; // Weak ref to AudioPortEventHandler Java object to call on
245 };
246
JNIAudioPortCallback(JNIEnv * env,jobject thiz,jobject weak_thiz)247 JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
248 {
249
250 // Hold onto the AudioPortEventHandler class for use in calling the static method
251 // that posts events to the application thread.
252 jclass clazz = env->GetObjectClass(thiz);
253 if (clazz == NULL) {
254 ALOGE("Can't find class %s", kEventHandlerClassPathName);
255 return;
256 }
257 mClass = (jclass)env->NewGlobalRef(clazz);
258
259 // We use a weak reference so the AudioPortEventHandler object can be garbage collected.
260 // The reference is only used as a proxy for callbacks.
261 mObject = env->NewGlobalRef(weak_thiz);
262 }
263
~JNIAudioPortCallback()264 JNIAudioPortCallback::~JNIAudioPortCallback()
265 {
266 // remove global references
267 JNIEnv *env = AndroidRuntime::getJNIEnv();
268 if (env == NULL) {
269 return;
270 }
271 env->DeleteGlobalRef(mObject);
272 env->DeleteGlobalRef(mClass);
273 }
274
sendEvent(int event)275 void JNIAudioPortCallback::sendEvent(int event)
276 {
277 JNIEnv *env = AndroidRuntime::getJNIEnv();
278 if (env == NULL) {
279 return;
280 }
281 env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject,
282 event, 0, 0, NULL);
283 if (env->ExceptionCheck()) {
284 ALOGW("An exception occurred while notifying an event.");
285 env->ExceptionClear();
286 }
287 }
288
onAudioPortListUpdate()289 void JNIAudioPortCallback::onAudioPortListUpdate()
290 {
291 sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED);
292 }
293
onAudioPatchListUpdate()294 void JNIAudioPortCallback::onAudioPatchListUpdate()
295 {
296 sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED);
297 }
298
onServiceDied()299 void JNIAudioPortCallback::onServiceDied()
300 {
301 sendEvent(AUDIOPORT_EVENT_SERVICE_DIED);
302 }
303
setJniCallback(JNIEnv * env,jobject thiz,const sp<JNIAudioPortCallback> & callback)304 static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
305 jobject thiz,
306 const sp<JNIAudioPortCallback>& callback)
307 {
308 Mutex::Autolock l(gLock);
309 sp<JNIAudioPortCallback> old =
310 (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback);
311 if (callback.get()) {
312 callback->incStrong((void*)setJniCallback);
313 }
314 if (old != 0) {
315 old->decStrong((void*)setJniCallback);
316 }
317 env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get());
318 return old;
319 }
320
321 #define check_AudioSystem_Command(...) _check_AudioSystem_Command(__func__, __VA_ARGS__)
322
_check_AudioSystem_Command(const char * caller,status_t status,std::vector<status_t> ignoredErrors={})323 static int _check_AudioSystem_Command(const char *caller, status_t status,
324 std::vector<status_t> ignoredErrors = {}) {
325 int jniStatus = kAudioStatusOk;
326 switch (status) {
327 case DEAD_OBJECT:
328 jniStatus = kAudioStatusMediaServerDied;
329 break;
330 case NO_ERROR:
331 break;
332 default:
333 if (std::find(begin(ignoredErrors), end(ignoredErrors), status) == end(ignoredErrors)) {
334 jniStatus = kAudioStatusError;
335 }
336 break;
337 }
338 ALOGE_IF(jniStatus != kAudioStatusOk, "Command failed for %s: %d", caller, status);
339 return jniStatus;
340 }
341
getVectorOfAudioDeviceTypeAddr(JNIEnv * env,jintArray deviceTypes,jobjectArray deviceAddresses,AudioDeviceTypeAddrVector & audioDeviceTypeAddrVector)342 static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes,
343 jobjectArray deviceAddresses,
344 AudioDeviceTypeAddrVector &audioDeviceTypeAddrVector) {
345 if (deviceTypes == nullptr || deviceAddresses == nullptr) {
346 return (jint)AUDIO_JAVA_BAD_VALUE;
347 }
348 jsize deviceCount = env->GetArrayLength(deviceTypes);
349 if (deviceCount == 0 || deviceCount != env->GetArrayLength(deviceAddresses)) {
350 return (jint)AUDIO_JAVA_BAD_VALUE;
351 }
352 // retrieve all device types
353 std::vector<audio_devices_t> deviceTypesVector;
354 jint *typesPtr = nullptr;
355 typesPtr = env->GetIntArrayElements(deviceTypes, 0);
356 if (typesPtr == nullptr) {
357 return (jint)AUDIO_JAVA_BAD_VALUE;
358 }
359 for (jint i = 0; i < deviceCount; i++) {
360 deviceTypesVector.push_back((audio_devices_t)typesPtr[i]);
361 }
362 // check each address is a string and add device type/address to list
363 jclass stringClass = FindClassOrDie(env, "java/lang/String");
364 for (jint i = 0; i < deviceCount; i++) {
365 jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i);
366 if (!env->IsInstanceOf(addrJobj, stringClass)) {
367 return (jint)AUDIO_JAVA_BAD_VALUE;
368 }
369 const char *address = env->GetStringUTFChars((jstring)addrJobj, NULL);
370 AudioDeviceTypeAddr dev = AudioDeviceTypeAddr((audio_devices_t)typesPtr[i], address);
371 audioDeviceTypeAddrVector.push_back(dev);
372 env->ReleaseStringUTFChars((jstring)addrJobj, address);
373 }
374 env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
375
376 return (jint)NO_ERROR;
377 }
378
379 static jint
android_media_AudioSystem_muteMicrophone(JNIEnv * env,jobject thiz,jboolean on)380 android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
381 {
382 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
383 }
384
385 static jboolean
android_media_AudioSystem_isMicrophoneMuted(JNIEnv * env,jobject thiz)386 android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
387 {
388 bool state = false;
389 AudioSystem::isMicrophoneMuted(&state);
390 return state;
391 }
392
393 static jboolean
android_media_AudioSystem_isStreamActive(JNIEnv * env,jobject thiz,jint stream,jint inPastMs)394 android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
395 {
396 bool state = false;
397 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
398 return state;
399 }
400
401 static jboolean
android_media_AudioSystem_isStreamActiveRemotely(JNIEnv * env,jobject thiz,jint stream,jint inPastMs)402 android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
403 jint inPastMs)
404 {
405 bool state = false;
406 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
407 return state;
408 }
409
410 static jboolean
android_media_AudioSystem_isSourceActive(JNIEnv * env,jobject thiz,jint source)411 android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
412 {
413 bool state = false;
414 AudioSystem::isSourceActive((audio_source_t) source, &state);
415 return state;
416 }
417
418 static jint
android_media_AudioSystem_newAudioSessionId(JNIEnv * env,jobject thiz)419 android_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz)
420 {
421 return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
422 }
423
424 static jint
android_media_AudioSystem_newAudioPlayerId(JNIEnv * env,jobject thiz)425 android_media_AudioSystem_newAudioPlayerId(JNIEnv *env, jobject thiz)
426 {
427 int id = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_CLIENT);
428 return id != AUDIO_UNIQUE_ID_ALLOCATE ? id : PLAYER_PIID_INVALID;
429 }
430
431 static jint
android_media_AudioSystem_newAudioRecorderId(JNIEnv * env,jobject thiz)432 android_media_AudioSystem_newAudioRecorderId(JNIEnv *env, jobject thiz)
433 {
434 int id = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_CLIENT);
435 return id != AUDIO_UNIQUE_ID_ALLOCATE ? id : RECORD_RIID_INVALID;
436 }
437
438 static jint
android_media_AudioSystem_setParameters(JNIEnv * env,jobject thiz,jstring keyValuePairs)439 android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
440 {
441 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
442 String8 c_keyValuePairs8;
443 if (keyValuePairs) {
444 c_keyValuePairs8 = String8(
445 reinterpret_cast<const char16_t*>(c_keyValuePairs),
446 env->GetStringLength(keyValuePairs));
447 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
448 }
449 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
450 return (jint) status;
451 }
452
453 static jstring
android_media_AudioSystem_getParameters(JNIEnv * env,jobject thiz,jstring keys)454 android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
455 {
456 const jchar* c_keys = env->GetStringCritical(keys, 0);
457 String8 c_keys8;
458 if (keys) {
459 c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys),
460 env->GetStringLength(keys));
461 env->ReleaseStringCritical(keys, c_keys);
462 }
463 return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
464 }
465
466 static void
android_media_AudioSystem_error_callback(status_t err)467 android_media_AudioSystem_error_callback(status_t err)
468 {
469 JNIEnv *env = AndroidRuntime::getJNIEnv();
470 if (env == NULL) {
471 return;
472 }
473
474 jclass clazz = env->FindClass(kClassPathName);
475
476 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
477 "errorCallbackFromNative","(I)V"),
478 check_AudioSystem_Command(err));
479
480 env->DeleteLocalRef(clazz);
481 }
482
483 static void
android_media_AudioSystem_dyn_policy_callback(int event,String8 regId,int val)484 android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
485 {
486 JNIEnv *env = AndroidRuntime::getJNIEnv();
487 if (env == NULL) {
488 return;
489 }
490
491 jclass clazz = env->FindClass(kClassPathName);
492 const char* zechars = regId.string();
493 jstring zestring = env->NewStringUTF(zechars);
494
495 env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
496 event, zestring, val);
497
498 env->ReleaseStringUTFChars(zestring, zechars);
499 env->DeleteLocalRef(clazz);
500 }
501
502 static void
android_media_AudioSystem_recording_callback(int event,const record_client_info_t * clientInfo,const audio_config_base_t * clientConfig,std::vector<effect_descriptor_t> clientEffects,const audio_config_base_t * deviceConfig,std::vector<effect_descriptor_t> effects __unused,audio_patch_handle_t patchHandle,audio_source_t source)503 android_media_AudioSystem_recording_callback(int event,
504 const record_client_info_t *clientInfo,
505 const audio_config_base_t *clientConfig,
506 std::vector<effect_descriptor_t> clientEffects,
507 const audio_config_base_t *deviceConfig,
508 std::vector<effect_descriptor_t> effects __unused,
509 audio_patch_handle_t patchHandle,
510 audio_source_t source)
511 {
512 JNIEnv *env = AndroidRuntime::getJNIEnv();
513 if (env == NULL) {
514 return;
515 }
516 if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
517 ALOGE("Unexpected null client/device info or configurations in recording callback");
518 return;
519 }
520
521 // create an array for 2*3 integers to store the record configurations (client + device)
522 // plus 1 integer for the patch handle
523 const int REC_PARAM_SIZE = 7;
524 jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE);
525 if (recParamArray == NULL) {
526 ALOGE("recording callback: Couldn't allocate int array for configuration data");
527 return;
528 }
529 jint recParamData[REC_PARAM_SIZE];
530 recParamData[0] = (jint) audioFormatFromNative(clientConfig->format);
531 // FIXME this doesn't support index-based masks
532 recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask);
533 recParamData[2] = (jint) clientConfig->sample_rate;
534 recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format);
535 // FIXME this doesn't support index-based masks
536 recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask);
537 recParamData[5] = (jint) deviceConfig->sample_rate;
538 recParamData[6] = (jint) patchHandle;
539 env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData);
540
541 jobjectArray jClientEffects;
542 convertAudioEffectDescriptorVectorFromNative(env, &jClientEffects, clientEffects);
543
544 jobjectArray jEffects;
545 convertAudioEffectDescriptorVectorFromNative(env, &jEffects, effects);
546
547 // callback into java
548 jclass clazz = env->FindClass(kClassPathName);
549
550 env->CallStaticVoidMethod(clazz,
551 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
552 event, (jint) clientInfo->riid, (jint) clientInfo->uid,
553 clientInfo->session, clientInfo->source, clientInfo->port_id,
554 clientInfo->silenced, recParamArray, jClientEffects, jEffects,
555 source);
556 env->DeleteLocalRef(clazz);
557 env->DeleteLocalRef(recParamArray);
558 env->DeleteLocalRef(jClientEffects);
559 env->DeleteLocalRef(jEffects);
560 }
561
562 static void
android_media_AudioSystem_routing_callback()563 android_media_AudioSystem_routing_callback()
564 {
565 JNIEnv *env = AndroidRuntime::getJNIEnv();
566 if (env == NULL) {
567 return;
568 }
569
570 // callback into java
571 jclass clazz = env->FindClass(kClassPathName);
572 env->CallStaticVoidMethod(clazz,
573 gAudioPolicyEventHandlerMethods.postRoutingUpdatedFromNative);
574 env->DeleteLocalRef(clazz);
575 }
576
577 static jint
android_media_AudioSystem_setDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jint state,jstring device_address,jstring device_name,jint codec)578 android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
579 jint codec)
580 {
581 const char *c_address = env->GetStringUTFChars(device_address, NULL);
582 const char *c_name = env->GetStringUTFChars(device_name, NULL);
583 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
584 static_cast <audio_policy_dev_state_t>(state),
585 c_address, c_name,
586 static_cast <audio_format_t>(codec)));
587 env->ReleaseStringUTFChars(device_address, c_address);
588 env->ReleaseStringUTFChars(device_name, c_name);
589 return (jint) status;
590 }
591
592 static jint
android_media_AudioSystem_getDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jstring device_address)593 android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
594 {
595 const char *c_address = env->GetStringUTFChars(device_address, NULL);
596 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
597 c_address));
598 env->ReleaseStringUTFChars(device_address, c_address);
599 return (jint) state;
600 }
601
602 static jint
android_media_AudioSystem_handleDeviceConfigChange(JNIEnv * env,jobject thiz,jint device,jstring device_address,jstring device_name,jint codec)603 android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name,
604 jint codec)
605 {
606 const char *c_address = env->GetStringUTFChars(device_address, NULL);
607 const char *c_name = env->GetStringUTFChars(device_name, NULL);
608 int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
609 c_address, c_name, static_cast <audio_format_t>(codec)));
610 env->ReleaseStringUTFChars(device_address, c_address);
611 env->ReleaseStringUTFChars(device_name, c_name);
612 return (jint) status;
613 }
614
android_media_AudioSystem_setPhoneState(JNIEnv * env,jobject thiz,jint state,jint uid)615 static jint android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state,
616 jint uid) {
617 return (jint)check_AudioSystem_Command(
618 AudioSystem::setPhoneState((audio_mode_t)state, (uid_t)uid));
619 }
620
621 static jint
android_media_AudioSystem_setForceUse(JNIEnv * env,jobject thiz,jint usage,jint config)622 android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
623 {
624 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
625 static_cast <audio_policy_forced_cfg_t>(config)));
626 }
627
628 static jint
android_media_AudioSystem_getForceUse(JNIEnv * env,jobject thiz,jint usage)629 android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
630 {
631 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
632 }
633
634 static jint
android_media_AudioSystem_initStreamVolume(JNIEnv * env,jobject thiz,jint stream,jint indexMin,jint indexMax)635 android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
636 {
637 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
638 indexMin,
639 indexMax));
640 }
641
642 static jint
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint index,jint device)643 android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
644 jobject thiz,
645 jint stream,
646 jint index,
647 jint device)
648 {
649 return (jint) check_AudioSystem_Command(
650 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
651 index,
652 (audio_devices_t)device));
653 }
654
655 static jint
android_media_AudioSystem_getStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint device)656 android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
657 jobject thiz,
658 jint stream,
659 jint device)
660 {
661 int index;
662 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
663 &index,
664 (audio_devices_t)device)
665 != NO_ERROR) {
666 index = -1;
667 }
668 return (jint) index;
669 }
670
671 static jint
android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv * env,jobject thiz,jobject jaa,jint index,jint device)672 android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env,
673 jobject thiz,
674 jobject jaa,
675 jint index,
676 jint device)
677 {
678 // read the AudioAttributes values
679 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
680 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
681 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
682 return jStatus;
683 }
684 return (jint) check_AudioSystem_Command(
685 AudioSystem::setVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device));
686 }
687
688 static jint
android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv * env,jobject thiz,jobject jaa,jint device)689 android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
690 jobject thiz,
691 jobject jaa,
692 jint device)
693 {
694 // read the AudioAttributes values
695 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
696 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
697 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
698 return jStatus;
699 }
700 int index;
701 if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, (audio_devices_t)device)
702 != NO_ERROR) {
703 index = -1;
704 }
705 return (jint) index;
706 }
707
708 static jint
android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv * env,jobject thiz,jobject jaa)709 android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
710 jobject thiz,
711 jobject jaa)
712 {
713 // read the AudioAttributes values
714 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
715 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
716 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
717 return jStatus;
718 }
719 int index;
720 if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index)
721 != NO_ERROR) {
722 index = -1;
723 }
724 return (jint) index;
725 }
726
727 static jint
android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv * env,jobject thiz,jobject jaa)728 android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
729 jobject thiz,
730 jobject jaa)
731 {
732 // read the AudioAttributes values
733 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
734 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
735 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
736 return jStatus;
737 }
738 int index;
739 if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index)
740 != NO_ERROR) {
741 index = -1;
742 }
743 return (jint) index;
744 }
745
746 static jint
android_media_AudioSystem_setMasterVolume(JNIEnv * env,jobject thiz,jfloat value)747 android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
748 {
749 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
750 }
751
752 static jfloat
android_media_AudioSystem_getMasterVolume(JNIEnv * env,jobject thiz)753 android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
754 {
755 float value;
756 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
757 value = -1.0;
758 }
759 return value;
760 }
761
762 static jint
android_media_AudioSystem_setMasterMute(JNIEnv * env,jobject thiz,jboolean mute)763 android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
764 {
765 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
766 }
767
768 static jboolean
android_media_AudioSystem_getMasterMute(JNIEnv * env,jobject thiz)769 android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
770 {
771 bool mute;
772 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
773 mute = false;
774 }
775 return mute;
776 }
777
778 static jint
android_media_AudioSystem_setMasterMono(JNIEnv * env,jobject thiz,jboolean mono)779 android_media_AudioSystem_setMasterMono(JNIEnv *env, jobject thiz, jboolean mono)
780 {
781 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMono(mono));
782 }
783
784 static jboolean
android_media_AudioSystem_getMasterMono(JNIEnv * env,jobject thiz)785 android_media_AudioSystem_getMasterMono(JNIEnv *env, jobject thiz)
786 {
787 bool mono;
788 if (AudioSystem::getMasterMono(&mono) != NO_ERROR) {
789 mono = false;
790 }
791 return mono;
792 }
793
794 static jint
android_media_AudioSystem_setMasterBalance(JNIEnv * env,jobject thiz,jfloat balance)795 android_media_AudioSystem_setMasterBalance(JNIEnv *env, jobject thiz, jfloat balance)
796 {
797 return (jint) check_AudioSystem_Command(AudioSystem::setMasterBalance(balance));
798 }
799
800 static jfloat
android_media_AudioSystem_getMasterBalance(JNIEnv * env,jobject thiz)801 android_media_AudioSystem_getMasterBalance(JNIEnv *env, jobject thiz)
802 {
803 float balance;
804 const status_t status = AudioSystem::getMasterBalance(&balance);
805 if (status != NO_ERROR) {
806 ALOGW("%s getMasterBalance error %d, returning 0.f, audioserver down?", __func__, status);
807 balance = 0.f;
808 }
809 return balance;
810 }
811
812 static jint
android_media_AudioSystem_getDevicesForStream(JNIEnv * env,jobject thiz,jint stream)813 android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
814 {
815 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
816 }
817
818 static jint
android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv * env,jobject clazz)819 android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
820 {
821 return (jint) AudioSystem::getPrimaryOutputSamplingRate();
822 }
823
824 static jint
android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv * env,jobject clazz)825 android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
826 {
827 return (jint) AudioSystem::getPrimaryOutputFrameCount();
828 }
829
830 static jint
android_media_AudioSystem_getOutputLatency(JNIEnv * env,jobject clazz,jint stream)831 android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
832 {
833 uint32_t afLatency;
834 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
835 != NO_ERROR) {
836 afLatency = -1;
837 }
838 return (jint) afLatency;
839 }
840
841 static jint
android_media_AudioSystem_setLowRamDevice(JNIEnv * env,jobject clazz,jboolean isLowRamDevice,jlong totalMemory)842 android_media_AudioSystem_setLowRamDevice(
843 JNIEnv *env, jobject clazz, jboolean isLowRamDevice, jlong totalMemory)
844 {
845 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice, (int64_t) totalMemory);
846 }
847
848 static jint
android_media_AudioSystem_checkAudioFlinger(JNIEnv * env,jobject clazz)849 android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
850 {
851 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
852 }
853
android_media_AudioSystem_setAudioFlingerBinder(JNIEnv * env,jobject clazz,jobject audioFlinger)854 static void android_media_AudioSystem_setAudioFlingerBinder(JNIEnv *env, jobject clazz,
855 jobject audioFlinger) {
856 AudioSystem::setAudioFlingerBinder(android::ibinderForJavaObject(env, audioFlinger));
857 }
858
convertAudioGainConfigToNative(JNIEnv * env,struct audio_gain_config * nAudioGainConfig,const jobject jAudioGainConfig,bool useInMask)859 static void convertAudioGainConfigToNative(JNIEnv *env,
860 struct audio_gain_config *nAudioGainConfig,
861 const jobject jAudioGainConfig,
862 bool useInMask)
863 {
864 nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex);
865 nAudioGainConfig->mode =
866 (audio_gain_mode_t)env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode);
867 ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index);
868 jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask);
869 audio_channel_mask_t nMask;
870 if (useInMask) {
871 nMask = inChannelMaskToNative(jMask);
872 ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask);
873 } else {
874 nMask = outChannelMaskToNative(jMask);
875 ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask);
876 }
877 nAudioGainConfig->channel_mask = nMask;
878 nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig,
879 gAudioGainConfigFields.mRampDurationMs);
880 jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig,
881 gAudioGainConfigFields.mValues);
882 int *nValues = env->GetIntArrayElements(jValues, NULL);
883 size_t size = env->GetArrayLength(jValues);
884 memcpy(nAudioGainConfig->values, nValues, size * sizeof(int));
885 env->DeleteLocalRef(jValues);
886 }
887
convertAudioPortConfigToNative(JNIEnv * env,struct audio_port_config * nAudioPortConfig,const jobject jAudioPortConfig,bool useConfigMask)888 static jint convertAudioPortConfigToNative(JNIEnv *env,
889 struct audio_port_config *nAudioPortConfig,
890 const jobject jAudioPortConfig,
891 bool useConfigMask)
892 {
893 jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
894 jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
895 nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId);
896 nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort,
897 gAudioPortFields.mRole);
898 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
899 nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE;
900 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
901 nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX;
902 } else {
903 env->DeleteLocalRef(jAudioPort);
904 env->DeleteLocalRef(jHandle);
905 return (jint)AUDIO_JAVA_ERROR;
906 }
907 ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
908 nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
909
910 unsigned int configMask = 0;
911
912 nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
913 gAudioPortConfigFields.mSamplingRate);
914 if (nAudioPortConfig->sample_rate != 0) {
915 configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
916 }
917
918 bool useInMask = audio_port_config_has_input_direction(nAudioPortConfig);
919 audio_channel_mask_t nMask;
920 jint jMask = env->GetIntField(jAudioPortConfig,
921 gAudioPortConfigFields.mChannelMask);
922 if (useInMask) {
923 nMask = inChannelMaskToNative(jMask);
924 ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask);
925 } else {
926 nMask = outChannelMaskToNative(jMask);
927 ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
928 }
929 nAudioPortConfig->channel_mask = nMask;
930 if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
931 configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
932 }
933
934 jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
935 audio_format_t nFormat = audioFormatToNative(jFormat);
936 ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
937 nAudioPortConfig->format = nFormat;
938 if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
939 nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
940 configMask |= AUDIO_PORT_CONFIG_FORMAT;
941 }
942
943 jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
944 if (jGain != NULL) {
945 convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
946 env->DeleteLocalRef(jGain);
947 configMask |= AUDIO_PORT_CONFIG_GAIN;
948 } else {
949 ALOGV("convertAudioPortConfigToNative no gain");
950 nAudioPortConfig->gain.index = -1;
951 }
952 if (useConfigMask) {
953 nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
954 gAudioPortConfigFields.mConfigMask);
955 } else {
956 nAudioPortConfig->config_mask = configMask;
957 }
958 env->DeleteLocalRef(jAudioPort);
959 env->DeleteLocalRef(jHandle);
960 return (jint)AUDIO_JAVA_SUCCESS;
961 }
962
963 /**
964 * Extends convertAudioPortConfigToNative with extra device port info.
965 * Mix / Session specific info is not fulfilled.
966 */
convertAudioPortConfigToNativeWithDevicePort(JNIEnv * env,struct audio_port_config * nAudioPortConfig,const jobject jAudioPortConfig,bool useConfigMask)967 static jint convertAudioPortConfigToNativeWithDevicePort(JNIEnv *env,
968 struct audio_port_config *nAudioPortConfig,
969 const jobject jAudioPortConfig,
970 bool useConfigMask)
971 {
972 jint jStatus = convertAudioPortConfigToNative(env,
973 nAudioPortConfig,
974 jAudioPortConfig,
975 useConfigMask);
976 if (jStatus != AUDIO_JAVA_SUCCESS) {
977 return jStatus;
978 }
979 // Supports AUDIO_PORT_TYPE_DEVICE only
980 if (nAudioPortConfig->type != AUDIO_PORT_TYPE_DEVICE) {
981 return (jint)AUDIO_JAVA_BAD_VALUE;
982 }
983
984 jobject jAudioDevicePort = env->GetObjectField(jAudioPortConfig,
985 gAudioPortConfigFields.mPort);
986 nAudioPortConfig->ext.device.type =
987 (audio_devices_t)env->GetIntField(jAudioDevicePort, gAudioPortFields.mType);
988 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioDevicePort,
989 gAudioPortFields.mAddress);
990 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
991 strncpy(nAudioPortConfig->ext.device.address,
992 nDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN - 1);
993 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
994 env->DeleteLocalRef(jDeviceAddress);
995 env->DeleteLocalRef(jAudioDevicePort);
996 return jStatus;
997 }
998
convertAudioPortConfigFromNative(JNIEnv * env,jobject jAudioPort,jobject * jAudioPortConfig,const struct audio_port_config * nAudioPortConfig)999 static jint convertAudioPortConfigFromNative(JNIEnv *env,
1000 jobject jAudioPort,
1001 jobject *jAudioPortConfig,
1002 const struct audio_port_config *nAudioPortConfig)
1003 {
1004 jint jStatus = AUDIO_JAVA_SUCCESS;
1005 jobject jAudioGainConfig = NULL;
1006 jobject jAudioGain = NULL;
1007 jintArray jGainValues;
1008 bool audioportCreated = false;
1009
1010 ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort);
1011
1012 if (jAudioPort == NULL) {
1013 jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1014 nAudioPortConfig->id);
1015
1016 ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id,
1017 nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix");
1018
1019 if (jHandle == NULL) {
1020 return (jint)AUDIO_JAVA_ERROR;
1021 }
1022 // create placeholder port and port config objects with just the correct handle
1023 // and configuration data. The actual AudioPortConfig objects will be
1024 // constructed by java code with correct class type (device, mix etc...)
1025 // and reference to AudioPort instance in this client
1026 jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
1027 jHandle, // handle
1028 0, // role
1029 NULL, // name
1030 NULL, // samplingRates
1031 NULL, // channelMasks
1032 NULL, // channelIndexMasks
1033 NULL, // formats
1034 NULL); // gains
1035 env->DeleteLocalRef(jHandle);
1036 if (jAudioPort == NULL) {
1037 return (jint)AUDIO_JAVA_ERROR;
1038 }
1039 ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d",
1040 nAudioPortConfig->id);
1041
1042 audioportCreated = true;
1043 }
1044
1045 bool useInMask = audio_port_config_has_input_direction(nAudioPortConfig);
1046
1047 audio_channel_mask_t nMask;
1048 jint jMask;
1049
1050 int gainIndex = (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
1051 ? nAudioPortConfig->gain.index
1052 : -1;
1053 if (gainIndex >= 0) {
1054 ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
1055 gainIndex, nAudioPortConfig->gain.mode);
1056 if (audioportCreated) {
1057 ALOGV("convertAudioPortConfigFromNative creating gain");
1058 jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1059 gainIndex,
1060 0,
1061 0,
1062 0,
1063 0,
1064 0,
1065 0,
1066 0,
1067 0);
1068 if (jAudioGain == NULL) {
1069 ALOGV("convertAudioPortConfigFromNative creating gain FAILED");
1070 jStatus = (jint)AUDIO_JAVA_ERROR;
1071 goto exit;
1072 }
1073 } else {
1074 ALOGV("convertAudioPortConfigFromNative reading gain from port");
1075 jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort,
1076 gAudioPortFields.mGains);
1077 if (jGains == NULL) {
1078 ALOGV("convertAudioPortConfigFromNative could not get gains from port");
1079 jStatus = (jint)AUDIO_JAVA_ERROR;
1080 goto exit;
1081 }
1082 jAudioGain = env->GetObjectArrayElement(jGains, gainIndex);
1083 env->DeleteLocalRef(jGains);
1084 if (jAudioGain == NULL) {
1085 ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex);
1086 jStatus = (jint)AUDIO_JAVA_ERROR;
1087 goto exit;
1088 }
1089 }
1090 int numValues;
1091 if (useInMask) {
1092 numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
1093 } else {
1094 numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
1095 }
1096 jGainValues = env->NewIntArray(numValues);
1097 if (jGainValues == NULL) {
1098 ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
1099 jStatus = (jint)AUDIO_JAVA_ERROR;
1100 goto exit;
1101 }
1102 env->SetIntArrayRegion(jGainValues, 0, numValues,
1103 nAudioPortConfig->gain.values);
1104
1105 nMask = nAudioPortConfig->gain.channel_mask;
1106 if (useInMask) {
1107 jMask = inChannelMaskFromNative(nMask);
1108 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1109 } else {
1110 jMask = outChannelMaskFromNative(nMask);
1111 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1112 }
1113
1114 jAudioGainConfig = env->NewObject(gAudioGainConfigClass,
1115 gAudioGainConfigCstor,
1116 gainIndex,
1117 jAudioGain,
1118 nAudioPortConfig->gain.mode,
1119 jMask,
1120 jGainValues,
1121 nAudioPortConfig->gain.ramp_duration_ms);
1122 env->DeleteLocalRef(jGainValues);
1123 if (jAudioGainConfig == NULL) {
1124 ALOGV("convertAudioPortConfigFromNative could not create gain config");
1125 jStatus = (jint)AUDIO_JAVA_ERROR;
1126 goto exit;
1127 }
1128 }
1129 jclass clazz;
1130 jmethodID methodID;
1131 if (audioportCreated) {
1132 clazz = gAudioPortConfigClass;
1133 methodID = gAudioPortConfigCstor;
1134 ALOGV("convertAudioPortConfigFromNative building a generic port config");
1135 } else {
1136 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
1137 clazz = gAudioDevicePortConfigClass;
1138 methodID = gAudioDevicePortConfigCstor;
1139 ALOGV("convertAudioPortConfigFromNative building a device config");
1140 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
1141 clazz = gAudioMixPortConfigClass;
1142 methodID = gAudioMixPortConfigCstor;
1143 ALOGV("convertAudioPortConfigFromNative building a mix config");
1144 } else {
1145 jStatus = (jint)AUDIO_JAVA_ERROR;
1146 goto exit;
1147 }
1148 }
1149 nMask = (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)
1150 ? nAudioPortConfig->channel_mask
1151 : AUDIO_CONFIG_BASE_INITIALIZER.channel_mask;
1152 if (useInMask) {
1153 jMask = inChannelMaskFromNative(nMask);
1154 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1155 } else {
1156 jMask = outChannelMaskFromNative(nMask);
1157 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1158 }
1159
1160 *jAudioPortConfig =
1161 env->NewObject(clazz, methodID, jAudioPort,
1162 (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)
1163 ? nAudioPortConfig->sample_rate
1164 : AUDIO_CONFIG_BASE_INITIALIZER.sample_rate,
1165 jMask,
1166 audioFormatFromNative(
1167 (nAudioPortConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)
1168 ? nAudioPortConfig->format
1169 : AUDIO_CONFIG_BASE_INITIALIZER.format),
1170 jAudioGainConfig);
1171 if (*jAudioPortConfig == NULL) {
1172 ALOGV("convertAudioPortConfigFromNative could not create new port config");
1173 jStatus = (jint)AUDIO_JAVA_ERROR;
1174 } else {
1175 ALOGV("convertAudioPortConfigFromNative OK");
1176 }
1177
1178 exit:
1179 if (audioportCreated) {
1180 env->DeleteLocalRef(jAudioPort);
1181 if (jAudioGain != NULL) {
1182 env->DeleteLocalRef(jAudioGain);
1183 }
1184 }
1185 if (jAudioGainConfig != NULL) {
1186 env->DeleteLocalRef(jAudioGainConfig);
1187 }
1188 return jStatus;
1189 }
1190
1191 // TODO: pull out to separate file
1192 template <typename T, size_t N>
array_size(const T (&)[N])1193 static constexpr size_t array_size(const T (&)[N]) {
1194 return N;
1195 }
1196
convertEncapsulationInfoFromNative(JNIEnv * env,uint32_t encapsulationInfo)1197 static jintArray convertEncapsulationInfoFromNative(JNIEnv *env, uint32_t encapsulationInfo) {
1198 std::vector<int> encapsulation;
1199 // Ignore the first bit, which is ENCAPSULATION_.*_NONE, as an empty array
1200 // should be returned if no encapsulation is supported.
1201 encapsulationInfo >>= 1;
1202 for (int bitPosition = 1; encapsulationInfo; encapsulationInfo >>= 1, bitPosition++) {
1203 if (encapsulationInfo & 1) {
1204 encapsulation.push_back(bitPosition);
1205 }
1206 }
1207 jintArray result = env->NewIntArray(encapsulation.size());
1208 env->SetIntArrayRegion(result, 0, encapsulation.size(), (jint *)encapsulation.data());
1209 return result;
1210 }
1211
isAudioPortArrayCountOutOfBounds(const struct audio_port_v7 * nAudioPort,std::stringstream & ss)1212 static bool isAudioPortArrayCountOutOfBounds(const struct audio_port_v7 *nAudioPort,
1213 std::stringstream &ss) {
1214 ss << " num_audio_profiles " << nAudioPort->num_audio_profiles << " num_gains "
1215 << nAudioPort->num_gains;
1216 if (nAudioPort->num_audio_profiles > array_size(nAudioPort->audio_profiles) ||
1217 nAudioPort->num_gains > array_size(nAudioPort->gains)) {
1218 return true;
1219 }
1220 for (size_t i = 0; i < nAudioPort->num_audio_profiles; ++i) {
1221 ss << " (" << i << ") audio profile,"
1222 << " num_sample_rates " << nAudioPort->audio_profiles[i].num_sample_rates
1223 << " num_channel_masks " << nAudioPort->audio_profiles[i].num_channel_masks;
1224 if (nAudioPort->audio_profiles[i].num_sample_rates >
1225 array_size(nAudioPort->audio_profiles[i].sample_rates) ||
1226 nAudioPort->audio_profiles[i].num_channel_masks >
1227 array_size(nAudioPort->audio_profiles[i].channel_masks)) {
1228 return true;
1229 }
1230 }
1231 return false;
1232 }
1233
convertAudioPortFromNative(JNIEnv * env,jobject * jAudioPort,const struct audio_port_v7 * nAudioPort)1234 static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
1235 const struct audio_port_v7 *nAudioPort) {
1236 jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
1237 jintArray jEncapsulationModes = NULL;
1238 jintArray jEncapsulationMetadataTypes = NULL;
1239 jobjectArray jGains = NULL;
1240 jobject jHandle = NULL;
1241 jobject jAudioPortConfig = NULL;
1242 jstring jDeviceName = NULL;
1243 jobject jAudioProfiles = NULL;
1244 jobject jAudioDescriptors = nullptr;
1245 ScopedLocalRef<jobject> jPcmFloatProfileFromExtendedInteger(env, nullptr);
1246 bool hasFloat = false;
1247 bool useInMask;
1248
1249 ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
1250 nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
1251
1252 // Verify audio port array count info.
1253 if (std::stringstream ss; isAudioPortArrayCountOutOfBounds(nAudioPort, ss)) {
1254 std::string s = "convertAudioPortFromNative array count out of bounds:" + ss.str();
1255
1256 // Prefer to log through Java wtf instead of native ALOGE.
1257 ScopedLocalRef<jclass> jLogClass(env, env->FindClass("android/util/Log"));
1258 jmethodID jWtfId = (jLogClass.get() == nullptr)
1259 ? nullptr
1260 : env->GetStaticMethodID(jLogClass.get(), "wtf",
1261 "(Ljava/lang/String;Ljava/lang/String;)I");
1262 if (jWtfId != nullptr) {
1263 ScopedLocalRef<jstring> jMessage(env, env->NewStringUTF(s.c_str()));
1264 ScopedLocalRef<jstring> jTag(env, env->NewStringUTF(LOG_TAG));
1265 (void)env->CallStaticIntMethod(jLogClass.get(), jWtfId, jTag.get(), jMessage.get());
1266 } else {
1267 ALOGE("%s", s.c_str());
1268 }
1269 jStatus = (jint)AUDIO_JAVA_ERROR;
1270 goto exit;
1271 }
1272
1273 useInMask = audio_has_input_direction(nAudioPort->type, nAudioPort->role);
1274 jAudioProfiles = env->NewObject(gArrayListClass, gArrayListMethods.cstor);
1275 if (jAudioProfiles == nullptr) {
1276 jStatus = (jint)AUDIO_JAVA_ERROR;
1277 goto exit;
1278 }
1279 for (size_t i = 0; i < nAudioPort->num_audio_profiles; ++i) {
1280 size_t numPositionMasks = 0;
1281 size_t numIndexMasks = 0;
1282 // count up how many masks are positional and indexed
1283 for (size_t index = 0; index < nAudioPort->audio_profiles[i].num_channel_masks; index++) {
1284 const audio_channel_mask_t mask = nAudioPort->audio_profiles[i].channel_masks[index];
1285 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1286 numIndexMasks++;
1287 } else {
1288 numPositionMasks++;
1289 }
1290 }
1291
1292 ScopedLocalRef<jintArray> jSamplingRates(env,
1293 env->NewIntArray(nAudioPort->audio_profiles[i]
1294 .num_sample_rates));
1295 ScopedLocalRef<jintArray> jChannelMasks(env, env->NewIntArray(numPositionMasks));
1296 ScopedLocalRef<jintArray> jChannelIndexMasks(env, env->NewIntArray(numIndexMasks));
1297 if (!jSamplingRates.get() || !jChannelMasks.get() || !jChannelIndexMasks.get()) {
1298 jStatus = (jint)AUDIO_JAVA_ERROR;
1299 goto exit;
1300 }
1301
1302 if (nAudioPort->audio_profiles[i].num_sample_rates) {
1303 env->SetIntArrayRegion(jSamplingRates.get(), 0 /*start*/,
1304 nAudioPort->audio_profiles[i].num_sample_rates,
1305 (jint *)nAudioPort->audio_profiles[i].sample_rates);
1306 }
1307
1308 // put the masks in the output arrays
1309 for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
1310 maskIndex < nAudioPort->audio_profiles[i].num_channel_masks; maskIndex++) {
1311 const audio_channel_mask_t mask =
1312 nAudioPort->audio_profiles[i].channel_masks[maskIndex];
1313 if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1314 jint jMask = audio_channel_mask_get_bits(mask);
1315 env->SetIntArrayRegion(jChannelIndexMasks.get(), indexedMaskIndex++, 1, &jMask);
1316 } else {
1317 jint jMask =
1318 useInMask ? inChannelMaskFromNative(mask) : outChannelMaskFromNative(mask);
1319 env->SetIntArrayRegion(jChannelMasks.get(), posMaskIndex++, 1, &jMask);
1320 }
1321 }
1322
1323 int encapsulationType;
1324 if (audioEncapsulationTypeFromNative(nAudioPort->audio_profiles[i].encapsulation_type,
1325 &encapsulationType) != NO_ERROR) {
1326 ALOGW("Unknown encapsualtion type for JAVA API: %u",
1327 nAudioPort->audio_profiles[i].encapsulation_type);
1328 continue;
1329 }
1330
1331 ScopedLocalRef<jobject>
1332 jAudioProfile(env,
1333 env->NewObject(gAudioProfileClass, gAudioProfileCstor,
1334 audioFormatFromNative(
1335 nAudioPort->audio_profiles[i].format),
1336 jSamplingRates.get(), jChannelMasks.get(),
1337 jChannelIndexMasks.get(), encapsulationType));
1338 if (jAudioProfile == nullptr) {
1339 jStatus = (jint)AUDIO_JAVA_ERROR;
1340 goto exit;
1341 }
1342 env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add, jAudioProfile.get());
1343 if (nAudioPort->audio_profiles[i].format == AUDIO_FORMAT_PCM_FLOAT) {
1344 hasFloat = true;
1345 } else if (jPcmFloatProfileFromExtendedInteger.get() == nullptr &&
1346 audio_is_linear_pcm(nAudioPort->audio_profiles[i].format) &&
1347 audio_bytes_per_sample(nAudioPort->audio_profiles[i].format) > 2) {
1348 jPcmFloatProfileFromExtendedInteger.reset(
1349 env->NewObject(gAudioProfileClass, gAudioProfileCstor,
1350 audioFormatFromNative(AUDIO_FORMAT_PCM_FLOAT),
1351 jSamplingRates.get(), jChannelMasks.get(),
1352 jChannelIndexMasks.get(), encapsulationType));
1353 }
1354 }
1355 if (!hasFloat && jPcmFloatProfileFromExtendedInteger.get() != nullptr) {
1356 // R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
1357 // (replacing the zero pad). This ensures pre-S apps that look
1358 // for ENCODING_PCM_FLOAT continue to see that encoding if the device supports
1359 // extended precision integers.
1360 env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add,
1361 jPcmFloatProfileFromExtendedInteger.get());
1362 }
1363
1364 jAudioDescriptors = env->NewObject(gArrayListClass, gArrayListMethods.cstor);
1365 if (jAudioDescriptors == nullptr) {
1366 jStatus = (jint)AUDIO_JAVA_ERROR;
1367 goto exit;
1368 }
1369 for (size_t i = 0; i < nAudioPort->num_extra_audio_descriptors; ++i) {
1370 const auto &extraAudioDescriptor = nAudioPort->extra_audio_descriptors[i];
1371 ScopedLocalRef<jobject> jAudioDescriptor(env);
1372 if (extraAudioDescriptor.descriptor_length == 0) {
1373 continue;
1374 }
1375 int standard;
1376 if (audioStandardFromNative(extraAudioDescriptor.standard, &standard) != NO_ERROR) {
1377 ALOGW("Unknown standard for JAVA API: %u", extraAudioDescriptor.standard);
1378 continue;
1379 }
1380 int encapsulationType;
1381 if (audioEncapsulationTypeFromNative(extraAudioDescriptor.encapsulation_type,
1382 &encapsulationType) != NO_ERROR) {
1383 ALOGW("Unknown encapsualtion type for JAVA API: %u",
1384 extraAudioDescriptor.encapsulation_type);
1385 continue;
1386 }
1387 ScopedLocalRef<jbyteArray> jDescriptor(env,
1388 env->NewByteArray(
1389 extraAudioDescriptor.descriptor_length));
1390 env->SetByteArrayRegion(jDescriptor.get(), 0, extraAudioDescriptor.descriptor_length,
1391 reinterpret_cast<const jbyte *>(extraAudioDescriptor.descriptor));
1392 jAudioDescriptor =
1393 ScopedLocalRef<jobject>(env,
1394 env->NewObject(gAudioDescriptorClass, gAudioDescriptorCstor,
1395 standard, encapsulationType,
1396 jDescriptor.get()));
1397 env->CallBooleanMethod(jAudioDescriptors, gArrayListMethods.add, jAudioDescriptor.get());
1398 }
1399
1400 // gains
1401 jGains = env->NewObjectArray(nAudioPort->num_gains,
1402 gAudioGainClass, NULL);
1403 if (jGains == NULL) {
1404 jStatus = (jint)AUDIO_JAVA_ERROR;
1405 goto exit;
1406 }
1407
1408 for (size_t j = 0; j < nAudioPort->num_gains; j++) {
1409 audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
1410 jint jMask;
1411 if (useInMask) {
1412 jMask = inChannelMaskFromNative(nMask);
1413 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1414 } else {
1415 jMask = outChannelMaskFromNative(nMask);
1416 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1417 }
1418
1419 jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1420 j,
1421 nAudioPort->gains[j].mode,
1422 jMask,
1423 nAudioPort->gains[j].min_value,
1424 nAudioPort->gains[j].max_value,
1425 nAudioPort->gains[j].default_value,
1426 nAudioPort->gains[j].step_value,
1427 nAudioPort->gains[j].min_ramp_ms,
1428 nAudioPort->gains[j].max_ramp_ms);
1429 if (jGain == NULL) {
1430 jStatus = (jint)AUDIO_JAVA_ERROR;
1431 goto exit;
1432 }
1433 env->SetObjectArrayElement(jGains, j, jGain);
1434 env->DeleteLocalRef(jGain);
1435 }
1436
1437 jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1438 nAudioPort->id);
1439 if (jHandle == NULL) {
1440 jStatus = (jint)AUDIO_JAVA_ERROR;
1441 goto exit;
1442 }
1443
1444 jDeviceName = env->NewStringUTF(nAudioPort->name);
1445
1446 if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) {
1447 ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type);
1448 jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
1449 jEncapsulationModes =
1450 convertEncapsulationInfoFromNative(env, nAudioPort->ext.device.encapsulation_modes);
1451 jEncapsulationMetadataTypes =
1452 convertEncapsulationInfoFromNative(env,
1453 nAudioPort->ext.device
1454 .encapsulation_metadata_types);
1455 *jAudioPort =
1456 env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor, jHandle, jDeviceName,
1457 jAudioProfiles, jGains, nAudioPort->ext.device.type, jAddress,
1458 jEncapsulationModes, jEncapsulationMetadataTypes, jAudioDescriptors);
1459 env->DeleteLocalRef(jAddress);
1460 } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
1461 ALOGV("convertAudioPortFromNative is a mix");
1462 *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor, jHandle,
1463 nAudioPort->ext.mix.handle, nAudioPort->role, jDeviceName,
1464 jAudioProfiles, jGains);
1465 } else {
1466 ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
1467 jStatus = (jint)AUDIO_JAVA_ERROR;
1468 goto exit;
1469 }
1470 if (*jAudioPort == NULL) {
1471 jStatus = (jint)AUDIO_JAVA_ERROR;
1472 goto exit;
1473 }
1474
1475 jStatus = convertAudioPortConfigFromNative(env,
1476 *jAudioPort,
1477 &jAudioPortConfig,
1478 &nAudioPort->active_config);
1479 if (jStatus != AUDIO_JAVA_SUCCESS) {
1480 goto exit;
1481 }
1482
1483 env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig);
1484
1485 exit:
1486 if (jDeviceName != NULL) {
1487 env->DeleteLocalRef(jDeviceName);
1488 }
1489 if (jEncapsulationModes != NULL) {
1490 env->DeleteLocalRef(jEncapsulationModes);
1491 }
1492 if (jEncapsulationMetadataTypes != NULL) {
1493 env->DeleteLocalRef(jEncapsulationMetadataTypes);
1494 }
1495 if (jAudioProfiles != NULL) {
1496 env->DeleteLocalRef(jAudioProfiles);
1497 }
1498 if (jGains != NULL) {
1499 env->DeleteLocalRef(jGains);
1500 }
1501 if (jHandle != NULL) {
1502 env->DeleteLocalRef(jHandle);
1503 }
1504 if (jAudioPortConfig != NULL) {
1505 env->DeleteLocalRef(jAudioPortConfig);
1506 }
1507 if (jAudioDescriptors != nullptr) {
1508 env->DeleteLocalRef(jAudioDescriptors);
1509 }
1510
1511 return jStatus;
1512 }
1513
1514 static jint
android_media_AudioSystem_listAudioPorts(JNIEnv * env,jobject clazz,jobject jPorts,jintArray jGeneration)1515 android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
1516 jobject jPorts, jintArray jGeneration)
1517 {
1518 ALOGV("listAudioPorts");
1519
1520 if (jPorts == NULL) {
1521 ALOGE("listAudioPorts NULL AudioPort ArrayList");
1522 return (jint)AUDIO_JAVA_BAD_VALUE;
1523 }
1524 if (!env->IsInstanceOf(jPorts, gArrayListClass)) {
1525 ALOGE("listAudioPorts not an arraylist");
1526 return (jint)AUDIO_JAVA_BAD_VALUE;
1527 }
1528
1529 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1530 return (jint)AUDIO_JAVA_BAD_VALUE;
1531 }
1532
1533 status_t status;
1534 unsigned int generation1;
1535 unsigned int generation;
1536 unsigned int numPorts;
1537 jint *nGeneration;
1538 struct audio_port_v7 *nPorts = nullptr;
1539 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
1540 jint jStatus;
1541
1542 // get the port count and all the ports until they both return the same generation
1543 do {
1544 if (attempts-- < 0) {
1545 status = TIMED_OUT;
1546 break;
1547 }
1548
1549 numPorts = 0;
1550 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
1551 nullptr, &generation1);
1552 if (status != NO_ERROR) {
1553 ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status);
1554 break;
1555 }
1556 if (numPorts == 0) {
1557 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1558 goto exit;
1559 }
1560 nPorts = (struct audio_port_v7 *)realloc(nPorts, numPorts * sizeof(struct audio_port_v7));
1561
1562 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
1563 nPorts, &generation);
1564 ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d",
1565 numPorts, generation, generation1);
1566 } while (generation1 != generation && status == NO_ERROR);
1567
1568 jStatus = nativeToJavaStatus(status);
1569 if (jStatus != AUDIO_JAVA_SUCCESS) {
1570 goto exit;
1571 }
1572
1573 for (size_t i = 0; i < numPorts; i++) {
1574 jobject jAudioPort = NULL;
1575 jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
1576 if (jStatus != AUDIO_JAVA_SUCCESS) {
1577 goto exit;
1578 }
1579 env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
1580 if (jAudioPort != NULL) {
1581 env->DeleteLocalRef(jAudioPort);
1582 }
1583 }
1584
1585 exit:
1586 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1587 if (nGeneration == NULL) {
1588 jStatus = (jint)AUDIO_JAVA_ERROR;
1589 } else {
1590 nGeneration[0] = generation1;
1591 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1592 }
1593 free(nPorts);
1594 return jStatus;
1595 }
1596
1597 static int
android_media_AudioSystem_createAudioPatch(JNIEnv * env,jobject clazz,jobjectArray jPatches,jobjectArray jSources,jobjectArray jSinks)1598 android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz,
1599 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks)
1600 {
1601 status_t status;
1602 jint jStatus;
1603
1604 ALOGV("createAudioPatch");
1605 if (jPatches == NULL || jSources == NULL || jSinks == NULL) {
1606 return (jint)AUDIO_JAVA_BAD_VALUE;
1607 }
1608
1609 if (env->GetArrayLength(jPatches) != 1) {
1610 return (jint)AUDIO_JAVA_BAD_VALUE;
1611 }
1612 jint numSources = env->GetArrayLength(jSources);
1613 if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) {
1614 return (jint)AUDIO_JAVA_BAD_VALUE;
1615 }
1616
1617 jint numSinks = env->GetArrayLength(jSinks);
1618 if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) {
1619 return (jint)AUDIO_JAVA_BAD_VALUE;
1620 }
1621
1622 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1623 jobject jPatch = env->GetObjectArrayElement(jPatches, 0);
1624 jobject jPatchHandle = NULL;
1625 if (jPatch != NULL) {
1626 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1627 return (jint)AUDIO_JAVA_BAD_VALUE;
1628 }
1629 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1630 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1631 }
1632
1633 struct audio_patch nPatch = { .id = handle };
1634
1635 jobject jSource = NULL;
1636 jobject jSink = NULL;
1637
1638 for (jint i = 0; i < numSources; i++) {
1639 jSource = env->GetObjectArrayElement(jSources, i);
1640 if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) {
1641 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1642 goto exit;
1643 }
1644 jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
1645 env->DeleteLocalRef(jSource);
1646 jSource = NULL;
1647 if (jStatus != AUDIO_JAVA_SUCCESS) {
1648 goto exit;
1649 }
1650 nPatch.num_sources++;
1651 }
1652
1653 for (jint i = 0; i < numSinks; i++) {
1654 jSink = env->GetObjectArrayElement(jSinks, i);
1655 if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) {
1656 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1657 goto exit;
1658 }
1659 jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
1660 env->DeleteLocalRef(jSink);
1661 jSink = NULL;
1662 if (jStatus != AUDIO_JAVA_SUCCESS) {
1663 goto exit;
1664 }
1665 nPatch.num_sinks++;
1666 }
1667
1668 ALOGV("AudioSystem::createAudioPatch");
1669 status = AudioSystem::createAudioPatch(&nPatch, &handle);
1670 ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle);
1671
1672 jStatus = nativeToJavaStatus(status);
1673 if (jStatus != AUDIO_JAVA_SUCCESS) {
1674 goto exit;
1675 }
1676
1677 if (jPatchHandle == NULL) {
1678 jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1679 handle);
1680 if (jPatchHandle == NULL) {
1681 jStatus = (jint)AUDIO_JAVA_ERROR;
1682 goto exit;
1683 }
1684 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks);
1685 if (jPatch == NULL) {
1686 jStatus = (jint)AUDIO_JAVA_ERROR;
1687 goto exit;
1688 }
1689 env->SetObjectArrayElement(jPatches, 0, jPatch);
1690 } else {
1691 env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle);
1692 }
1693
1694 exit:
1695 if (jPatchHandle != NULL) {
1696 env->DeleteLocalRef(jPatchHandle);
1697 }
1698 if (jPatch != NULL) {
1699 env->DeleteLocalRef(jPatch);
1700 }
1701 if (jSource != NULL) {
1702 env->DeleteLocalRef(jSource);
1703 }
1704 if (jSink != NULL) {
1705 env->DeleteLocalRef(jSink);
1706 }
1707 return jStatus;
1708 }
1709
1710 static jint
android_media_AudioSystem_releaseAudioPatch(JNIEnv * env,jobject clazz,jobject jPatch)1711 android_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz,
1712 jobject jPatch)
1713 {
1714 ALOGV("releaseAudioPatch");
1715 if (jPatch == NULL) {
1716 return (jint)AUDIO_JAVA_BAD_VALUE;
1717 }
1718
1719 audio_patch_handle_t handle = (audio_patch_handle_t)0;
1720 jobject jPatchHandle = NULL;
1721 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1722 return (jint)AUDIO_JAVA_BAD_VALUE;
1723 }
1724 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1725 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1726 env->DeleteLocalRef(jPatchHandle);
1727
1728 ALOGV("AudioSystem::releaseAudioPatch");
1729 status_t status = AudioSystem::releaseAudioPatch(handle);
1730 ALOGV("AudioSystem::releaseAudioPatch() returned %d", status);
1731 jint jStatus = nativeToJavaStatus(status);
1732 return jStatus;
1733 }
1734
1735 static jint
android_media_AudioSystem_listAudioPatches(JNIEnv * env,jobject clazz,jobject jPatches,jintArray jGeneration)1736 android_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz,
1737 jobject jPatches, jintArray jGeneration)
1738 {
1739 ALOGV("listAudioPatches");
1740 if (jPatches == NULL) {
1741 ALOGE("listAudioPatches NULL AudioPatch ArrayList");
1742 return (jint)AUDIO_JAVA_BAD_VALUE;
1743 }
1744 if (!env->IsInstanceOf(jPatches, gArrayListClass)) {
1745 ALOGE("listAudioPatches not an arraylist");
1746 return (jint)AUDIO_JAVA_BAD_VALUE;
1747 }
1748
1749 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1750 return (jint)AUDIO_JAVA_BAD_VALUE;
1751 }
1752
1753 status_t status;
1754 unsigned int generation1;
1755 unsigned int generation;
1756 unsigned int numPatches;
1757 jint *nGeneration;
1758 struct audio_patch *nPatches = NULL;
1759 jobjectArray jSources = NULL;
1760 jobject jSource = NULL;
1761 jobjectArray jSinks = NULL;
1762 jobject jSink = NULL;
1763 jobject jPatch = NULL;
1764 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
1765 jint jStatus;
1766
1767 // get the patch count and all the patches until they both return the same generation
1768 do {
1769 if (attempts-- < 0) {
1770 status = TIMED_OUT;
1771 break;
1772 }
1773
1774 numPatches = 0;
1775 status = AudioSystem::listAudioPatches(&numPatches,
1776 NULL,
1777 &generation1);
1778 if (status != NO_ERROR) {
1779 ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d",
1780 status);
1781 break;
1782 }
1783 if (numPatches == 0) {
1784 jStatus = (jint)AUDIO_JAVA_SUCCESS;
1785 goto exit;
1786 }
1787
1788 nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch));
1789
1790 status = AudioSystem::listAudioPatches(&numPatches,
1791 nPatches,
1792 &generation);
1793 ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d",
1794 numPatches, generation, generation1);
1795
1796 } while (generation1 != generation && status == NO_ERROR);
1797
1798 jStatus = nativeToJavaStatus(status);
1799 if (jStatus != AUDIO_JAVA_SUCCESS) {
1800 goto exit;
1801 }
1802
1803 for (size_t i = 0; i < numPatches; i++) {
1804 jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1805 nPatches[i].id);
1806 if (patchHandle == NULL) {
1807 jStatus = AUDIO_JAVA_ERROR;
1808 goto exit;
1809 }
1810 ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d",
1811 i, nPatches[i].num_sources, nPatches[i].num_sinks);
1812
1813 env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id);
1814
1815 // load sources
1816 jSources = env->NewObjectArray(nPatches[i].num_sources,
1817 gAudioPortConfigClass, NULL);
1818 if (jSources == NULL) {
1819 jStatus = AUDIO_JAVA_ERROR;
1820 goto exit;
1821 }
1822
1823 for (size_t j = 0; j < nPatches[i].num_sources; j++) {
1824 jStatus = convertAudioPortConfigFromNative(env,
1825 NULL,
1826 &jSource,
1827 &nPatches[i].sources[j]);
1828 if (jStatus != AUDIO_JAVA_SUCCESS) {
1829 goto exit;
1830 }
1831 env->SetObjectArrayElement(jSources, j, jSource);
1832 env->DeleteLocalRef(jSource);
1833 jSource = NULL;
1834 ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d",
1835 i, j,
1836 nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1837 nPatches[i].sources[j].id);
1838 }
1839 // load sinks
1840 jSinks = env->NewObjectArray(nPatches[i].num_sinks,
1841 gAudioPortConfigClass, NULL);
1842 if (jSinks == NULL) {
1843 jStatus = AUDIO_JAVA_ERROR;
1844 goto exit;
1845 }
1846
1847 for (size_t j = 0; j < nPatches[i].num_sinks; j++) {
1848 jStatus = convertAudioPortConfigFromNative(env,
1849 NULL,
1850 &jSink,
1851 &nPatches[i].sinks[j]);
1852
1853 if (jStatus != AUDIO_JAVA_SUCCESS) {
1854 goto exit;
1855 }
1856 env->SetObjectArrayElement(jSinks, j, jSink);
1857 env->DeleteLocalRef(jSink);
1858 jSink = NULL;
1859 ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d",
1860 i, j,
1861 nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1862 nPatches[i].sinks[j].id);
1863 }
1864
1865 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor,
1866 patchHandle, jSources, jSinks);
1867 env->DeleteLocalRef(jSources);
1868 jSources = NULL;
1869 env->DeleteLocalRef(jSinks);
1870 jSinks = NULL;
1871 if (jPatch == NULL) {
1872 jStatus = AUDIO_JAVA_ERROR;
1873 goto exit;
1874 }
1875 env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch);
1876 env->DeleteLocalRef(jPatch);
1877 jPatch = NULL;
1878 }
1879
1880 exit:
1881
1882 nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1883 if (nGeneration == NULL) {
1884 jStatus = AUDIO_JAVA_ERROR;
1885 } else {
1886 nGeneration[0] = generation1;
1887 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1888 }
1889
1890 if (jSources != NULL) {
1891 env->DeleteLocalRef(jSources);
1892 }
1893 if (jSource != NULL) {
1894 env->DeleteLocalRef(jSource);
1895 }
1896 if (jSinks != NULL) {
1897 env->DeleteLocalRef(jSinks);
1898 }
1899 if (jSink != NULL) {
1900 env->DeleteLocalRef(jSink);
1901 }
1902 if (jPatch != NULL) {
1903 env->DeleteLocalRef(jPatch);
1904 }
1905 free(nPatches);
1906 return jStatus;
1907 }
1908
1909 static jint
android_media_AudioSystem_setAudioPortConfig(JNIEnv * env,jobject clazz,jobject jAudioPortConfig)1910 android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz,
1911 jobject jAudioPortConfig)
1912 {
1913 ALOGV("setAudioPortConfig");
1914 if (jAudioPortConfig == NULL) {
1915 return AUDIO_JAVA_BAD_VALUE;
1916 }
1917 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1918 return AUDIO_JAVA_BAD_VALUE;
1919 }
1920 struct audio_port_config nAudioPortConfig = {};
1921 jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
1922 if (jStatus != AUDIO_JAVA_SUCCESS) {
1923 return jStatus;
1924 }
1925 status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig);
1926 ALOGV("AudioSystem::setAudioPortConfig() returned %d", status);
1927 jStatus = nativeToJavaStatus(status);
1928 return jStatus;
1929 }
1930
1931 /**
1932 * Returns handle if the audio source is successfully started.
1933 */
1934 static jint
android_media_AudioSystem_startAudioSource(JNIEnv * env,jobject clazz,jobject jAudioPortConfig,jobject jAudioAttributes)1935 android_media_AudioSystem_startAudioSource(JNIEnv *env, jobject clazz,
1936 jobject jAudioPortConfig,
1937 jobject jAudioAttributes)
1938 {
1939 ALOGV("startAudioSource");
1940 if (jAudioPortConfig == NULL || jAudioAttributes == NULL) {
1941 return AUDIO_JAVA_BAD_VALUE;
1942 }
1943 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
1944 return AUDIO_JAVA_BAD_VALUE;
1945 }
1946 struct audio_port_config nAudioPortConfig = {};
1947 jint jStatus = convertAudioPortConfigToNativeWithDevicePort(env,
1948 &nAudioPortConfig, jAudioPortConfig, false);
1949 if (jStatus != AUDIO_JAVA_SUCCESS) {
1950 return jStatus;
1951 }
1952 auto paa = JNIAudioAttributeHelper::makeUnique();
1953 jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAudioAttributes, paa.get());
1954 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
1955 return jStatus;
1956 }
1957 audio_port_handle_t handle;
1958 status_t status = AudioSystem::startAudioSource(&nAudioPortConfig, paa.get(), &handle);
1959 ALOGV("AudioSystem::startAudioSource() returned %d handle %d", status, handle);
1960 if (status != NO_ERROR) {
1961 return nativeToJavaStatus(status);
1962 }
1963 ALOG_ASSERT(handle > 0, "%s: invalid handle reported on successful call", __func__);
1964 return handle;
1965 }
1966
1967 static jint
android_media_AudioSystem_stopAudioSource(JNIEnv * env,jobject clazz,jint handle)1968 android_media_AudioSystem_stopAudioSource(JNIEnv *env, jobject clazz, jint handle)
1969 {
1970 ALOGV("stopAudioSource");
1971 status_t status = AudioSystem::stopAudioSource(
1972 static_cast <audio_port_handle_t>(handle));
1973 ALOGV("AudioSystem::stopAudioSource() returned %d", status);
1974 return nativeToJavaStatus(status);
1975 }
1976
1977 static void
android_media_AudioSystem_eventHandlerSetup(JNIEnv * env,jobject thiz,jobject weak_this)1978 android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this)
1979 {
1980 ALOGV("eventHandlerSetup");
1981
1982 sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this);
1983
1984 if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) {
1985 setJniCallback(env, thiz, callback);
1986 }
1987 }
1988
1989 static void
android_media_AudioSystem_eventHandlerFinalize(JNIEnv * env,jobject thiz)1990 android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz)
1991 {
1992 ALOGV("eventHandlerFinalize");
1993
1994 sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0);
1995
1996 if (callback != 0) {
1997 AudioSystem::removeAudioPortCallback(callback);
1998 }
1999 }
2000
2001 static jint
android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv * env,jobject thiz,jint sessionId)2002 android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
2003 {
2004 return (jint) AudioSystem::getAudioHwSyncForSession((audio_session_t) sessionId);
2005 }
2006
2007 static void
android_media_AudioSystem_registerDynPolicyCallback(JNIEnv * env,jobject thiz)2008 android_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
2009 {
2010 AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
2011 }
2012
2013 static void
android_media_AudioSystem_registerRecordingCallback(JNIEnv * env,jobject thiz)2014 android_media_AudioSystem_registerRecordingCallback(JNIEnv *env, jobject thiz)
2015 {
2016 AudioSystem::setRecordConfigCallback(android_media_AudioSystem_recording_callback);
2017 }
2018
2019 static void
android_media_AudioSystem_registerRoutingCallback(JNIEnv * env,jobject thiz)2020 android_media_AudioSystem_registerRoutingCallback(JNIEnv *env, jobject thiz)
2021 {
2022 AudioSystem::setRoutingCallback(android_media_AudioSystem_routing_callback);
2023 }
2024
2025
convertAudioMixToNative(JNIEnv * env,AudioMix * nAudioMix,const jobject jAudioMix)2026 static jint convertAudioMixToNative(JNIEnv *env,
2027 AudioMix *nAudioMix,
2028 const jobject jAudioMix)
2029 {
2030 nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
2031 nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
2032 nAudioMix->mDeviceType = (audio_devices_t)
2033 env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType);
2034
2035 jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioMix,
2036 gAudioMixFields.mDeviceAddress);
2037 const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
2038 nAudioMix->mDeviceAddress = String8(nDeviceAddress);
2039 env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
2040 env->DeleteLocalRef(jDeviceAddress);
2041
2042 nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
2043
2044 jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
2045 nAudioMix->mFormat = AUDIO_CONFIG_INITIALIZER;
2046 nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
2047 gAudioFormatFields.mSampleRate);
2048 nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
2049 gAudioFormatFields.mChannelMask));
2050 nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
2051 gAudioFormatFields.mEncoding));
2052 env->DeleteLocalRef(jFormat);
2053
2054 jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
2055 jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
2056 nAudioMix->mAllowPrivilegedMediaPlaybackCapture =
2057 env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
2058 nAudioMix->mVoiceCommunicationCaptureAllowed =
2059 env->GetBooleanField(jRule, gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed);
2060 env->DeleteLocalRef(jRule);
2061 jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
2062 gArrayListMethods.toArray);
2063 env->DeleteLocalRef(jRuleCriteria);
2064
2065 jint numCriteria = env->GetArrayLength(jCriteria);
2066 if (numCriteria > MAX_CRITERIA_PER_MIX) {
2067 numCriteria = MAX_CRITERIA_PER_MIX;
2068 }
2069
2070 for (jint i = 0; i < numCriteria; i++) {
2071 AudioMixMatchCriterion nCriterion;
2072
2073 jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
2074
2075 nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
2076
2077 const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
2078 switch (match_rule) {
2079 case RULE_MATCH_UID:
2080 nCriterion.mValue.mUid = env->GetIntField(jCriterion,
2081 gAudioMixMatchCriterionFields.mIntProp);
2082 break;
2083 case RULE_MATCH_USERID:
2084 nCriterion.mValue.mUserId =
2085 env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp);
2086 break;
2087 case RULE_MATCH_ATTRIBUTE_USAGE:
2088 case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
2089 jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
2090
2091 auto paa = JNIAudioAttributeHelper::makeUnique();
2092 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get());
2093 if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
2094 return jStatus;
2095 }
2096 if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
2097 nCriterion.mValue.mUsage = paa->usage;
2098 } else {
2099 nCriterion.mValue.mSource = paa->source;
2100 }
2101 env->DeleteLocalRef(jAttributes);
2102 }
2103 break;
2104 }
2105
2106 nAudioMix->mCriteria.add(nCriterion);
2107 env->DeleteLocalRef(jCriterion);
2108 }
2109
2110 env->DeleteLocalRef(jCriteria);
2111
2112 return (jint)AUDIO_JAVA_SUCCESS;
2113 }
2114
2115 static jint
android_media_AudioSystem_registerPolicyMixes(JNIEnv * env,jobject clazz,jobject jMixesList,jboolean registration)2116 android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
2117 jobject jMixesList, jboolean registration)
2118 {
2119 ALOGV("registerPolicyMixes");
2120
2121 if (jMixesList == NULL) {
2122 return (jint)AUDIO_JAVA_BAD_VALUE;
2123 }
2124 if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
2125 return (jint)AUDIO_JAVA_BAD_VALUE;
2126 }
2127 jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
2128 gArrayListMethods.toArray);
2129 jint numMixes = env->GetArrayLength(jMixes);
2130 if (numMixes > MAX_MIXES_PER_POLICY) {
2131 numMixes = MAX_MIXES_PER_POLICY;
2132 }
2133
2134 status_t status;
2135 jint jStatus;
2136 jobject jAudioMix = NULL;
2137 Vector <AudioMix> mixes;
2138 for (jint i = 0; i < numMixes; i++) {
2139 jAudioMix = env->GetObjectArrayElement(jMixes, i);
2140 if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
2141 jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
2142 goto exit;
2143 }
2144 AudioMix mix;
2145 jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
2146 env->DeleteLocalRef(jAudioMix);
2147 jAudioMix = NULL;
2148 if (jStatus != AUDIO_JAVA_SUCCESS) {
2149 goto exit;
2150 }
2151 mixes.add(mix);
2152 }
2153
2154 ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
2155 status = AudioSystem::registerPolicyMixes(mixes, registration);
2156 ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
2157
2158 jStatus = nativeToJavaStatus(status);
2159 if (jStatus != AUDIO_JAVA_SUCCESS) {
2160 goto exit;
2161 }
2162
2163 exit:
2164 if (jAudioMix != NULL) {
2165 env->DeleteLocalRef(jAudioMix);
2166 }
2167 return jStatus;
2168 }
2169
android_media_AudioSystem_setUidDeviceAffinities(JNIEnv * env,jobject clazz,jint uid,jintArray deviceTypes,jobjectArray deviceAddresses)2170 static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
2171 jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
2172 AudioDeviceTypeAddrVector deviceVector;
2173 jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector);
2174 if (results != NO_ERROR) {
2175 return results;
2176 }
2177 status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector);
2178 return (jint) nativeToJavaStatus(status);
2179 }
2180
android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv * env,jobject clazz,jint uid)2181 static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz,
2182 jint uid) {
2183 status_t status = AudioSystem::removeUidDeviceAffinities((uid_t) uid);
2184 return (jint) nativeToJavaStatus(status);
2185 }
2186
android_media_AudioSystem_setUserIdDeviceAffinities(JNIEnv * env,jobject clazz,jint userId,jintArray deviceTypes,jobjectArray deviceAddresses)2187 static jint android_media_AudioSystem_setUserIdDeviceAffinities(JNIEnv *env, jobject clazz,
2188 jint userId, jintArray deviceTypes,
2189 jobjectArray deviceAddresses) {
2190 AudioDeviceTypeAddrVector deviceVector;
2191 jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector);
2192 if (results != NO_ERROR) {
2193 return results;
2194 }
2195 status_t status = AudioSystem::setUserIdDeviceAffinities((int)userId, deviceVector);
2196 return (jint)nativeToJavaStatus(status);
2197 }
2198
android_media_AudioSystem_removeUserIdDeviceAffinities(JNIEnv * env,jobject clazz,jint userId)2199 static jint android_media_AudioSystem_removeUserIdDeviceAffinities(JNIEnv *env, jobject clazz,
2200 jint userId) {
2201 status_t status = AudioSystem::removeUserIdDeviceAffinities((int)userId);
2202 return (jint)nativeToJavaStatus(status);
2203 }
2204
2205 static jint
android_media_AudioSystem_systemReady(JNIEnv * env,jobject thiz)2206 android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz)
2207 {
2208 return nativeToJavaStatus(AudioSystem::systemReady());
2209 }
2210
2211 static jfloat
android_media_AudioSystem_getStreamVolumeDB(JNIEnv * env,jobject thiz,jint stream,jint index,jint device)2212 android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
2213 jint stream, jint index, jint device)
2214 {
2215 return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
2216 (int)index,
2217 (audio_devices_t)device);
2218 }
2219
android_media_AudioSystem_getOffloadSupport(JNIEnv * env,jobject thiz,jint encoding,jint sampleRate,jint channelMask,jint channelIndexMask,jint streamType)2220 static jint android_media_AudioSystem_getOffloadSupport(JNIEnv *env, jobject thiz, jint encoding,
2221 jint sampleRate, jint channelMask,
2222 jint channelIndexMask, jint streamType) {
2223 audio_offload_info_t format = AUDIO_INFO_INITIALIZER;
2224 format.format = (audio_format_t) audioFormatToNative(encoding);
2225 format.sample_rate = (uint32_t) sampleRate;
2226 format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask);
2227 format.stream_type = (audio_stream_type_t) streamType;
2228 format.has_video = false;
2229 format.is_streaming = false;
2230 // offload duration unknown at this point:
2231 // client side code cannot access "audio.offload.min.duration.secs" property to make a query
2232 // agnostic of duration, so using acceptable estimate of 2mn
2233 format.duration_us = 120 * 1000000;
2234 return AudioSystem::getOffloadSupport(format);
2235 }
2236
2237 static jint
android_media_AudioSystem_getMicrophones(JNIEnv * env,jobject thiz,jobject jMicrophonesInfo)2238 android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMicrophonesInfo)
2239 {
2240 ALOGV("getMicrophones");
2241
2242 if (jMicrophonesInfo == NULL) {
2243 ALOGE("jMicrophonesInfo NULL MicrophoneInfo ArrayList");
2244 return (jint)AUDIO_JAVA_BAD_VALUE;
2245 }
2246 if (!env->IsInstanceOf(jMicrophonesInfo, gArrayListClass)) {
2247 ALOGE("getMicrophones not an arraylist");
2248 return (jint)AUDIO_JAVA_BAD_VALUE;
2249 }
2250
2251 jint jStatus;
2252 std::vector<media::MicrophoneInfo> microphones;
2253 status_t status = AudioSystem::getMicrophones(µphones);
2254 if (status != NO_ERROR) {
2255 ALOGE("AudioSystem::getMicrophones error %d", status);
2256 jStatus = nativeToJavaStatus(status);
2257 return jStatus;
2258 }
2259 if (microphones.size() == 0) {
2260 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2261 return jStatus;
2262 }
2263 for (size_t i = 0; i < microphones.size(); i++) {
2264 jobject jMicrophoneInfo;
2265 jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, µphones[i]);
2266 if (jStatus != AUDIO_JAVA_SUCCESS) {
2267 return jStatus;
2268 }
2269 env->CallBooleanMethod(jMicrophonesInfo, gArrayListMethods.add, jMicrophoneInfo);
2270 env->DeleteLocalRef(jMicrophoneInfo);
2271 }
2272
2273 return jStatus;
2274 }
2275
2276 static jint
android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(JNIEnv * env,jobject thiz,jobject jEncodingFormatList)2277 android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
2278 JNIEnv *env, jobject thiz, jobject jEncodingFormatList)
2279 {
2280 ALOGV("%s", __FUNCTION__);
2281 jint jStatus = AUDIO_JAVA_SUCCESS;
2282 if (!env->IsInstanceOf(jEncodingFormatList, gArrayListClass)) {
2283 ALOGE("%s: jEncodingFormatList not an ArrayList", __FUNCTION__);
2284 return (jint)AUDIO_JAVA_BAD_VALUE;
2285 }
2286 std::vector<audio_format_t> encodingFormats;
2287 status_t status = AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
2288 &encodingFormats);
2289 if (status != NO_ERROR) {
2290 ALOGE("%s: error %d", __FUNCTION__, status);
2291 jStatus = nativeToJavaStatus(status);
2292 return jStatus;
2293 }
2294
2295 for (size_t i = 0; i < encodingFormats.size(); i++) {
2296 ScopedLocalRef<jobject> jEncodingFormat(
2297 env, env->NewObject(gIntegerClass, gIntegerCstor, encodingFormats[i]));
2298 env->CallBooleanMethod(jEncodingFormatList, gArrayListMethods.add,
2299 jEncodingFormat.get());
2300 }
2301 return jStatus;
2302 }
2303
android_media_AudioSystem_getSurroundFormats(JNIEnv * env,jobject thiz,jobject jSurroundFormats)2304 static jint android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
2305 jobject jSurroundFormats) {
2306 ALOGV("getSurroundFormats");
2307
2308 if (jSurroundFormats == nullptr) {
2309 ALOGE("jSurroundFormats is NULL");
2310 return (jint)AUDIO_JAVA_BAD_VALUE;
2311 }
2312 if (!env->IsInstanceOf(jSurroundFormats, gMapClass)) {
2313 ALOGE("getSurroundFormats not a map");
2314 return (jint)AUDIO_JAVA_BAD_VALUE;
2315 }
2316
2317 jint jStatus;
2318 unsigned int numSurroundFormats = 0;
2319 audio_format_t *surroundFormats = nullptr;
2320 bool *surroundFormatsEnabled = nullptr;
2321 status_t status = AudioSystem::getSurroundFormats(&numSurroundFormats, surroundFormats,
2322 surroundFormatsEnabled);
2323 if (status != NO_ERROR) {
2324 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2325 jStatus = nativeToJavaStatus(status);
2326 goto exit;
2327 }
2328 if (numSurroundFormats == 0) {
2329 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2330 goto exit;
2331 }
2332 surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
2333 surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
2334 status = AudioSystem::getSurroundFormats(&numSurroundFormats, surroundFormats,
2335 surroundFormatsEnabled);
2336 jStatus = nativeToJavaStatus(status);
2337 if (status != NO_ERROR) {
2338 ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
2339 goto exit;
2340 }
2341 for (size_t i = 0; i < numSurroundFormats; i++) {
2342 jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
2343 audioFormatFromNative(surroundFormats[i]));
2344 jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
2345 env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
2346 env->DeleteLocalRef(surroundFormat);
2347 env->DeleteLocalRef(enabled);
2348 }
2349
2350 exit:
2351 free(surroundFormats);
2352 free(surroundFormatsEnabled);
2353 return jStatus;
2354 }
2355
android_media_AudioSystem_getReportedSurroundFormats(JNIEnv * env,jobject thiz,jobject jSurroundFormats)2356 static jint android_media_AudioSystem_getReportedSurroundFormats(JNIEnv *env, jobject thiz,
2357 jobject jSurroundFormats) {
2358 ALOGV("getReportedSurroundFormats");
2359
2360 if (jSurroundFormats == nullptr) {
2361 ALOGE("jSurroundFormats is NULL");
2362 return (jint)AUDIO_JAVA_BAD_VALUE;
2363 }
2364 if (!env->IsInstanceOf(jSurroundFormats, gArrayListClass)) {
2365 ALOGE("jSurroundFormats not an arraylist");
2366 return (jint)AUDIO_JAVA_BAD_VALUE;
2367 }
2368 jint jStatus;
2369 unsigned int numSurroundFormats = 0;
2370 audio_format_t *surroundFormats = nullptr;
2371 status_t status = AudioSystem::getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
2372 if (status != NO_ERROR) {
2373 ALOGE_IF(status != NO_ERROR, "AudioSystem::getReportedSurroundFormats error %d", status);
2374 jStatus = nativeToJavaStatus(status);
2375 goto exit;
2376 }
2377 if (numSurroundFormats == 0) {
2378 jStatus = (jint)AUDIO_JAVA_SUCCESS;
2379 goto exit;
2380 }
2381 surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
2382 status = AudioSystem::getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
2383 jStatus = nativeToJavaStatus(status);
2384 if (status != NO_ERROR) {
2385 ALOGE_IF(status != NO_ERROR, "AudioSystem::getReportedSurroundFormats error %d", status);
2386 goto exit;
2387 }
2388 for (size_t i = 0; i < numSurroundFormats; i++) {
2389 jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
2390 audioFormatFromNative(surroundFormats[i]));
2391 env->CallObjectMethod(jSurroundFormats, gArrayListMethods.add, surroundFormat);
2392 env->DeleteLocalRef(surroundFormat);
2393 }
2394
2395 exit:
2396 free(surroundFormats);
2397 return jStatus;
2398 }
2399
2400 static jint
android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv * env,jobject thiz,jint audioFormat,jboolean enabled)2401 android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
2402 jint audioFormat, jboolean enabled)
2403 {
2404 status_t status = AudioSystem::setSurroundFormatEnabled(audioFormatToNative(audioFormat),
2405 (bool)enabled);
2406 if (status != NO_ERROR) {
2407 ALOGE_IF(status != NO_ERROR, "AudioSystem::setSurroundFormatEnabled error %d", status);
2408 }
2409 return (jint)nativeToJavaStatus(status);
2410 }
2411
android_media_AudioSystem_getMaxChannelCount(JNIEnv * env,jobject thiz)2412 static jint android_media_AudioSystem_getMaxChannelCount(JNIEnv *env, jobject thiz) {
2413 return FCC_LIMIT;
2414 }
2415
android_media_AudioSystem_getMaxSampleRate(JNIEnv * env,jobject thiz)2416 static jint android_media_AudioSystem_getMaxSampleRate(JNIEnv *env, jobject thiz) {
2417 // see frameworks/av/services/audiopolicy/common/include/policy.h
2418 return 192000; // SAMPLE_RATE_HZ_MAX (for API)
2419 }
2420
android_media_AudioSystem_getMinSampleRate(JNIEnv * env,jobject thiz)2421 static jint android_media_AudioSystem_getMinSampleRate(JNIEnv *env, jobject thiz) {
2422 return 4000; // SAMPLE_RATE_HZ_MIN (for API)
2423 }
2424
2425 static jint
android_media_AudioSystem_setAssistantUid(JNIEnv * env,jobject thiz,jint uid)2426 android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
2427 {
2428 status_t status = AudioSystem::setAssistantUid(uid);
2429 return (jint)nativeToJavaStatus(status);
2430 }
2431
android_media_AudioSystem_setHotwordDetectionServiceUid(JNIEnv * env,jobject thiz,jint uid)2432 static jint android_media_AudioSystem_setHotwordDetectionServiceUid(JNIEnv *env, jobject thiz,
2433 jint uid) {
2434 status_t status = AudioSystem::setHotwordDetectionServiceUid(uid);
2435 return (jint)nativeToJavaStatus(status);
2436 }
2437
2438 static jint
android_media_AudioSystem_setA11yServicesUids(JNIEnv * env,jobject thiz,jintArray uids)2439 android_media_AudioSystem_setA11yServicesUids(JNIEnv *env, jobject thiz, jintArray uids) {
2440 std::vector<uid_t> nativeUidsVector;
2441
2442 if (uids != nullptr) {
2443 jsize len = env->GetArrayLength(uids);
2444
2445 if (len > 0) {
2446 int *nativeUids = nullptr;
2447 nativeUids = env->GetIntArrayElements(uids, 0);
2448 if (nativeUids != nullptr) {
2449 for (size_t i = 0; i < len; i++) {
2450 nativeUidsVector.push_back(nativeUids[i]);
2451 }
2452 env->ReleaseIntArrayElements(uids, nativeUids, 0);
2453 }
2454 }
2455 }
2456 status_t status = AudioSystem::setA11yServicesUids(nativeUidsVector);
2457 return (jint)nativeToJavaStatus(status);
2458 }
2459
android_media_AudioSystem_setCurrentImeUid(JNIEnv * env,jobject thiz,jint uid)2460 static jint android_media_AudioSystem_setCurrentImeUid(JNIEnv *env, jobject thiz, jint uid) {
2461 status_t status = AudioSystem::setCurrentImeUid(uid);
2462 return (jint)nativeToJavaStatus(status);
2463 }
2464
2465 static jboolean
android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv * env,jobject thiz)2466 android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
2467 {
2468 return AudioSystem::isHapticPlaybackSupported();
2469 }
2470
android_media_AudioSystem_setSupportedSystemUsages(JNIEnv * env,jobject thiz,jintArray systemUsages)2471 static jint android_media_AudioSystem_setSupportedSystemUsages(JNIEnv *env, jobject thiz,
2472 jintArray systemUsages) {
2473 std::vector<audio_usage_t> nativeSystemUsagesVector;
2474
2475 if (systemUsages == nullptr) {
2476 return (jint) AUDIO_JAVA_BAD_VALUE;
2477 }
2478
2479 int *nativeSystemUsages = nullptr;
2480 nativeSystemUsages = env->GetIntArrayElements(systemUsages, 0);
2481
2482 if (nativeSystemUsages != nullptr) {
2483 jsize len = env->GetArrayLength(systemUsages);
2484 for (size_t i = 0; i < len; i++) {
2485 audio_usage_t nativeAudioUsage =
2486 static_cast<audio_usage_t>(nativeSystemUsages[i]);
2487 nativeSystemUsagesVector.push_back(nativeAudioUsage);
2488 }
2489 env->ReleaseIntArrayElements(systemUsages, nativeSystemUsages, 0);
2490 }
2491
2492 status_t status = AudioSystem::setSupportedSystemUsages(nativeSystemUsagesVector);
2493 return (jint)nativeToJavaStatus(status);
2494 }
2495
2496 static jint
android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv * env,jobject thiz,jint uid,jint flags)2497 android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) {
2498 return AudioSystem::setAllowedCapturePolicy(uid, static_cast<audio_flags_mask_t>(flags));
2499 }
2500
2501 static jint
android_media_AudioSystem_setRttEnabled(JNIEnv * env,jobject thiz,jboolean enabled)2502 android_media_AudioSystem_setRttEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
2503 {
2504 return (jint) check_AudioSystem_Command(AudioSystem::setRttEnabled(enabled));
2505 }
2506
2507 static jint
android_media_AudioSystem_setAudioHalPids(JNIEnv * env,jobject clazz,jintArray jPids)2508 android_media_AudioSystem_setAudioHalPids(JNIEnv *env, jobject clazz, jintArray jPids)
2509 {
2510 if (jPids == NULL) {
2511 return (jint) AUDIO_JAVA_BAD_VALUE;
2512 }
2513 pid_t *nPidsArray = (pid_t *) env->GetIntArrayElements(jPids, NULL);
2514 std::vector<pid_t> nPids(nPidsArray, nPidsArray + env->GetArrayLength(jPids));
2515 status_t status = AudioSystem::setAudioHalPids(nPids);
2516 env->ReleaseIntArrayElements(jPids, nPidsArray, 0);
2517 jint jStatus = nativeToJavaStatus(status);
2518 return jStatus;
2519 }
2520
2521 static jboolean
android_media_AudioSystem_isCallScreeningModeSupported(JNIEnv * env,jobject thiz)2522 android_media_AudioSystem_isCallScreeningModeSupported(JNIEnv *env, jobject thiz)
2523 {
2524 return AudioSystem::isCallScreenModeSupported();
2525 }
2526
android_media_AudioSystem_setDevicesRoleForStrategy(JNIEnv * env,jobject thiz,jint strategy,jint role,jintArray jDeviceTypes,jobjectArray jDeviceAddresses)2527 static jint android_media_AudioSystem_setDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
2528 jint strategy, jint role,
2529 jintArray jDeviceTypes,
2530 jobjectArray jDeviceAddresses) {
2531 AudioDeviceTypeAddrVector nDevices;
2532 jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
2533 if (results != NO_ERROR) {
2534 return results;
2535 }
2536 int status = check_AudioSystem_Command(
2537 AudioSystem::setDevicesRoleForStrategy((product_strategy_t)strategy,
2538 (device_role_t)role, nDevices));
2539 return (jint) status;
2540 }
2541
android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv * env,jobject thiz,jint strategy,jint role)2542 static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
2543 jint strategy, jint role) {
2544 return (jint)
2545 check_AudioSystem_Command(AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)
2546 strategy,
2547 (device_role_t)
2548 role),
2549 {NAME_NOT_FOUND});
2550 }
2551
android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv * env,jobject thiz,jint strategy,jint role,jobject jDevices)2552 static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz,
2553 jint strategy, jint role,
2554 jobject jDevices) {
2555 AudioDeviceTypeAddrVector nDevices;
2556 status_t status = check_AudioSystem_Command(
2557 AudioSystem::getDevicesForRoleAndStrategy((product_strategy_t)strategy,
2558 (device_role_t)role, nDevices));
2559 if (status != NO_ERROR) {
2560 return (jint) status;
2561 }
2562 for (const auto &device : nDevices) {
2563 jobject jAudioDeviceAttributes = NULL;
2564 jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device);
2565 if (jStatus != AUDIO_JAVA_SUCCESS) {
2566 return jStatus;
2567 }
2568 env->CallBooleanMethod(jDevices, gListMethods.add, jAudioDeviceAttributes);
2569 env->DeleteLocalRef(jAudioDeviceAttributes);
2570 }
2571 return AUDIO_JAVA_SUCCESS;
2572 }
2573
android_media_AudioSystem_setDevicesRoleForCapturePreset(JNIEnv * env,jobject thiz,jint capturePreset,jint role,jintArray jDeviceTypes,jobjectArray jDeviceAddresses)2574 static jint android_media_AudioSystem_setDevicesRoleForCapturePreset(
2575 JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
2576 jobjectArray jDeviceAddresses) {
2577 AudioDeviceTypeAddrVector nDevices;
2578 jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
2579 if (results != NO_ERROR) {
2580 return results;
2581 }
2582 int status = check_AudioSystem_Command(
2583 AudioSystem::setDevicesRoleForCapturePreset((audio_source_t)capturePreset,
2584 (device_role_t)role, nDevices));
2585 return (jint)status;
2586 }
2587
android_media_AudioSystem_addDevicesRoleForCapturePreset(JNIEnv * env,jobject thiz,jint capturePreset,jint role,jintArray jDeviceTypes,jobjectArray jDeviceAddresses)2588 static jint android_media_AudioSystem_addDevicesRoleForCapturePreset(
2589 JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
2590 jobjectArray jDeviceAddresses) {
2591 AudioDeviceTypeAddrVector nDevices;
2592 jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
2593 if (results != NO_ERROR) {
2594 return results;
2595 }
2596 int status = check_AudioSystem_Command(
2597 AudioSystem::addDevicesRoleForCapturePreset((audio_source_t)capturePreset,
2598 (device_role_t)role, nDevices));
2599 return (jint)status;
2600 }
2601
android_media_AudioSystem_removeDevicesRoleForCapturePreset(JNIEnv * env,jobject thiz,jint capturePreset,jint role,jintArray jDeviceTypes,jobjectArray jDeviceAddresses)2602 static jint android_media_AudioSystem_removeDevicesRoleForCapturePreset(
2603 JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
2604 jobjectArray jDeviceAddresses) {
2605 AudioDeviceTypeAddrVector nDevices;
2606 jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
2607 if (results != NO_ERROR) {
2608 return results;
2609 }
2610 int status = check_AudioSystem_Command(
2611 AudioSystem::removeDevicesRoleForCapturePreset((audio_source_t)capturePreset,
2612 (device_role_t)role, nDevices));
2613 return (jint)status;
2614 }
2615
android_media_AudioSystem_clearDevicesRoleForCapturePreset(JNIEnv * env,jobject thiz,jint capturePreset,jint role)2616 static jint android_media_AudioSystem_clearDevicesRoleForCapturePreset(JNIEnv *env, jobject thiz,
2617 jint capturePreset,
2618 jint role) {
2619 return (jint)check_AudioSystem_Command(
2620 AudioSystem::clearDevicesRoleForCapturePreset((audio_source_t)capturePreset,
2621 (device_role_t)role));
2622 }
2623
android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv * env,jobject thiz,jint capturePreset,jint role,jobject jDevices)2624 static jint android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv *env, jobject thiz,
2625 jint capturePreset,
2626 jint role,
2627 jobject jDevices) {
2628 AudioDeviceTypeAddrVector nDevices;
2629 status_t status = check_AudioSystem_Command(
2630 AudioSystem::getDevicesForRoleAndCapturePreset((audio_source_t)capturePreset,
2631 (device_role_t)role, nDevices));
2632 if (status != NO_ERROR) {
2633 return (jint)status;
2634 }
2635 for (const auto &device : nDevices) {
2636 jobject jAudioDeviceAttributes = NULL;
2637 jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device);
2638 if (jStatus != AUDIO_JAVA_SUCCESS) {
2639 return jStatus;
2640 }
2641 env->CallBooleanMethod(jDevices, gListMethods.add, jAudioDeviceAttributes);
2642 env->DeleteLocalRef(jAudioDeviceAttributes);
2643 }
2644 return AUDIO_JAVA_SUCCESS;
2645 }
2646
2647 static jint
android_media_AudioSystem_getDevicesForAttributes(JNIEnv * env,jobject thiz,jobject jaa,jobjectArray jDeviceArray)2648 android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz,
2649 jobject jaa, jobjectArray jDeviceArray)
2650 {
2651 const jsize maxResultSize = env->GetArrayLength(jDeviceArray);
2652 // the JNI is always expected to provide us with an array capable of holding enough
2653 // devices i.e. the most we ever route a track to. This is preferred over receiving an ArrayList
2654 // with reverse JNI to make the array grow as need as this would be less efficient, and some
2655 // components call this method often
2656 if (jDeviceArray == nullptr || maxResultSize == 0) {
2657 ALOGE("%s invalid array to store AudioDeviceAttributes", __FUNCTION__);
2658 return (jint)AUDIO_JAVA_BAD_VALUE;
2659 }
2660
2661 JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
2662 jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
2663 if (jStatus != (jint) AUDIO_JAVA_SUCCESS) {
2664 return jStatus;
2665 }
2666
2667 AudioDeviceTypeAddrVector devices;
2668 jStatus = check_AudioSystem_Command(
2669 AudioSystem::getDevicesForAttributes(*(paa.get()), &devices));
2670 if (jStatus != NO_ERROR) {
2671 return jStatus;
2672 }
2673
2674 if (devices.size() > maxResultSize) {
2675 return AUDIO_JAVA_INVALID_OPERATION;
2676 }
2677 size_t index = 0;
2678 jobject jAudioDeviceAttributes = NULL;
2679 for (const auto& device : devices) {
2680 jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device);
2681 if (jStatus != AUDIO_JAVA_SUCCESS) {
2682 return jStatus;
2683 }
2684 env->SetObjectArrayElement(jDeviceArray, index++, jAudioDeviceAttributes);
2685 }
2686 return jStatus;
2687 }
2688
android_media_AudioSystem_setVibratorInfos(JNIEnv * env,jobject thiz,jobject jVibrators)2689 static jint android_media_AudioSystem_setVibratorInfos(JNIEnv *env, jobject thiz,
2690 jobject jVibrators) {
2691 if (!env->IsInstanceOf(jVibrators, gListClass)) {
2692 return (jint)AUDIO_JAVA_BAD_VALUE;
2693 }
2694 const jint size = env->CallIntMethod(jVibrators, gListMethods.size);
2695 std::vector<media::AudioVibratorInfo> vibratorInfos;
2696 for (jint i = 0; i < size; ++i) {
2697 ScopedLocalRef<jobject> jVibrator(env,
2698 env->CallObjectMethod(jVibrators, gListMethods.get, i));
2699 if (!env->IsInstanceOf(jVibrator.get(), gVibratorClass)) {
2700 return (jint)AUDIO_JAVA_BAD_VALUE;
2701 }
2702 media::AudioVibratorInfo vibratorInfo;
2703 vibratorInfo.id = env->CallIntMethod(jVibrator.get(), gVibratorMethods.getId);
2704 vibratorInfo.resonantFrequency =
2705 env->CallFloatMethod(jVibrator.get(), gVibratorMethods.getResonantFrequency);
2706 vibratorInfo.qFactor = env->CallFloatMethod(jVibrator.get(), gVibratorMethods.getQFactor);
2707 vibratorInfos.push_back(vibratorInfo);
2708 }
2709 return (jint)check_AudioSystem_Command(AudioSystem::setVibratorInfos(vibratorInfos));
2710 }
2711
2712 // ----------------------------------------------------------------------------
2713
2714 static const JNINativeMethod gMethods[] =
2715 {{"setParameters", "(Ljava/lang/String;)I",
2716 (void *)android_media_AudioSystem_setParameters},
2717 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;",
2718 (void *)android_media_AudioSystem_getParameters},
2719 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
2720 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
2721 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
2722 {"isStreamActiveRemotely", "(II)Z",
2723 (void *)android_media_AudioSystem_isStreamActiveRemotely},
2724 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
2725 {"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
2726 {"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
2727 {"newAudioRecorderId", "()I", (void *)android_media_AudioSystem_newAudioRecorderId},
2728 {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I",
2729 (void *)android_media_AudioSystem_setDeviceConnectionState},
2730 {"getDeviceConnectionState", "(ILjava/lang/String;)I",
2731 (void *)android_media_AudioSystem_getDeviceConnectionState},
2732 {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I",
2733 (void *)android_media_AudioSystem_handleDeviceConfigChange},
2734 {"setPhoneState", "(II)I", (void *)android_media_AudioSystem_setPhoneState},
2735 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
2736 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
2737 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
2738 {"setStreamVolumeIndex", "(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
2739 {"getStreamVolumeIndex", "(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
2740 {"setVolumeIndexForAttributes", "(Landroid/media/AudioAttributes;II)I",
2741 (void *)android_media_AudioSystem_setVolumeIndexForAttributes},
2742 {"getVolumeIndexForAttributes", "(Landroid/media/AudioAttributes;I)I",
2743 (void *)android_media_AudioSystem_getVolumeIndexForAttributes},
2744 {"getMinVolumeIndexForAttributes", "(Landroid/media/AudioAttributes;)I",
2745 (void *)android_media_AudioSystem_getMinVolumeIndexForAttributes},
2746 {"getMaxVolumeIndexForAttributes", "(Landroid/media/AudioAttributes;)I",
2747 (void *)android_media_AudioSystem_getMaxVolumeIndexForAttributes},
2748 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
2749 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
2750 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
2751 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
2752 {"setMasterMono", "(Z)I", (void *)android_media_AudioSystem_setMasterMono},
2753 {"getMasterMono", "()Z", (void *)android_media_AudioSystem_getMasterMono},
2754 {"setMasterBalance", "(F)I", (void *)android_media_AudioSystem_setMasterBalance},
2755 {"getMasterBalance", "()F", (void *)android_media_AudioSystem_getMasterBalance},
2756 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
2757 {"getPrimaryOutputSamplingRate", "()I",
2758 (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
2759 {"getPrimaryOutputFrameCount", "()I",
2760 (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
2761 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency},
2762 {"setLowRamDevice", "(ZJ)I", (void *)android_media_AudioSystem_setLowRamDevice},
2763 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger},
2764 {"setAudioFlingerBinder", "(Landroid/os/IBinder;)V",
2765 (void *)android_media_AudioSystem_setAudioFlingerBinder},
2766 {"listAudioPorts", "(Ljava/util/ArrayList;[I)I",
2767 (void *)android_media_AudioSystem_listAudioPorts},
2768 {"createAudioPatch",
2769 "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/"
2770 "AudioPortConfig;)I",
2771 (void *)android_media_AudioSystem_createAudioPatch},
2772 {"releaseAudioPatch", "(Landroid/media/AudioPatch;)I",
2773 (void *)android_media_AudioSystem_releaseAudioPatch},
2774 {"listAudioPatches", "(Ljava/util/ArrayList;[I)I",
2775 (void *)android_media_AudioSystem_listAudioPatches},
2776 {"setAudioPortConfig", "(Landroid/media/AudioPortConfig;)I",
2777 (void *)android_media_AudioSystem_setAudioPortConfig},
2778 {"startAudioSource", "(Landroid/media/AudioPortConfig;Landroid/media/AudioAttributes;)I",
2779 (void *)android_media_AudioSystem_startAudioSource},
2780 {"stopAudioSource", "(I)I", (void *)android_media_AudioSystem_stopAudioSource},
2781 {"getAudioHwSyncForSession", "(I)I",
2782 (void *)android_media_AudioSystem_getAudioHwSyncForSession},
2783 {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I",
2784 (void *)android_media_AudioSystem_registerPolicyMixes},
2785 {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I",
2786 (void *)android_media_AudioSystem_setUidDeviceAffinities},
2787 {"removeUidDeviceAffinities", "(I)I",
2788 (void *)android_media_AudioSystem_removeUidDeviceAffinities},
2789 {"native_register_dynamic_policy_callback", "()V",
2790 (void *)android_media_AudioSystem_registerDynPolicyCallback},
2791 {"native_register_recording_callback", "()V",
2792 (void *)android_media_AudioSystem_registerRecordingCallback},
2793 {"native_register_routing_callback", "()V",
2794 (void *)android_media_AudioSystem_registerRoutingCallback},
2795 {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
2796 {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
2797 {"native_get_offload_support", "(IIIII)I",
2798 (void *)android_media_AudioSystem_getOffloadSupport},
2799 {"getMicrophones", "(Ljava/util/ArrayList;)I",
2800 (void *)android_media_AudioSystem_getMicrophones},
2801 {"getSurroundFormats", "(Ljava/util/Map;)I",
2802 (void *)android_media_AudioSystem_getSurroundFormats},
2803 {"getReportedSurroundFormats", "(Ljava/util/ArrayList;)I",
2804 (void *)android_media_AudioSystem_getReportedSurroundFormats},
2805 {"setSurroundFormatEnabled", "(IZ)I",
2806 (void *)android_media_AudioSystem_setSurroundFormatEnabled},
2807 {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
2808 {"setHotwordDetectionServiceUid", "(I)I",
2809 (void *)android_media_AudioSystem_setHotwordDetectionServiceUid},
2810 {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
2811 {"isHapticPlaybackSupported", "()Z",
2812 (void *)android_media_AudioSystem_isHapticPlaybackSupported},
2813 {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
2814 (void *)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
2815 {"setSupportedSystemUsages", "([I)I",
2816 (void *)android_media_AudioSystem_setSupportedSystemUsages},
2817 {"setAllowedCapturePolicy", "(II)I",
2818 (void *)android_media_AudioSystem_setAllowedCapturePolicy},
2819 {"setRttEnabled", "(Z)I", (void *)android_media_AudioSystem_setRttEnabled},
2820 {"setAudioHalPids", "([I)I", (void *)android_media_AudioSystem_setAudioHalPids},
2821 {"isCallScreeningModeSupported", "()Z",
2822 (void *)android_media_AudioSystem_isCallScreeningModeSupported},
2823 {"setDevicesRoleForStrategy", "(II[I[Ljava/lang/String;)I",
2824 (void *)android_media_AudioSystem_setDevicesRoleForStrategy},
2825 {"removeDevicesRoleForStrategy", "(II)I",
2826 (void *)android_media_AudioSystem_removeDevicesRoleForStrategy},
2827 {"getDevicesForRoleAndStrategy", "(IILjava/util/List;)I",
2828 (void *)android_media_AudioSystem_getDevicesForRoleAndStrategy},
2829 {"setDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
2830 (void *)android_media_AudioSystem_setDevicesRoleForCapturePreset},
2831 {"addDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
2832 (void *)android_media_AudioSystem_addDevicesRoleForCapturePreset},
2833 {"removeDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
2834 (void *)android_media_AudioSystem_removeDevicesRoleForCapturePreset},
2835 {"clearDevicesRoleForCapturePreset", "(II)I",
2836 (void *)android_media_AudioSystem_clearDevicesRoleForCapturePreset},
2837 {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I",
2838 (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset},
2839 {"getDevicesForAttributes",
2840 "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I",
2841 (void *)android_media_AudioSystem_getDevicesForAttributes},
2842 {"setUserIdDeviceAffinities", "(I[I[Ljava/lang/String;)I",
2843 (void *)android_media_AudioSystem_setUserIdDeviceAffinities},
2844 {"removeUserIdDeviceAffinities", "(I)I",
2845 (void *)android_media_AudioSystem_removeUserIdDeviceAffinities},
2846 {"setCurrentImeUid", "(I)I", (void *)android_media_AudioSystem_setCurrentImeUid},
2847 {"setVibratorInfos", "(Ljava/util/List;)I",
2848 (void *)android_media_AudioSystem_setVibratorInfos}};
2849
2850 static const JNINativeMethod gEventHandlerMethods[] = {
2851 {"native_setup",
2852 "(Ljava/lang/Object;)V",
2853 (void *)android_media_AudioSystem_eventHandlerSetup},
2854 {"native_finalize",
2855 "()V",
2856 (void *)android_media_AudioSystem_eventHandlerFinalize},
2857 };
2858
2859 static const JNINativeMethod gFrameworkCapabilities[] = {
2860 {"native_getMaxChannelCount", "()I", (void *)android_media_AudioSystem_getMaxChannelCount},
2861 {"native_getMaxSampleRate", "()I", (void *)android_media_AudioSystem_getMaxSampleRate},
2862 {"native_getMinSampleRate", "()I", (void *)android_media_AudioSystem_getMinSampleRate},
2863 };
2864
register_android_media_AudioSystem(JNIEnv * env)2865 int register_android_media_AudioSystem(JNIEnv *env)
2866 {
2867 // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
2868 // as the calls are performed in the static initializer of AudioSystem.
2869 RegisterMethodsOrDie(env, kClassPathName, gFrameworkCapabilities,
2870 NELEM(gFrameworkCapabilities));
2871
2872 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
2873 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
2874 gArrayListMethods.cstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
2875 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
2876 gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
2877
2878 jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
2879 gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
2880 gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
2881
2882 jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2883 gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
2884 gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
2885
2886 jclass mapClass = FindClassOrDie(env, "java/util/Map");
2887 gMapClass = MakeGlobalRefOrDie(env, mapClass);
2888 gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
2889
2890 jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
2891 gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
2892 gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
2893 gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I");
2894
2895 jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
2896 gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
2897 gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
2898 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
2899 gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
2900 "Landroid/media/AudioHandle;");
2901 gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
2902 gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains",
2903 "[Landroid/media/AudioGain;");
2904 gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig",
2905 "Landroid/media/AudioPortConfig;");
2906
2907 jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig");
2908 gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass);
2909 gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>",
2910 "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V");
2911 gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort",
2912 "Landroid/media/AudioPort;");
2913 gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass,
2914 "mSamplingRate", "I");
2915 gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass,
2916 "mChannelMask", "I");
2917 gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I");
2918 gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain",
2919 "Landroid/media/AudioGainConfig;");
2920 gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask",
2921 "I");
2922
2923 jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig");
2924 gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass);
2925 gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>",
2926 "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V");
2927
2928 jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig");
2929 gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass);
2930 gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>",
2931 "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V");
2932
2933 jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
2934 gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
2935 gAudioDevicePortCstor =
2936 GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
2937 "(Landroid/media/AudioHandle;Ljava/lang/String;Ljava/util/List;"
2938 "[Landroid/media/AudioGain;ILjava/lang/String;[I[I"
2939 "Ljava/util/List;)V");
2940
2941 // When access AudioPort as AudioDevicePort
2942 gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
2943 gAudioPortFields.mAddress = GetFieldIDOrDie(env, audioDevicePortClass, "mAddress",
2944 "Ljava/lang/String;");
2945
2946 jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
2947 gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
2948 gAudioMixPortCstor =
2949 GetMethodIDOrDie(env, audioMixPortClass, "<init>",
2950 "(Landroid/media/AudioHandle;IILjava/lang/String;Ljava/util/List;"
2951 "[Landroid/media/AudioGain;)V");
2952
2953 jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
2954 gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
2955 gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V");
2956
2957 jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig");
2958 gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass);
2959 gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>",
2960 "(ILandroid/media/AudioGain;II[II)V");
2961 gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I");
2962 gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I");
2963 gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask",
2964 "I");
2965 gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I");
2966 gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass,
2967 "mRampDurationMs", "I");
2968
2969 jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch");
2970 gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass);
2971 gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>",
2972 "(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V");
2973 gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle",
2974 "Landroid/media/AudioHandle;");
2975
2976 jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName);
2977 gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie(
2978 env, eventHandlerClass, "postEventFromNative",
2979 "(Ljava/lang/Object;IIILjava/lang/Object;)V");
2980 gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
2981 eventHandlerClass, "mJniCallback", "J");
2982
2983 gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative =
2984 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2985 "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
2986 gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
2987 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2988 "recordingCallbackFromNative", "(IIIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V");
2989 gAudioPolicyEventHandlerMethods.postRoutingUpdatedFromNative =
2990 GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
2991 "routingCallbackFromNative", "()V");
2992
2993 jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
2994 gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
2995 gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
2996 "Landroid/media/audiopolicy/AudioMixingRule;");
2997 gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat",
2998 "Landroid/media/AudioFormat;");
2999 gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I");
3000 gAudioMixFields.mDeviceType = GetFieldIDOrDie(env, audioMixClass, "mDeviceSystemType", "I");
3001 gAudioMixFields.mDeviceAddress = GetFieldIDOrDie(env, audioMixClass, "mDeviceAddress",
3002 "Ljava/lang/String;");
3003 gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
3004 gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
3005
3006 jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
3007 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
3008 gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I");
3009 gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I");
3010 gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I");
3011
3012 jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule");
3013 gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
3014 gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
3015 "Ljava/util/ArrayList;");
3016 gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture =
3017 GetFieldIDOrDie(env, audioMixingRuleClass, "mAllowPrivilegedPlaybackCapture", "Z");
3018
3019 gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed =
3020 GetFieldIDOrDie(env, audioMixingRuleClass, "mVoiceCommunicationCaptureAllowed", "Z");
3021
3022 jclass audioMixMatchCriterionClass =
3023 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
3024 gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
3025 gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
3026 "Landroid/media/AudioAttributes;");
3027 gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
3028 "I");
3029 gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
3030 "I");
3031 // AudioTrackRoutingProxy methods
3032 gClsAudioTrackRoutingProxy =
3033 android::FindClassOrDie(env, "android/media/AudioTrackRoutingProxy");
3034 // make sure this reference doesn't get deleted
3035 gClsAudioTrackRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioTrackRoutingProxy);
3036
3037 gMidAudioTrackRoutingProxy_ctor =
3038 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "<init>", "(J)V");
3039 gMidAudioTrackRoutingProxy_release =
3040 android::GetMethodIDOrDie(env, gClsAudioTrackRoutingProxy, "native_release", "()V");
3041
3042 // AudioRecordRoutingProxy
3043 gClsAudioRecordRoutingProxy =
3044 android::FindClassOrDie(env, "android/media/AudioRecordRoutingProxy");
3045 // make sure this reference doesn't get deleted
3046 gClsAudioRecordRoutingProxy = (jclass)env->NewGlobalRef(gClsAudioRecordRoutingProxy);
3047
3048 gMidAudioRecordRoutingProxy_ctor =
3049 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "<init>", "(J)V");
3050 gMidAudioRecordRoutingProxy_release =
3051 android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V");
3052
3053 jclass listClass = FindClassOrDie(env, "java/util/List");
3054 gListClass = MakeGlobalRefOrDie(env, listClass);
3055 gListMethods.add = GetMethodIDOrDie(env, listClass, "add", "(Ljava/lang/Object;)Z");
3056 gListMethods.get = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
3057 gListMethods.size = GetMethodIDOrDie(env, listClass, "size", "()I");
3058
3059 jclass audioProfileClass = FindClassOrDie(env, "android/media/AudioProfile");
3060 gAudioProfileClass = MakeGlobalRefOrDie(env, audioProfileClass);
3061 gAudioProfileCstor = GetMethodIDOrDie(env, audioProfileClass, "<init>", "(I[I[I[II)V");
3062
3063 jclass audioDescriptorClass = FindClassOrDie(env, "android/media/AudioDescriptor");
3064 gAudioDescriptorClass = MakeGlobalRefOrDie(env, audioDescriptorClass);
3065 gAudioDescriptorCstor = GetMethodIDOrDie(env, audioDescriptorClass, "<init>", "(II[B)V");
3066
3067 jclass vibratorClass = FindClassOrDie(env, "android/os/Vibrator");
3068 gVibratorClass = MakeGlobalRefOrDie(env, vibratorClass);
3069 gVibratorMethods.getId = GetMethodIDOrDie(env, vibratorClass, "getId", "()I");
3070 gVibratorMethods.getResonantFrequency =
3071 GetMethodIDOrDie(env, vibratorClass, "getResonantFrequency", "()F");
3072 gVibratorMethods.getQFactor = GetMethodIDOrDie(env, vibratorClass, "getQFactor", "()F");
3073
3074 AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback);
3075
3076 RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
3077 return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods,
3078 NELEM(gEventHandlerMethods));
3079 }
3080