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