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