android_media_AudioSystem.cpp revision d8812ce390a972cb2f2c273f7ede55fcccd6298b
1/* 2** 3** Copyright 2006, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19 20#define LOG_TAG "AudioSystem-JNI" 21#include <utils/Log.h> 22 23#include <jni.h> 24#include <JNIHelp.h> 25#include "core_jni_helpers.h" 26 27#include <media/AudioSystem.h> 28#include <media/AudioPolicy.h> 29 30#include <system/audio.h> 31#include <system/audio_policy.h> 32#include "android_media_AudioFormat.h" 33#include "android_media_AudioErrors.h" 34 35// ---------------------------------------------------------------------------- 36 37using namespace android; 38 39static const char* const kClassPathName = "android/media/AudioSystem"; 40 41static jclass gArrayListClass; 42static struct { 43 jmethodID add; 44 jmethodID toArray; 45} gArrayListMethods; 46 47static jclass gAudioHandleClass; 48static jmethodID gAudioHandleCstor; 49static struct { 50 jfieldID mId; 51} gAudioHandleFields; 52 53static jclass gAudioPortClass; 54static jmethodID gAudioPortCstor; 55static struct { 56 jfieldID mHandle; 57 jfieldID mRole; 58 jfieldID mGains; 59 jfieldID mActiveConfig; 60 // other fields unused by JNI 61} gAudioPortFields; 62 63static jclass gAudioPortConfigClass; 64static jmethodID gAudioPortConfigCstor; 65static struct { 66 jfieldID mPort; 67 jfieldID mSamplingRate; 68 jfieldID mChannelMask; 69 jfieldID mFormat; 70 jfieldID mGain; 71 jfieldID mConfigMask; 72} gAudioPortConfigFields; 73 74static jclass gAudioDevicePortClass; 75static jmethodID gAudioDevicePortCstor; 76 77static jclass gAudioDevicePortConfigClass; 78static jmethodID gAudioDevicePortConfigCstor; 79 80static jclass gAudioMixPortClass; 81static jmethodID gAudioMixPortCstor; 82 83static jclass gAudioMixPortConfigClass; 84static jmethodID gAudioMixPortConfigCstor; 85 86static jclass gAudioGainClass; 87static jmethodID gAudioGainCstor; 88 89static jclass gAudioGainConfigClass; 90static jmethodID gAudioGainConfigCstor; 91static struct { 92 jfieldID mIndex; 93 jfieldID mMode; 94 jfieldID mChannelMask; 95 jfieldID mValues; 96 jfieldID mRampDurationMs; 97 // other fields unused by JNI 98} gAudioGainConfigFields; 99 100static jclass gAudioPatchClass; 101static jmethodID gAudioPatchCstor; 102static struct { 103 jfieldID mHandle; 104 // other fields unused by JNI 105} gAudioPatchFields; 106 107static jclass gAudioMixClass; 108static struct { 109 jfieldID mRule; 110 jfieldID mFormat; 111 jfieldID mRouteFlags; 112 jfieldID mRegistrationId; 113 jfieldID mMixType; 114} gAudioMixFields; 115 116static jclass gAudioFormatClass; 117static struct { 118 jfieldID mEncoding; 119 jfieldID mSampleRate; 120 jfieldID mChannelMask; 121 // other fields unused by JNI 122} gAudioFormatFields; 123 124static jclass gAudioMixingRuleClass; 125static struct { 126 jfieldID mCriteria; 127 // other fields unused by JNI 128} gAudioMixingRuleFields; 129 130static jclass gAttributeMatchCriterionClass; 131static struct { 132 jfieldID mAttr; 133 jfieldID mRule; 134} gAttributeMatchCriterionFields; 135 136static jclass gAudioAttributesClass; 137static struct { 138 jfieldID mUsage; 139 jfieldID mSource; 140} gAudioAttributesFields; 141 142 143static const char* const kEventHandlerClassPathName = 144 "android/media/AudioPortEventHandler"; 145static jmethodID gPostEventFromNative; 146 147enum AudioError { 148 kAudioStatusOk = 0, 149 kAudioStatusError = 1, 150 kAudioStatusMediaServerDied = 100 151}; 152 153enum { 154 AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1, 155 AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2, 156 AUDIOPORT_EVENT_SERVICE_DIED = 3, 157}; 158 159#define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5 160 161// ---------------------------------------------------------------------------- 162// ref-counted object for callbacks 163class JNIAudioPortCallback: public AudioSystem::AudioPortCallback 164{ 165public: 166 JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz); 167 ~JNIAudioPortCallback(); 168 169 virtual void onAudioPortListUpdate(); 170 virtual void onAudioPatchListUpdate(); 171 virtual void onServiceDied(); 172 173private: 174 void sendEvent(int event); 175 176 jclass mClass; // Reference to AudioPortEventHandlerDelegate class 177 jobject mObject; // Weak ref to AudioPortEventHandlerDelegate Java object to call on 178}; 179 180JNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz) 181{ 182 183 // Hold onto the SoundTriggerModule class for use in calling the static method 184 // that posts events to the application thread. 185 jclass clazz = env->GetObjectClass(thiz); 186 if (clazz == NULL) { 187 ALOGE("Can't find class %s", kEventHandlerClassPathName); 188 return; 189 } 190 mClass = (jclass)env->NewGlobalRef(clazz); 191 192 // We use a weak reference so the SoundTriggerModule object can be garbage collected. 193 // The reference is only used as a proxy for callbacks. 194 mObject = env->NewGlobalRef(weak_thiz); 195} 196 197JNIAudioPortCallback::~JNIAudioPortCallback() 198{ 199 // remove global references 200 JNIEnv *env = AndroidRuntime::getJNIEnv(); 201 if (env == NULL) { 202 return; 203 } 204 env->DeleteGlobalRef(mObject); 205 env->DeleteGlobalRef(mClass); 206} 207 208void JNIAudioPortCallback::sendEvent(int event) 209{ 210 JNIEnv *env = AndroidRuntime::getJNIEnv(); 211 if (env == NULL) { 212 return; 213 } 214 env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, 215 event, 0, 0, NULL); 216 if (env->ExceptionCheck()) { 217 ALOGW("An exception occurred while notifying an event."); 218 env->ExceptionClear(); 219 } 220} 221 222void JNIAudioPortCallback::onAudioPortListUpdate() 223{ 224 sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED); 225} 226 227void JNIAudioPortCallback::onAudioPatchListUpdate() 228{ 229 sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED); 230} 231 232void JNIAudioPortCallback::onServiceDied() 233{ 234 sendEvent(AUDIOPORT_EVENT_SERVICE_DIED); 235} 236 237static int check_AudioSystem_Command(status_t status) 238{ 239 switch (status) { 240 case DEAD_OBJECT: 241 return kAudioStatusMediaServerDied; 242 case NO_ERROR: 243 return kAudioStatusOk; 244 default: 245 break; 246 } 247 return kAudioStatusError; 248} 249 250static jint 251android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on) 252{ 253 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on)); 254} 255 256static jboolean 257android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz) 258{ 259 bool state = false; 260 AudioSystem::isMicrophoneMuted(&state); 261 return state; 262} 263 264static jboolean 265android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs) 266{ 267 bool state = false; 268 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs); 269 return state; 270} 271 272static jboolean 273android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream, 274 jint inPastMs) 275{ 276 bool state = false; 277 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs); 278 return state; 279} 280 281static jboolean 282android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source) 283{ 284 bool state = false; 285 AudioSystem::isSourceActive((audio_source_t) source, &state); 286 return state; 287} 288 289static jint 290android_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz) 291{ 292 return AudioSystem::newAudioUniqueId(); 293} 294 295static jint 296android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs) 297{ 298 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0); 299 String8 c_keyValuePairs8; 300 if (keyValuePairs) { 301 c_keyValuePairs8 = String8( 302 reinterpret_cast<const char16_t*>(c_keyValuePairs), 303 env->GetStringLength(keyValuePairs)); 304 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs); 305 } 306 int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8)); 307 return (jint) status; 308} 309 310static jstring 311android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys) 312{ 313 const jchar* c_keys = env->GetStringCritical(keys, 0); 314 String8 c_keys8; 315 if (keys) { 316 c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys), 317 env->GetStringLength(keys)); 318 env->ReleaseStringCritical(keys, c_keys); 319 } 320 return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string()); 321} 322 323static void 324android_media_AudioSystem_error_callback(status_t err) 325{ 326 JNIEnv *env = AndroidRuntime::getJNIEnv(); 327 if (env == NULL) { 328 return; 329 } 330 331 jclass clazz = env->FindClass(kClassPathName); 332 333 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, 334 "errorCallbackFromNative","(I)V"), 335 check_AudioSystem_Command(err)); 336 337 env->DeleteLocalRef(clazz); 338} 339 340static jint 341android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name) 342{ 343 const char *c_address = env->GetStringUTFChars(device_address, NULL); 344 const char *c_name = env->GetStringUTFChars(device_name, NULL); 345 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device), 346 static_cast <audio_policy_dev_state_t>(state), 347 c_address, c_name)); 348 env->ReleaseStringUTFChars(device_address, c_address); 349 env->ReleaseStringUTFChars(device_name, c_name); 350 return (jint) status; 351} 352 353static jint 354android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address) 355{ 356 const char *c_address = env->GetStringUTFChars(device_address, NULL); 357 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device), 358 c_address)); 359 env->ReleaseStringUTFChars(device_address, c_address); 360 return (jint) state; 361} 362 363static jint 364android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state) 365{ 366 return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state)); 367} 368 369static jint 370android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config) 371{ 372 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage), 373 static_cast <audio_policy_forced_cfg_t>(config))); 374} 375 376static jint 377android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage) 378{ 379 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage))); 380} 381 382static jint 383android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax) 384{ 385 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream), 386 indexMin, 387 indexMax)); 388} 389 390static jint 391android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, 392 jobject thiz, 393 jint stream, 394 jint index, 395 jint device) 396{ 397 return (jint) check_AudioSystem_Command( 398 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream), 399 index, 400 (audio_devices_t)device)); 401} 402 403static jint 404android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env, 405 jobject thiz, 406 jint stream, 407 jint device) 408{ 409 int index; 410 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream), 411 &index, 412 (audio_devices_t)device) 413 != NO_ERROR) { 414 index = -1; 415 } 416 return (jint) index; 417} 418 419static jint 420android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value) 421{ 422 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value)); 423} 424 425static jfloat 426android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz) 427{ 428 float value; 429 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) { 430 value = -1.0; 431 } 432 return value; 433} 434 435static jint 436android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute) 437{ 438 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute)); 439} 440 441static jboolean 442android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz) 443{ 444 bool mute; 445 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) { 446 mute = false; 447 } 448 return mute; 449} 450 451static jint 452android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream) 453{ 454 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream)); 455} 456 457static jint 458android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz) 459{ 460 return (jint) AudioSystem::getPrimaryOutputSamplingRate(); 461} 462 463static jint 464android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz) 465{ 466 return (jint) AudioSystem::getPrimaryOutputFrameCount(); 467} 468 469static jint 470android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream) 471{ 472 uint32_t afLatency; 473 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream)) 474 != NO_ERROR) { 475 afLatency = -1; 476 } 477 return (jint) afLatency; 478} 479 480static jint 481android_media_AudioSystem_setLowRamDevice(JNIEnv *env, jobject clazz, jboolean isLowRamDevice) 482{ 483 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice); 484} 485 486static jint 487android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz) 488{ 489 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger()); 490} 491 492 493static bool useInChannelMask(audio_port_type_t type, audio_port_role_t role) 494{ 495 return ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || 496 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK)); 497} 498 499static void convertAudioGainConfigToNative(JNIEnv *env, 500 struct audio_gain_config *nAudioGainConfig, 501 const jobject jAudioGainConfig, 502 bool useInMask) 503{ 504 nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex); 505 nAudioGainConfig->mode = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode); 506 ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index); 507 jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask); 508 audio_channel_mask_t nMask; 509 if (useInMask) { 510 nMask = inChannelMaskToNative(jMask); 511 ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask); 512 } else { 513 nMask = outChannelMaskToNative(jMask); 514 ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask); 515 } 516 nAudioGainConfig->channel_mask = nMask; 517 nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig, 518 gAudioGainConfigFields.mRampDurationMs); 519 jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig, 520 gAudioGainConfigFields.mValues); 521 int *nValues = env->GetIntArrayElements(jValues, NULL); 522 size_t size = env->GetArrayLength(jValues); 523 memcpy(nAudioGainConfig->values, nValues, size * sizeof(int)); 524 env->DeleteLocalRef(jValues); 525} 526 527 528static jint convertAudioPortConfigToNative(JNIEnv *env, 529 struct audio_port_config *nAudioPortConfig, 530 const jobject jAudioPortConfig, 531 bool useConfigMask) 532{ 533 jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort); 534 jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle); 535 nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId); 536 nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort, 537 gAudioPortFields.mRole); 538 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) { 539 nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE; 540 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) { 541 nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX; 542 } else { 543 env->DeleteLocalRef(jAudioPort); 544 env->DeleteLocalRef(jHandle); 545 return (jint)AUDIO_JAVA_ERROR; 546 } 547 ALOGV("convertAudioPortConfigToNative handle %d role %d type %d", 548 nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type); 549 550 unsigned int configMask = 0; 551 552 nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig, 553 gAudioPortConfigFields.mSamplingRate); 554 if (nAudioPortConfig->sample_rate != 0) { 555 configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE; 556 } 557 558 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role); 559 audio_channel_mask_t nMask; 560 jint jMask = env->GetIntField(jAudioPortConfig, 561 gAudioPortConfigFields.mChannelMask); 562 if (useInMask) { 563 nMask = inChannelMaskToNative(jMask); 564 ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask); 565 } else { 566 nMask = outChannelMaskToNative(jMask); 567 ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask); 568 } 569 nAudioPortConfig->channel_mask = nMask; 570 if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) { 571 configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK; 572 } 573 574 jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat); 575 audio_format_t nFormat = audioFormatToNative(jFormat); 576 ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat); 577 nAudioPortConfig->format = nFormat; 578 if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT && 579 nAudioPortConfig->format != AUDIO_FORMAT_INVALID) { 580 configMask |= AUDIO_PORT_CONFIG_FORMAT; 581 } 582 583 jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain); 584 if (jGain != NULL) { 585 convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask); 586 env->DeleteLocalRef(jGain); 587 configMask |= AUDIO_PORT_CONFIG_GAIN; 588 } else { 589 ALOGV("convertAudioPortConfigToNative no gain"); 590 nAudioPortConfig->gain.index = -1; 591 } 592 if (useConfigMask) { 593 nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig, 594 gAudioPortConfigFields.mConfigMask); 595 } else { 596 nAudioPortConfig->config_mask = configMask; 597 } 598 env->DeleteLocalRef(jAudioPort); 599 env->DeleteLocalRef(jHandle); 600 return (jint)AUDIO_JAVA_SUCCESS; 601} 602 603static jint convertAudioPortConfigFromNative(JNIEnv *env, 604 jobject jAudioPort, 605 jobject *jAudioPortConfig, 606 const struct audio_port_config *nAudioPortConfig) 607{ 608 jint jStatus = AUDIO_JAVA_SUCCESS; 609 jobject jAudioGainConfig = NULL; 610 jobject jAudioGain = NULL; 611 jintArray jGainValues; 612 bool audioportCreated = false; 613 614 ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort); 615 616 if (jAudioPort == NULL) { 617 jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor, 618 nAudioPortConfig->id); 619 620 ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id, 621 nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix"); 622 623 if (jHandle == NULL) { 624 return (jint)AUDIO_JAVA_ERROR; 625 } 626 // create dummy port and port config objects with just the correct handle 627 // and configuration data. The actual AudioPortConfig objects will be 628 // constructed by java code with correct class type (device, mix etc...) 629 // and reference to AudioPort instance in this client 630 jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor, 631 jHandle, 632 0, 633 NULL, 634 NULL, 635 NULL, 636 NULL, 637 NULL); 638 env->DeleteLocalRef(jHandle); 639 if (jAudioPort == NULL) { 640 return (jint)AUDIO_JAVA_ERROR; 641 } 642 ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d", 643 nAudioPortConfig->id); 644 645 audioportCreated = true; 646 } 647 648 bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role); 649 650 audio_channel_mask_t nMask; 651 jint jMask; 652 653 int gainIndex = nAudioPortConfig->gain.index; 654 if (gainIndex >= 0) { 655 ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x", 656 gainIndex, nAudioPortConfig->gain.mode); 657 if (audioportCreated) { 658 ALOGV("convertAudioPortConfigFromNative creating gain"); 659 jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor, 660 gainIndex, 661 0, 662 0, 663 0, 664 0, 665 0, 666 0, 667 0, 668 0); 669 if (jAudioGain == NULL) { 670 ALOGV("convertAudioPortConfigFromNative creating gain FAILED"); 671 jStatus = (jint)AUDIO_JAVA_ERROR; 672 goto exit; 673 } 674 } else { 675 ALOGV("convertAudioPortConfigFromNative reading gain from port"); 676 jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort, 677 gAudioPortFields.mGains); 678 if (jGains == NULL) { 679 ALOGV("convertAudioPortConfigFromNative could not get gains from port"); 680 jStatus = (jint)AUDIO_JAVA_ERROR; 681 goto exit; 682 } 683 jAudioGain = env->GetObjectArrayElement(jGains, gainIndex); 684 env->DeleteLocalRef(jGains); 685 if (jAudioGain == NULL) { 686 ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex); 687 jStatus = (jint)AUDIO_JAVA_ERROR; 688 goto exit; 689 } 690 } 691 int numValues; 692 if (useInMask) { 693 numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask); 694 } else { 695 numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask); 696 } 697 jGainValues = env->NewIntArray(numValues); 698 if (jGainValues == NULL) { 699 ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues); 700 jStatus = (jint)AUDIO_JAVA_ERROR; 701 goto exit; 702 } 703 env->SetIntArrayRegion(jGainValues, 0, numValues, 704 nAudioPortConfig->gain.values); 705 706 nMask = nAudioPortConfig->gain.channel_mask; 707 if (useInMask) { 708 jMask = inChannelMaskFromNative(nMask); 709 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask); 710 } else { 711 jMask = outChannelMaskFromNative(nMask); 712 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask); 713 } 714 715 jAudioGainConfig = env->NewObject(gAudioGainConfigClass, 716 gAudioGainConfigCstor, 717 gainIndex, 718 jAudioGain, 719 nAudioPortConfig->gain.mode, 720 jMask, 721 jGainValues, 722 nAudioPortConfig->gain.ramp_duration_ms); 723 env->DeleteLocalRef(jGainValues); 724 if (jAudioGainConfig == NULL) { 725 ALOGV("convertAudioPortConfigFromNative could not create gain config"); 726 jStatus = (jint)AUDIO_JAVA_ERROR; 727 goto exit; 728 } 729 } 730 jclass clazz; 731 jmethodID methodID; 732 if (audioportCreated) { 733 clazz = gAudioPortConfigClass; 734 methodID = gAudioPortConfigCstor; 735 ALOGV("convertAudioPortConfigFromNative building a generic port config"); 736 } else { 737 if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) { 738 clazz = gAudioDevicePortConfigClass; 739 methodID = gAudioDevicePortConfigCstor; 740 ALOGV("convertAudioPortConfigFromNative building a device config"); 741 } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) { 742 clazz = gAudioMixPortConfigClass; 743 methodID = gAudioMixPortConfigCstor; 744 ALOGV("convertAudioPortConfigFromNative building a mix config"); 745 } else { 746 jStatus = (jint)AUDIO_JAVA_ERROR; 747 goto exit; 748 } 749 } 750 nMask = nAudioPortConfig->channel_mask; 751 if (useInMask) { 752 jMask = inChannelMaskFromNative(nMask); 753 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask); 754 } else { 755 jMask = outChannelMaskFromNative(nMask); 756 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask); 757 } 758 759 *jAudioPortConfig = env->NewObject(clazz, methodID, 760 jAudioPort, 761 nAudioPortConfig->sample_rate, 762 jMask, 763 audioFormatFromNative(nAudioPortConfig->format), 764 jAudioGainConfig); 765 if (*jAudioPortConfig == NULL) { 766 ALOGV("convertAudioPortConfigFromNative could not create new port config"); 767 jStatus = (jint)AUDIO_JAVA_ERROR; 768 } else { 769 ALOGV("convertAudioPortConfigFromNative OK"); 770 } 771 772exit: 773 if (audioportCreated) { 774 env->DeleteLocalRef(jAudioPort); 775 if (jAudioGain != NULL) { 776 env->DeleteLocalRef(jAudioGain); 777 } 778 } 779 if (jAudioGainConfig != NULL) { 780 env->DeleteLocalRef(jAudioGainConfig); 781 } 782 return jStatus; 783} 784 785static jint convertAudioPortFromNative(JNIEnv *env, 786 jobject *jAudioPort, const struct audio_port *nAudioPort) 787{ 788 jint jStatus = (jint)AUDIO_JAVA_SUCCESS; 789 jintArray jSamplingRates = NULL; 790 jintArray jChannelMasks = NULL; 791 jintArray jFormats = NULL; 792 jobjectArray jGains = NULL; 793 jobject jHandle = NULL; 794 jstring jDeviceName = NULL; 795 bool useInMask; 796 797 ALOGV("convertAudioPortFromNative id %d role %d type %d name %s", 798 nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name); 799 800 jSamplingRates = env->NewIntArray(nAudioPort->num_sample_rates); 801 if (jSamplingRates == NULL) { 802 jStatus = (jint)AUDIO_JAVA_ERROR; 803 goto exit; 804 } 805 if (nAudioPort->num_sample_rates) { 806 env->SetIntArrayRegion(jSamplingRates, 0, nAudioPort->num_sample_rates, 807 (jint *)nAudioPort->sample_rates); 808 } 809 810 jChannelMasks = env->NewIntArray(nAudioPort->num_channel_masks); 811 if (jChannelMasks == NULL) { 812 jStatus = (jint)AUDIO_JAVA_ERROR; 813 goto exit; 814 } 815 useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role); 816 817 jint jMask; 818 for (size_t j = 0; j < nAudioPort->num_channel_masks; j++) { 819 if (useInMask) { 820 jMask = inChannelMaskFromNative(nAudioPort->channel_masks[j]); 821 } else { 822 jMask = outChannelMaskFromNative(nAudioPort->channel_masks[j]); 823 } 824 env->SetIntArrayRegion(jChannelMasks, j, 1, &jMask); 825 } 826 827 jFormats = env->NewIntArray(nAudioPort->num_formats); 828 if (jFormats == NULL) { 829 jStatus = (jint)AUDIO_JAVA_ERROR; 830 goto exit; 831 } 832 for (size_t j = 0; j < nAudioPort->num_formats; j++) { 833 jint jFormat = audioFormatFromNative(nAudioPort->formats[j]); 834 env->SetIntArrayRegion(jFormats, j, 1, &jFormat); 835 } 836 837 jGains = env->NewObjectArray(nAudioPort->num_gains, 838 gAudioGainClass, NULL); 839 if (jGains == NULL) { 840 jStatus = (jint)AUDIO_JAVA_ERROR; 841 goto exit; 842 } 843 for (size_t j = 0; j < nAudioPort->num_gains; j++) { 844 audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask; 845 if (useInMask) { 846 jMask = inChannelMaskFromNative(nMask); 847 ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask); 848 } else { 849 jMask = outChannelMaskFromNative(nMask); 850 ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask); 851 } 852 853 jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor, 854 j, 855 nAudioPort->gains[j].mode, 856 jMask, 857 nAudioPort->gains[j].min_value, 858 nAudioPort->gains[j].max_value, 859 nAudioPort->gains[j].default_value, 860 nAudioPort->gains[j].step_value, 861 nAudioPort->gains[j].min_ramp_ms, 862 nAudioPort->gains[j].max_ramp_ms); 863 if (jGain == NULL) { 864 jStatus = (jint)AUDIO_JAVA_ERROR; 865 goto exit; 866 } 867 env->SetObjectArrayElement(jGains, j, jGain); 868 env->DeleteLocalRef(jGain); 869 } 870 871 jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor, 872 nAudioPort->id); 873 if (jHandle == NULL) { 874 jStatus = (jint)AUDIO_JAVA_ERROR; 875 goto exit; 876 } 877 878 jDeviceName = env->NewStringUTF(nAudioPort->name); 879 880 if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) { 881 ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type); 882 jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address); 883 *jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor, 884 jHandle, jDeviceName, 885 jSamplingRates, jChannelMasks, jFormats, jGains, 886 nAudioPort->ext.device.type, jAddress); 887 env->DeleteLocalRef(jAddress); 888 } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) { 889 ALOGV("convertAudioPortFromNative is a mix"); 890 *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor, 891 jHandle, nAudioPort->role, jDeviceName, 892 jSamplingRates, jChannelMasks, 893 jFormats, jGains); 894 } else { 895 ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type); 896 jStatus = (jint)AUDIO_JAVA_ERROR; 897 goto exit; 898 } 899 if (*jAudioPort == NULL) { 900 jStatus = (jint)AUDIO_JAVA_ERROR; 901 goto exit; 902 } 903 904 jobject jAudioPortConfig; 905 jStatus = convertAudioPortConfigFromNative(env, 906 *jAudioPort, 907 &jAudioPortConfig, 908 &nAudioPort->active_config); 909 if (jStatus != AUDIO_JAVA_SUCCESS) { 910 return jStatus; 911 } 912 913 env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig); 914 915exit: 916 if (jDeviceName != NULL) { 917 env->DeleteLocalRef(jDeviceName); 918 } 919 if (jSamplingRates != NULL) { 920 env->DeleteLocalRef(jSamplingRates); 921 } 922 if (jChannelMasks != NULL) { 923 env->DeleteLocalRef(jChannelMasks); 924 } 925 if (jFormats != NULL) { 926 env->DeleteLocalRef(jFormats); 927 } 928 if (jGains != NULL) { 929 env->DeleteLocalRef(jGains); 930 } 931 if (jHandle != NULL) { 932 env->DeleteLocalRef(jHandle); 933 } 934 935 return jStatus; 936} 937 938 939static jint 940android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz, 941 jobject jPorts, jintArray jGeneration) 942{ 943 ALOGV("listAudioPorts"); 944 945 if (jPorts == NULL) { 946 ALOGE("listAudioPorts NULL AudioPort ArrayList"); 947 return (jint)AUDIO_JAVA_BAD_VALUE; 948 } 949 if (!env->IsInstanceOf(jPorts, gArrayListClass)) { 950 ALOGE("listAudioPorts not an arraylist"); 951 return (jint)AUDIO_JAVA_BAD_VALUE; 952 } 953 954 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) { 955 return (jint)AUDIO_JAVA_BAD_VALUE; 956 } 957 958 status_t status; 959 unsigned int generation1; 960 unsigned int generation; 961 unsigned int numPorts; 962 jint *nGeneration; 963 struct audio_port *nPorts = NULL; 964 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS; 965 966 // get the port count and all the ports until they both return the same generation 967 do { 968 if (attempts-- < 0) { 969 status = TIMED_OUT; 970 break; 971 } 972 973 numPorts = 0; 974 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, 975 AUDIO_PORT_TYPE_NONE, 976 &numPorts, 977 NULL, 978 &generation1); 979 if (status != NO_ERROR || numPorts == 0) { 980 ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status); 981 break; 982 } 983 nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port)); 984 985 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, 986 AUDIO_PORT_TYPE_NONE, 987 &numPorts, 988 nPorts, 989 &generation); 990 ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d", 991 numPorts, generation, generation1); 992 } while (generation1 != generation && status == NO_ERROR); 993 994 jint jStatus = nativeToJavaStatus(status); 995 if (jStatus != AUDIO_JAVA_SUCCESS) { 996 goto exit; 997 } 998 999 nGeneration = env->GetIntArrayElements(jGeneration, NULL); 1000 if (nGeneration == NULL) { 1001 jStatus = (jint)AUDIO_JAVA_ERROR; 1002 goto exit; 1003 } 1004 nGeneration[0] = generation1; 1005 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0); 1006 1007 for (size_t i = 0; i < numPorts; i++) { 1008 jobject jAudioPort; 1009 jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]); 1010 if (jStatus != AUDIO_JAVA_SUCCESS) { 1011 goto exit; 1012 } 1013 env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort); 1014 } 1015 1016exit: 1017 free(nPorts); 1018 return jStatus; 1019} 1020 1021static int 1022android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz, 1023 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks) 1024{ 1025 status_t status; 1026 jint jStatus; 1027 1028 ALOGV("createAudioPatch"); 1029 if (jPatches == NULL || jSources == NULL || jSinks == NULL) { 1030 return (jint)AUDIO_JAVA_BAD_VALUE; 1031 } 1032 1033 if (env->GetArrayLength(jPatches) != 1) { 1034 return (jint)AUDIO_JAVA_BAD_VALUE; 1035 } 1036 jint numSources = env->GetArrayLength(jSources); 1037 if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) { 1038 return (jint)AUDIO_JAVA_BAD_VALUE; 1039 } 1040 1041 jint numSinks = env->GetArrayLength(jSinks); 1042 if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) { 1043 return (jint)AUDIO_JAVA_BAD_VALUE; 1044 } 1045 1046 audio_patch_handle_t handle = (audio_patch_handle_t)0; 1047 jobject jPatch = env->GetObjectArrayElement(jPatches, 0); 1048 jobject jPatchHandle = NULL; 1049 if (jPatch != NULL) { 1050 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) { 1051 return (jint)AUDIO_JAVA_BAD_VALUE; 1052 } 1053 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle); 1054 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId); 1055 } 1056 1057 struct audio_patch nPatch; 1058 1059 nPatch.id = handle; 1060 nPatch.num_sources = 0; 1061 nPatch.num_sinks = 0; 1062 jobject jSource = NULL; 1063 jobject jSink = NULL; 1064 1065 for (jint i = 0; i < numSources; i++) { 1066 jSource = env->GetObjectArrayElement(jSources, i); 1067 if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) { 1068 jStatus = (jint)AUDIO_JAVA_BAD_VALUE; 1069 goto exit; 1070 } 1071 jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false); 1072 env->DeleteLocalRef(jSource); 1073 jSource = NULL; 1074 if (jStatus != AUDIO_JAVA_SUCCESS) { 1075 goto exit; 1076 } 1077 nPatch.num_sources++; 1078 } 1079 1080 for (jint i = 0; i < numSinks; i++) { 1081 jSink = env->GetObjectArrayElement(jSinks, i); 1082 if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) { 1083 jStatus = (jint)AUDIO_JAVA_BAD_VALUE; 1084 goto exit; 1085 } 1086 jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false); 1087 env->DeleteLocalRef(jSink); 1088 jSink = NULL; 1089 if (jStatus != AUDIO_JAVA_SUCCESS) { 1090 goto exit; 1091 } 1092 nPatch.num_sinks++; 1093 } 1094 1095 ALOGV("AudioSystem::createAudioPatch"); 1096 status = AudioSystem::createAudioPatch(&nPatch, &handle); 1097 ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle); 1098 1099 jStatus = nativeToJavaStatus(status); 1100 if (jStatus != AUDIO_JAVA_SUCCESS) { 1101 goto exit; 1102 } 1103 1104 if (jPatchHandle == NULL) { 1105 jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor, 1106 handle); 1107 if (jPatchHandle == NULL) { 1108 jStatus = (jint)AUDIO_JAVA_ERROR; 1109 goto exit; 1110 } 1111 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks); 1112 if (jPatch == NULL) { 1113 jStatus = (jint)AUDIO_JAVA_ERROR; 1114 goto exit; 1115 } 1116 env->SetObjectArrayElement(jPatches, 0, jPatch); 1117 } else { 1118 env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle); 1119 } 1120 1121exit: 1122 if (jPatchHandle != NULL) { 1123 env->DeleteLocalRef(jPatchHandle); 1124 } 1125 if (jPatch != NULL) { 1126 env->DeleteLocalRef(jPatch); 1127 } 1128 if (jSource != NULL) { 1129 env->DeleteLocalRef(jSource); 1130 } 1131 if (jSink != NULL) { 1132 env->DeleteLocalRef(jSink); 1133 } 1134 return jStatus; 1135} 1136 1137static jint 1138android_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz, 1139 jobject jPatch) 1140{ 1141 ALOGV("releaseAudioPatch"); 1142 if (jPatch == NULL) { 1143 return (jint)AUDIO_JAVA_BAD_VALUE; 1144 } 1145 1146 audio_patch_handle_t handle = (audio_patch_handle_t)0; 1147 jobject jPatchHandle = NULL; 1148 if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) { 1149 return (jint)AUDIO_JAVA_BAD_VALUE; 1150 } 1151 jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle); 1152 handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId); 1153 env->DeleteLocalRef(jPatchHandle); 1154 1155 ALOGV("AudioSystem::releaseAudioPatch"); 1156 status_t status = AudioSystem::releaseAudioPatch(handle); 1157 ALOGV("AudioSystem::releaseAudioPatch() returned %d", status); 1158 jint jStatus = nativeToJavaStatus(status); 1159 return jStatus; 1160} 1161 1162static jint 1163android_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz, 1164 jobject jPatches, jintArray jGeneration) 1165{ 1166 ALOGV("listAudioPatches"); 1167 if (jPatches == NULL) { 1168 ALOGE("listAudioPatches NULL AudioPatch ArrayList"); 1169 return (jint)AUDIO_JAVA_BAD_VALUE; 1170 } 1171 if (!env->IsInstanceOf(jPatches, gArrayListClass)) { 1172 ALOGE("listAudioPatches not an arraylist"); 1173 return (jint)AUDIO_JAVA_BAD_VALUE; 1174 } 1175 1176 if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) { 1177 return (jint)AUDIO_JAVA_BAD_VALUE; 1178 } 1179 1180 status_t status; 1181 unsigned int generation1; 1182 unsigned int generation; 1183 unsigned int numPatches; 1184 jint *nGeneration; 1185 struct audio_patch *nPatches = NULL; 1186 jobjectArray jSources = NULL; 1187 jobject jSource = NULL; 1188 jobjectArray jSinks = NULL; 1189 jobject jSink = NULL; 1190 jobject jPatch = NULL; 1191 int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS; 1192 1193 // get the patch count and all the patches until they both return the same generation 1194 do { 1195 if (attempts-- < 0) { 1196 status = TIMED_OUT; 1197 break; 1198 } 1199 1200 numPatches = 0; 1201 status = AudioSystem::listAudioPatches(&numPatches, 1202 NULL, 1203 &generation1); 1204 if (status != NO_ERROR || numPatches == 0) { 1205 ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d", 1206 status); 1207 break; 1208 } 1209 nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch)); 1210 1211 status = AudioSystem::listAudioPatches(&numPatches, 1212 nPatches, 1213 &generation); 1214 ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d", 1215 numPatches, generation, generation1); 1216 1217 } while (generation1 != generation && status == NO_ERROR); 1218 1219 jint jStatus = nativeToJavaStatus(status); 1220 if (jStatus != AUDIO_JAVA_SUCCESS) { 1221 goto exit; 1222 } 1223 1224 nGeneration = env->GetIntArrayElements(jGeneration, NULL); 1225 if (nGeneration == NULL) { 1226 jStatus = AUDIO_JAVA_ERROR; 1227 goto exit; 1228 } 1229 nGeneration[0] = generation1; 1230 env->ReleaseIntArrayElements(jGeneration, nGeneration, 0); 1231 1232 for (size_t i = 0; i < numPatches; i++) { 1233 jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor, 1234 nPatches[i].id); 1235 if (patchHandle == NULL) { 1236 jStatus = AUDIO_JAVA_ERROR; 1237 goto exit; 1238 } 1239 ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d", 1240 i, nPatches[i].num_sources, nPatches[i].num_sinks); 1241 1242 env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id); 1243 1244 // load sources 1245 jSources = env->NewObjectArray(nPatches[i].num_sources, 1246 gAudioPortConfigClass, NULL); 1247 if (jSources == NULL) { 1248 jStatus = AUDIO_JAVA_ERROR; 1249 goto exit; 1250 } 1251 1252 for (size_t j = 0; j < nPatches[i].num_sources; j++) { 1253 jStatus = convertAudioPortConfigFromNative(env, 1254 NULL, 1255 &jSource, 1256 &nPatches[i].sources[j]); 1257 if (jStatus != AUDIO_JAVA_SUCCESS) { 1258 goto exit; 1259 } 1260 env->SetObjectArrayElement(jSources, j, jSource); 1261 env->DeleteLocalRef(jSource); 1262 jSource = NULL; 1263 ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d", 1264 i, j, 1265 nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix", 1266 nPatches[i].sources[j].id); 1267 } 1268 // load sinks 1269 jSinks = env->NewObjectArray(nPatches[i].num_sinks, 1270 gAudioPortConfigClass, NULL); 1271 if (jSinks == NULL) { 1272 jStatus = AUDIO_JAVA_ERROR; 1273 goto exit; 1274 } 1275 1276 for (size_t j = 0; j < nPatches[i].num_sinks; j++) { 1277 jStatus = convertAudioPortConfigFromNative(env, 1278 NULL, 1279 &jSink, 1280 &nPatches[i].sinks[j]); 1281 1282 if (jStatus != AUDIO_JAVA_SUCCESS) { 1283 goto exit; 1284 } 1285 env->SetObjectArrayElement(jSinks, j, jSink); 1286 env->DeleteLocalRef(jSink); 1287 jSink = NULL; 1288 ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d", 1289 i, j, 1290 nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix", 1291 nPatches[i].sinks[j].id); 1292 } 1293 1294 jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, 1295 patchHandle, jSources, jSinks); 1296 env->DeleteLocalRef(jSources); 1297 jSources = NULL; 1298 env->DeleteLocalRef(jSinks); 1299 jSinks = NULL; 1300 if (jPatch == NULL) { 1301 jStatus = AUDIO_JAVA_ERROR; 1302 goto exit; 1303 } 1304 env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch); 1305 env->DeleteLocalRef(jPatch); 1306 jPatch = NULL; 1307 } 1308 1309exit: 1310 if (jSources != NULL) { 1311 env->DeleteLocalRef(jSources); 1312 } 1313 if (jSource != NULL) { 1314 env->DeleteLocalRef(jSource); 1315 } 1316 if (jSinks != NULL) { 1317 env->DeleteLocalRef(jSinks); 1318 } 1319 if (jSink != NULL) { 1320 env->DeleteLocalRef(jSink); 1321 } 1322 if (jPatch != NULL) { 1323 env->DeleteLocalRef(jPatch); 1324 } 1325 free(nPatches); 1326 return jStatus; 1327} 1328 1329static jint 1330android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz, 1331 jobject jAudioPortConfig) 1332{ 1333 ALOGV("setAudioPortConfig"); 1334 if (jAudioPortConfig == NULL) { 1335 return AUDIO_JAVA_BAD_VALUE; 1336 } 1337 if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) { 1338 return AUDIO_JAVA_BAD_VALUE; 1339 } 1340 struct audio_port_config nAudioPortConfig; 1341 jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true); 1342 if (jStatus != AUDIO_JAVA_SUCCESS) { 1343 return jStatus; 1344 } 1345 status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig); 1346 ALOGV("AudioSystem::setAudioPortConfig() returned %d", status); 1347 jStatus = nativeToJavaStatus(status); 1348 return jStatus; 1349} 1350 1351static void 1352android_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this) 1353{ 1354 ALOGV("eventHandlerSetup"); 1355 1356 sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this); 1357 1358 AudioSystem::setAudioPortCallback(callback); 1359} 1360 1361static void 1362android_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz) 1363{ 1364 ALOGV("eventHandlerFinalize"); 1365 1366 sp<JNIAudioPortCallback> callback; 1367 1368 AudioSystem::setAudioPortCallback(callback); 1369} 1370 1371static jint 1372android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId) 1373{ 1374 return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId); 1375} 1376 1377 1378 1379 1380static jint convertAudioMixToNative(JNIEnv *env, 1381 AudioMix *nAudioMix, 1382 const jobject jAudioMix) 1383{ 1384 nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType); 1385 nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags); 1386 1387 jstring jRegistrationId = (jstring)env->GetObjectField(jAudioMix, 1388 gAudioMixFields.mRegistrationId); 1389 const char *nRegistrationId = env->GetStringUTFChars(jRegistrationId, NULL); 1390 nAudioMix->mRegistrationId = String8(nRegistrationId); 1391 env->ReleaseStringUTFChars(jRegistrationId, nRegistrationId); 1392 env->DeleteLocalRef(jRegistrationId); 1393 1394 jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat); 1395 nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat, 1396 gAudioFormatFields.mSampleRate); 1397 nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat, 1398 gAudioFormatFields.mChannelMask)); 1399 nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat, 1400 gAudioFormatFields.mEncoding)); 1401 env->DeleteLocalRef(jFormat); 1402 1403 jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); 1404 jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); 1405 env->DeleteLocalRef(jRule); 1406 jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria, 1407 gArrayListMethods.toArray); 1408 env->DeleteLocalRef(jRuleCriteria); 1409 1410 jint numCriteria = env->GetArrayLength(jCriteria); 1411 if (numCriteria > MAX_CRITERIA_PER_MIX) { 1412 numCriteria = MAX_CRITERIA_PER_MIX; 1413 } 1414 1415 for (jint i = 0; i < numCriteria; i++) { 1416 AttributeMatchCriterion nCriterion; 1417 1418 jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); 1419 1420 nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule); 1421 1422 jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr); 1423 if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE || 1424 nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { 1425 nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes, 1426 gAudioAttributesFields.mUsage); 1427 } else { 1428 nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes, 1429 gAudioAttributesFields.mSource); 1430 } 1431 env->DeleteLocalRef(jAttributes); 1432 1433 nAudioMix->mCriteria.add(nCriterion); 1434 env->DeleteLocalRef(jCriterion); 1435 } 1436 1437 env->DeleteLocalRef(jCriteria); 1438 1439 return (jint)AUDIO_JAVA_SUCCESS; 1440} 1441 1442static jint 1443android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz, 1444 jobject jMixesList, jboolean registration) 1445{ 1446 ALOGV("registerPolicyMixes"); 1447 1448 if (jMixesList == NULL) { 1449 return (jint)AUDIO_JAVA_BAD_VALUE; 1450 } 1451 if (!env->IsInstanceOf(jMixesList, gArrayListClass)) { 1452 return (jint)AUDIO_JAVA_BAD_VALUE; 1453 } 1454 jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList, 1455 gArrayListMethods.toArray); 1456 jint numMixes = env->GetArrayLength(jMixes); 1457 if (numMixes > MAX_MIXES_PER_POLICY) { 1458 numMixes = MAX_MIXES_PER_POLICY; 1459 } 1460 1461 status_t status; 1462 jint jStatus; 1463 jobject jAudioMix = NULL; 1464 Vector <AudioMix> mixes; 1465 for (jint i = 0; i < numMixes; i++) { 1466 jAudioMix = env->GetObjectArrayElement(jMixes, i); 1467 if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) { 1468 jStatus = (jint)AUDIO_JAVA_BAD_VALUE; 1469 goto exit; 1470 } 1471 AudioMix mix; 1472 jStatus = convertAudioMixToNative(env, &mix, jAudioMix); 1473 env->DeleteLocalRef(jAudioMix); 1474 jAudioMix = NULL; 1475 if (jStatus != AUDIO_JAVA_SUCCESS) { 1476 goto exit; 1477 } 1478 mixes.add(mix); 1479 } 1480 1481 ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration); 1482 status = AudioSystem::registerPolicyMixes(mixes, registration); 1483 ALOGV("AudioSystem::registerPolicyMixes() returned %d", status); 1484 1485 jStatus = nativeToJavaStatus(status); 1486 if (jStatus != AUDIO_JAVA_SUCCESS) { 1487 goto exit; 1488 } 1489 1490exit: 1491 if (jAudioMix != NULL) { 1492 env->DeleteLocalRef(jAudioMix); 1493 } 1494 return jStatus; 1495} 1496 1497 1498 1499// ---------------------------------------------------------------------------- 1500 1501static JNINativeMethod gMethods[] = { 1502 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters}, 1503 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters}, 1504 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone}, 1505 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted}, 1506 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive}, 1507 {"isStreamActiveRemotely","(II)Z", (void *)android_media_AudioSystem_isStreamActiveRemotely}, 1508 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive}, 1509 {"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId}, 1510 {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState}, 1511 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState}, 1512 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState}, 1513 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse}, 1514 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse}, 1515 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume}, 1516 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex}, 1517 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex}, 1518 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume}, 1519 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume}, 1520 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute}, 1521 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute}, 1522 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream}, 1523 {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate}, 1524 {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount}, 1525 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency}, 1526 {"setLowRamDevice", "(Z)I", (void *)android_media_AudioSystem_setLowRamDevice}, 1527 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger}, 1528 {"listAudioPorts", "(Ljava/util/ArrayList;[I)I", 1529 (void *)android_media_AudioSystem_listAudioPorts}, 1530 {"createAudioPatch", "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I", 1531 (void *)android_media_AudioSystem_createAudioPatch}, 1532 {"releaseAudioPatch", "(Landroid/media/AudioPatch;)I", 1533 (void *)android_media_AudioSystem_releaseAudioPatch}, 1534 {"listAudioPatches", "(Ljava/util/ArrayList;[I)I", 1535 (void *)android_media_AudioSystem_listAudioPatches}, 1536 {"setAudioPortConfig", "(Landroid/media/AudioPortConfig;)I", 1537 (void *)android_media_AudioSystem_setAudioPortConfig}, 1538 {"getAudioHwSyncForSession", "(I)I", 1539 (void *)android_media_AudioSystem_getAudioHwSyncForSession}, 1540 {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", 1541 (void *)android_media_AudioSystem_registerPolicyMixes}, 1542 1543}; 1544 1545 1546static JNINativeMethod gEventHandlerMethods[] = { 1547 {"native_setup", 1548 "(Ljava/lang/Object;)V", 1549 (void *)android_media_AudioSystem_eventHandlerSetup}, 1550 {"native_finalize", 1551 "()V", 1552 (void *)android_media_AudioSystem_eventHandlerFinalize}, 1553}; 1554 1555int register_android_media_AudioSystem(JNIEnv *env) 1556{ 1557 jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); 1558 gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); 1559 gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); 1560 gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;"); 1561 1562 jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle"); 1563 gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass); 1564 gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V"); 1565 gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I"); 1566 1567 jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort"); 1568 gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass); 1569 gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>", 1570 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V"); 1571 gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle", 1572 "Landroid/media/AudioHandle;"); 1573 gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I"); 1574 gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains", 1575 "[Landroid/media/AudioGain;"); 1576 gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig", 1577 "Landroid/media/AudioPortConfig;"); 1578 1579 jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig"); 1580 gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass); 1581 gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>", 1582 "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V"); 1583 gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort", 1584 "Landroid/media/AudioPort;"); 1585 gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass, 1586 "mSamplingRate", "I"); 1587 gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass, 1588 "mChannelMask", "I"); 1589 gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I"); 1590 gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain", 1591 "Landroid/media/AudioGainConfig;"); 1592 gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask", 1593 "I"); 1594 1595 jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig"); 1596 gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass); 1597 gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>", 1598 "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V"); 1599 1600 jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig"); 1601 gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass); 1602 gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>", 1603 "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V"); 1604 1605 jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort"); 1606 gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass); 1607 gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>", 1608 "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V"); 1609 1610 jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort"); 1611 gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass); 1612 gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>", 1613 "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[Landroid/media/AudioGain;)V"); 1614 1615 jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain"); 1616 gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass); 1617 gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V"); 1618 1619 jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig"); 1620 gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass); 1621 gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>", 1622 "(ILandroid/media/AudioGain;II[II)V"); 1623 gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I"); 1624 gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I"); 1625 gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask", 1626 "I"); 1627 gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I"); 1628 gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass, 1629 "mRampDurationMs", "I"); 1630 1631 jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch"); 1632 gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass); 1633 gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>", 1634"(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V"); 1635 gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle", 1636 "Landroid/media/AudioHandle;"); 1637 1638 jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName); 1639 gPostEventFromNative = GetStaticMethodIDOrDie(env, eventHandlerClass, "postEventFromNative", 1640 "(Ljava/lang/Object;IIILjava/lang/Object;)V"); 1641 1642 1643 jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); 1644 gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); 1645 gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule", 1646 "Landroid/media/audiopolicy/AudioMixingRule;"); 1647 gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat", 1648 "Landroid/media/AudioFormat;"); 1649 gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I"); 1650 gAudioMixFields.mRegistrationId = GetFieldIDOrDie(env, audioMixClass, "mRegistrationId", 1651 "Ljava/lang/String;"); 1652 gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I"); 1653 1654 jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat"); 1655 gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass); 1656 gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I"); 1657 gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I"); 1658 gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I"); 1659 1660 jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule"); 1661 gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass); 1662 gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria", 1663 "Ljava/util/ArrayList;"); 1664 1665 jclass attributeMatchCriterionClass = 1666 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion"); 1667 gAttributeMatchCriterionClass = MakeGlobalRefOrDie(env, attributeMatchCriterionClass); 1668 gAttributeMatchCriterionFields.mAttr = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mAttr", 1669 "Landroid/media/AudioAttributes;"); 1670 gAttributeMatchCriterionFields.mRule = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mRule", 1671 "I"); 1672 1673 jclass audioAttributesClass = FindClassOrDie(env, "android/media/AudioAttributes"); 1674 gAudioAttributesClass = MakeGlobalRefOrDie(env, audioAttributesClass); 1675 gAudioAttributesFields.mUsage = GetFieldIDOrDie(env, audioAttributesClass, "mUsage", "I"); 1676 gAudioAttributesFields.mSource = GetFieldIDOrDie(env, audioAttributesClass, "mSource", "I"); 1677 1678 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback); 1679 1680 RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); 1681 return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods, 1682 NELEM(gEventHandlerMethods)); 1683} 1684