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