Loading core/jni/android_media_AudioSystem.cpp +199 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <android_runtime/AndroidRuntime.h> #include <media/AudioSystem.h> #include <media/AudioPolicy.h> #include <system/audio.h> #include <system/audio_policy.h> Loading @@ -40,6 +41,7 @@ static const char* const kClassPathName = "android/media/AudioSystem"; static jclass gArrayListClass; static struct { jmethodID add; jmethodID toArray; } gArrayListMethods; static jclass gAudioHandleClass; Loading Loading @@ -102,6 +104,42 @@ static struct { // other fields unused by JNI } gAudioPatchFields; static jclass gAudioMixClass; static struct { jfieldID mRule; jfieldID mFormat; jfieldID mRouteFlags; jfieldID mRegistrationId; jfieldID mMixType; } gAudioMixFields; static jclass gAudioFormatClass; static struct { jfieldID mEncoding; jfieldID mSampleRate; jfieldID mChannelMask; // other fields unused by JNI } gAudioFormatFields; static jclass gAudioMixingRuleClass; static struct { jfieldID mCriteria; // other fields unused by JNI } gAudioMixingRuleFields; static jclass gAttributeMatchCriterionClass; static struct { jfieldID mAttr; jfieldID mRule; } gAttributeMatchCriterionFields; static jclass gAudioAttributesClass; static struct { jfieldID mUsage; jfieldID mSource; } gAudioAttributesFields; static const char* const kEventHandlerClassPathName = "android/media/AudioPortEventHandler"; static jmethodID gPostEventFromNative; Loading Loading @@ -1322,6 +1360,128 @@ android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, ji return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId); } static jint convertAudioMixToNative(JNIEnv *env, AudioMix *nAudioMix, const jobject jAudioMix) { nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType); nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags); jstring jRegistrationId = (jstring)env->GetObjectField(jAudioMix, gAudioMixFields.mRegistrationId); const char *nRegistrationId = env->GetStringUTFChars(jRegistrationId, NULL); nAudioMix->mRegistrationId = String8(nRegistrationId); env->ReleaseStringUTFChars(jRegistrationId, nRegistrationId); env->DeleteLocalRef(jRegistrationId); jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat); nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat, gAudioFormatFields.mSampleRate); nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat, gAudioFormatFields.mChannelMask)); nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat, gAudioFormatFields.mEncoding)); env->DeleteLocalRef(jFormat); jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); env->DeleteLocalRef(jRule); jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria, gArrayListMethods.toArray); env->DeleteLocalRef(jRuleCriteria); jint numCriteria = env->GetArrayLength(jCriteria); if (numCriteria > MAX_CRITERIA_PER_MIX) { numCriteria = MAX_CRITERIA_PER_MIX; } for (jint i = 0; i < numCriteria; i++) { AttributeMatchCriterion nCriterion; jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule); jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr); if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE || nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes, gAudioAttributesFields.mUsage); } else { nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes, gAudioAttributesFields.mSource); } env->DeleteLocalRef(jAttributes); nAudioMix->mCriteria.add(nCriterion); env->DeleteLocalRef(jCriterion); } env->DeleteLocalRef(jCriteria); return (jint)AUDIO_JAVA_SUCCESS; } static jint android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz, jobject jMixesList, jboolean registration) { ALOGV("registerPolicyMixes"); if (jMixesList == NULL) { return (jint)AUDIO_JAVA_BAD_VALUE; } if (!env->IsInstanceOf(jMixesList, gArrayListClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList, gArrayListMethods.toArray); jint numMixes = env->GetArrayLength(jMixes); if (numMixes > MAX_MIXES_PER_POLICY) { numMixes = MAX_MIXES_PER_POLICY; } status_t status; jint jStatus; jobject jAudioMix = NULL; Vector <AudioMix> mixes; for (jint i = 0; i < numMixes; i++) { jAudioMix = env->GetObjectArrayElement(jMixes, i); if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) { jStatus = (jint)AUDIO_JAVA_BAD_VALUE; goto exit; } AudioMix mix; jStatus = convertAudioMixToNative(env, &mix, jAudioMix); env->DeleteLocalRef(jAudioMix); jAudioMix = NULL; if (jStatus != AUDIO_JAVA_SUCCESS) { goto exit; } mixes.add(mix); } ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration); status = AudioSystem::registerPolicyMixes(mixes, registration); ALOGV("AudioSystem::registerPolicyMixes() returned %d", status); jStatus = nativeToJavaStatus(status); if (jStatus != AUDIO_JAVA_SUCCESS) { goto exit; } exit: if (jAudioMix != NULL) { env->DeleteLocalRef(jAudioMix); } return jStatus; } // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -1363,6 +1523,9 @@ static JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_setAudioPortConfig}, {"getAudioHwSyncForSession", "(I)I", (void *)android_media_AudioSystem_getAudioHwSyncForSession}, {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", (void *)android_media_AudioSystem_registerPolicyMixes}, }; Loading @@ -1381,6 +1544,7 @@ int register_android_media_AudioSystem(JNIEnv *env) jclass arrayListClass = env->FindClass("java/util/ArrayList"); gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass); gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); gArrayListMethods.toArray = env->GetMethodID(arrayListClass, "toArray", "()[Ljava/lang/Object;"); jclass audioHandleClass = env->FindClass("android/media/AudioHandle"); gAudioHandleClass = (jclass) env->NewGlobalRef(audioHandleClass); Loading Loading @@ -1462,6 +1626,41 @@ int register_android_media_AudioSystem(JNIEnv *env) "(Ljava/lang/Object;IIILjava/lang/Object;)V"); jclass audioMixClass = env->FindClass("android/media/audiopolicy/AudioMix"); gAudioMixClass = (jclass) env->NewGlobalRef(audioMixClass); gAudioMixFields.mRule = env->GetFieldID(audioMixClass, "mRule", "Landroid/media/audiopolicy/AudioMixingRule;"); gAudioMixFields.mFormat = env->GetFieldID(audioMixClass, "mFormat", "Landroid/media/AudioFormat;"); gAudioMixFields.mRouteFlags = env->GetFieldID(audioMixClass, "mRouteFlags", "I"); gAudioMixFields.mRegistrationId = env->GetFieldID(audioMixClass, "mRegistrationId", "Ljava/lang/String;"); gAudioMixFields.mMixType = env->GetFieldID(audioMixClass, "mMixType", "I"); jclass audioFormatClass = env->FindClass("android/media/AudioFormat"); gAudioFormatClass = (jclass) env->NewGlobalRef(audioFormatClass); gAudioFormatFields.mEncoding = env->GetFieldID(audioFormatClass, "mEncoding", "I"); gAudioFormatFields.mSampleRate = env->GetFieldID(audioFormatClass, "mSampleRate", "I"); gAudioFormatFields.mChannelMask = env->GetFieldID(audioFormatClass, "mChannelMask", "I"); jclass audioMixingRuleClass = env->FindClass("android/media/audiopolicy/AudioMixingRule"); gAudioMixingRuleClass = (jclass) env->NewGlobalRef(audioMixingRuleClass); gAudioMixingRuleFields.mCriteria = env->GetFieldID(audioMixingRuleClass, "mCriteria", "Ljava/util/ArrayList;"); jclass attributeMatchCriterionClass = env->FindClass("android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion"); gAttributeMatchCriterionClass = (jclass) env->NewGlobalRef(attributeMatchCriterionClass); gAttributeMatchCriterionFields.mAttr = env->GetFieldID(attributeMatchCriterionClass, "mAttr", "Landroid/media/AudioAttributes;"); gAttributeMatchCriterionFields.mRule = env->GetFieldID(attributeMatchCriterionClass, "mRule", "I"); jclass audioAttributesClass = env->FindClass("android/media/AudioAttributes"); gAudioAttributesClass = (jclass) env->NewGlobalRef(audioAttributesClass); gAudioAttributesFields.mUsage = env->GetFieldID(audioAttributesClass, "mUsage", "I"); gAudioAttributesFields.mSource = env->GetFieldID(audioAttributesClass, "mSource", "I"); AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback); int status = AndroidRuntime::registerNativeMethods(env, Loading media/java/android/media/AudioService.java +11 −16 Original line number Diff line number Diff line Loading @@ -4299,6 +4299,13 @@ public class AudioService extends IAudioService.Stub { } } } synchronized (mAudioPolicies) { for(AudioPolicyProxy policy : mAudioPolicies.values()) { policy.connectMixes(); } } // indicate the end of reconfiguration phase to audio HAL AudioSystem.setParameters("restarting=false"); break; Loading Loading @@ -5939,7 +5946,7 @@ public class AudioService extends IAudioService.Stub { if (mHasFocusListener) { mMediaFocusControl.addFocusFollower(mPolicyToken); } updateMixes(AudioSystem.DEVICE_STATE_AVAILABLE); connectMixes(); } public void binderDied() { Loading @@ -5961,23 +5968,11 @@ public class AudioService extends IAudioService.Stub { if (mHasFocusListener) { mMediaFocusControl.removeFocusFollower(mPolicyToken); } updateMixes(AudioSystem.DEVICE_STATE_UNAVAILABLE); AudioSystem.registerPolicyMixes(mMixes, false); } void updateMixes(int connectionState) { for (AudioMix mix : mMixes) { // TODO implement sending the mix attribute matching info to native audio policy if (DEBUG_AP) { Log.v(TAG, "AudioPolicyProxy mix new connection state=" + connectionState + " addr=" + mix.getRegistration()); } AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, connectionState, mix.getRegistration()); AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, connectionState, mix.getRegistration()); } void connectMixes() { AudioSystem.registerPolicyMixes(mMixes, true); } }; Loading media/java/android/media/AudioSystem.java +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.media; import android.media.audiopolicy.AudioMix; import java.util.ArrayList; /* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET Loading Loading @@ -566,5 +567,7 @@ public class AudioSystem public static final int AUDIO_HW_SYNC_INVALID = 0; public static native int getAudioHwSyncForSession(int sessionId); public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register); } Loading
core/jni/android_media_AudioSystem.cpp +199 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <android_runtime/AndroidRuntime.h> #include <media/AudioSystem.h> #include <media/AudioPolicy.h> #include <system/audio.h> #include <system/audio_policy.h> Loading @@ -40,6 +41,7 @@ static const char* const kClassPathName = "android/media/AudioSystem"; static jclass gArrayListClass; static struct { jmethodID add; jmethodID toArray; } gArrayListMethods; static jclass gAudioHandleClass; Loading Loading @@ -102,6 +104,42 @@ static struct { // other fields unused by JNI } gAudioPatchFields; static jclass gAudioMixClass; static struct { jfieldID mRule; jfieldID mFormat; jfieldID mRouteFlags; jfieldID mRegistrationId; jfieldID mMixType; } gAudioMixFields; static jclass gAudioFormatClass; static struct { jfieldID mEncoding; jfieldID mSampleRate; jfieldID mChannelMask; // other fields unused by JNI } gAudioFormatFields; static jclass gAudioMixingRuleClass; static struct { jfieldID mCriteria; // other fields unused by JNI } gAudioMixingRuleFields; static jclass gAttributeMatchCriterionClass; static struct { jfieldID mAttr; jfieldID mRule; } gAttributeMatchCriterionFields; static jclass gAudioAttributesClass; static struct { jfieldID mUsage; jfieldID mSource; } gAudioAttributesFields; static const char* const kEventHandlerClassPathName = "android/media/AudioPortEventHandler"; static jmethodID gPostEventFromNative; Loading Loading @@ -1322,6 +1360,128 @@ android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, ji return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId); } static jint convertAudioMixToNative(JNIEnv *env, AudioMix *nAudioMix, const jobject jAudioMix) { nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType); nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags); jstring jRegistrationId = (jstring)env->GetObjectField(jAudioMix, gAudioMixFields.mRegistrationId); const char *nRegistrationId = env->GetStringUTFChars(jRegistrationId, NULL); nAudioMix->mRegistrationId = String8(nRegistrationId); env->ReleaseStringUTFChars(jRegistrationId, nRegistrationId); env->DeleteLocalRef(jRegistrationId); jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat); nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat, gAudioFormatFields.mSampleRate); nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat, gAudioFormatFields.mChannelMask)); nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat, gAudioFormatFields.mEncoding)); env->DeleteLocalRef(jFormat); jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); env->DeleteLocalRef(jRule); jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria, gArrayListMethods.toArray); env->DeleteLocalRef(jRuleCriteria); jint numCriteria = env->GetArrayLength(jCriteria); if (numCriteria > MAX_CRITERIA_PER_MIX) { numCriteria = MAX_CRITERIA_PER_MIX; } for (jint i = 0; i < numCriteria; i++) { AttributeMatchCriterion nCriterion; jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule); jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr); if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE || nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes, gAudioAttributesFields.mUsage); } else { nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes, gAudioAttributesFields.mSource); } env->DeleteLocalRef(jAttributes); nAudioMix->mCriteria.add(nCriterion); env->DeleteLocalRef(jCriterion); } env->DeleteLocalRef(jCriteria); return (jint)AUDIO_JAVA_SUCCESS; } static jint android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz, jobject jMixesList, jboolean registration) { ALOGV("registerPolicyMixes"); if (jMixesList == NULL) { return (jint)AUDIO_JAVA_BAD_VALUE; } if (!env->IsInstanceOf(jMixesList, gArrayListClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList, gArrayListMethods.toArray); jint numMixes = env->GetArrayLength(jMixes); if (numMixes > MAX_MIXES_PER_POLICY) { numMixes = MAX_MIXES_PER_POLICY; } status_t status; jint jStatus; jobject jAudioMix = NULL; Vector <AudioMix> mixes; for (jint i = 0; i < numMixes; i++) { jAudioMix = env->GetObjectArrayElement(jMixes, i); if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) { jStatus = (jint)AUDIO_JAVA_BAD_VALUE; goto exit; } AudioMix mix; jStatus = convertAudioMixToNative(env, &mix, jAudioMix); env->DeleteLocalRef(jAudioMix); jAudioMix = NULL; if (jStatus != AUDIO_JAVA_SUCCESS) { goto exit; } mixes.add(mix); } ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration); status = AudioSystem::registerPolicyMixes(mixes, registration); ALOGV("AudioSystem::registerPolicyMixes() returned %d", status); jStatus = nativeToJavaStatus(status); if (jStatus != AUDIO_JAVA_SUCCESS) { goto exit; } exit: if (jAudioMix != NULL) { env->DeleteLocalRef(jAudioMix); } return jStatus; } // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -1363,6 +1523,9 @@ static JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_setAudioPortConfig}, {"getAudioHwSyncForSession", "(I)I", (void *)android_media_AudioSystem_getAudioHwSyncForSession}, {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", (void *)android_media_AudioSystem_registerPolicyMixes}, }; Loading @@ -1381,6 +1544,7 @@ int register_android_media_AudioSystem(JNIEnv *env) jclass arrayListClass = env->FindClass("java/util/ArrayList"); gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass); gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); gArrayListMethods.toArray = env->GetMethodID(arrayListClass, "toArray", "()[Ljava/lang/Object;"); jclass audioHandleClass = env->FindClass("android/media/AudioHandle"); gAudioHandleClass = (jclass) env->NewGlobalRef(audioHandleClass); Loading Loading @@ -1462,6 +1626,41 @@ int register_android_media_AudioSystem(JNIEnv *env) "(Ljava/lang/Object;IIILjava/lang/Object;)V"); jclass audioMixClass = env->FindClass("android/media/audiopolicy/AudioMix"); gAudioMixClass = (jclass) env->NewGlobalRef(audioMixClass); gAudioMixFields.mRule = env->GetFieldID(audioMixClass, "mRule", "Landroid/media/audiopolicy/AudioMixingRule;"); gAudioMixFields.mFormat = env->GetFieldID(audioMixClass, "mFormat", "Landroid/media/AudioFormat;"); gAudioMixFields.mRouteFlags = env->GetFieldID(audioMixClass, "mRouteFlags", "I"); gAudioMixFields.mRegistrationId = env->GetFieldID(audioMixClass, "mRegistrationId", "Ljava/lang/String;"); gAudioMixFields.mMixType = env->GetFieldID(audioMixClass, "mMixType", "I"); jclass audioFormatClass = env->FindClass("android/media/AudioFormat"); gAudioFormatClass = (jclass) env->NewGlobalRef(audioFormatClass); gAudioFormatFields.mEncoding = env->GetFieldID(audioFormatClass, "mEncoding", "I"); gAudioFormatFields.mSampleRate = env->GetFieldID(audioFormatClass, "mSampleRate", "I"); gAudioFormatFields.mChannelMask = env->GetFieldID(audioFormatClass, "mChannelMask", "I"); jclass audioMixingRuleClass = env->FindClass("android/media/audiopolicy/AudioMixingRule"); gAudioMixingRuleClass = (jclass) env->NewGlobalRef(audioMixingRuleClass); gAudioMixingRuleFields.mCriteria = env->GetFieldID(audioMixingRuleClass, "mCriteria", "Ljava/util/ArrayList;"); jclass attributeMatchCriterionClass = env->FindClass("android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion"); gAttributeMatchCriterionClass = (jclass) env->NewGlobalRef(attributeMatchCriterionClass); gAttributeMatchCriterionFields.mAttr = env->GetFieldID(attributeMatchCriterionClass, "mAttr", "Landroid/media/AudioAttributes;"); gAttributeMatchCriterionFields.mRule = env->GetFieldID(attributeMatchCriterionClass, "mRule", "I"); jclass audioAttributesClass = env->FindClass("android/media/AudioAttributes"); gAudioAttributesClass = (jclass) env->NewGlobalRef(audioAttributesClass); gAudioAttributesFields.mUsage = env->GetFieldID(audioAttributesClass, "mUsage", "I"); gAudioAttributesFields.mSource = env->GetFieldID(audioAttributesClass, "mSource", "I"); AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback); int status = AndroidRuntime::registerNativeMethods(env, Loading
media/java/android/media/AudioService.java +11 −16 Original line number Diff line number Diff line Loading @@ -4299,6 +4299,13 @@ public class AudioService extends IAudioService.Stub { } } } synchronized (mAudioPolicies) { for(AudioPolicyProxy policy : mAudioPolicies.values()) { policy.connectMixes(); } } // indicate the end of reconfiguration phase to audio HAL AudioSystem.setParameters("restarting=false"); break; Loading Loading @@ -5939,7 +5946,7 @@ public class AudioService extends IAudioService.Stub { if (mHasFocusListener) { mMediaFocusControl.addFocusFollower(mPolicyToken); } updateMixes(AudioSystem.DEVICE_STATE_AVAILABLE); connectMixes(); } public void binderDied() { Loading @@ -5961,23 +5968,11 @@ public class AudioService extends IAudioService.Stub { if (mHasFocusListener) { mMediaFocusControl.removeFocusFollower(mPolicyToken); } updateMixes(AudioSystem.DEVICE_STATE_UNAVAILABLE); AudioSystem.registerPolicyMixes(mMixes, false); } void updateMixes(int connectionState) { for (AudioMix mix : mMixes) { // TODO implement sending the mix attribute matching info to native audio policy if (DEBUG_AP) { Log.v(TAG, "AudioPolicyProxy mix new connection state=" + connectionState + " addr=" + mix.getRegistration()); } AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, connectionState, mix.getRegistration()); AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, connectionState, mix.getRegistration()); } void connectMixes() { AudioSystem.registerPolicyMixes(mMixes, true); } }; Loading
media/java/android/media/AudioSystem.java +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.media; import android.media.audiopolicy.AudioMix; import java.util.ArrayList; /* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET Loading Loading @@ -566,5 +567,7 @@ public class AudioSystem public static final int AUDIO_HW_SYNC_INVALID = 0; public static native int getAudioHwSyncForSession(int sessionId); public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register); }