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