Loading core/jni/android_media_AudioSystem.cpp +84 −23 Original line number Diff line number Diff line Loading @@ -788,12 +788,8 @@ static jint android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env, j static_cast<audio_devices_t>(device))); } static jint android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jint device) { static jint android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { // read the AudioAttributes values JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique(); jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get()); Loading @@ -801,19 +797,16 @@ android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, return jStatus; } int index; if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, static_cast<audio_devices_t>(device)) != NO_ERROR) { status_t status = AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index); if (status != NO_ERROR) { index = -1; ALOGE("%s AudioSystem::getMinVolumeIndexForAttributes error %d", __func__, status); } return index; } static jint android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { static jint android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { // read the AudioAttributes values JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique(); jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get()); Loading @@ -821,18 +814,16 @@ android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, return jStatus; } int index; if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index) != NO_ERROR) { status_t status = AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index); if (status != NO_ERROR) { index = -1; ALOGE("%s AudioSystem::getMaxVolumeIndexForAttributes error %d", __func__, status); } return index; } static jint android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { static jint android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jint device) { // read the AudioAttributes values JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique(); jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get()); Loading @@ -840,13 +831,71 @@ android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, return jStatus; } int index; if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index) != NO_ERROR) { status_t status = AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, static_cast<audio_devices_t>(device)); if (status != NO_ERROR) { ALOGE("%s AudioSystem::getVolumeIndexForAttributes error %d", __func__, status); index = -1; } return index; } static jint android_media_AudioSystem_setVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint index, jboolean muted, int device) { return (jint)check_AudioSystem_Command( AudioSystem::setVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index, muted, static_cast<audio_devices_t>(device))); } static jint android_media_AudioSystem_getVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint device) { int index; status_t status = AudioSystem::getVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index, static_cast<audio_devices_t>(device)); if (status != NO_ERROR) { ALOGE("%s AudioSystem::getVolumeIndexForGroup error %d", __func__, status); index = -1; } return (jint)index; } static jint android_media_AudioSystem_getMinVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId) { int index; if (AudioSystem::getMinVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index) != NO_ERROR) { index = -1; } return index; } static jint android_media_AudioSystem_setMinVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint index) { return check_AudioSystem_Command( AudioSystem::setMinVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index)); } static jint android_media_AudioSystem_getMaxVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId) { int index; status_t status = AudioSystem::getMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index); if (status != NO_ERROR) { ALOGE("%s AudioSystem::getMaxVolumeIndexForGroup error %d", __func__, status); index = -1; } return index; } static jint android_media_AudioSystem_setMaxVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint index) { return check_AudioSystem_Command( AudioSystem::setMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index)); } static jint android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value) { Loading Loading @@ -3497,6 +3546,18 @@ static const JNINativeMethod gMethods[] = { MAKE_JNI_NATIVE_METHOD("getMaxVolumeIndexForAttributes", "(Landroid/media/AudioAttributes;)I", android_media_AudioSystem_getMaxVolumeIndexForAttributes), MAKE_JNI_NATIVE_METHOD("setVolumeIndexForGroup", "(IIZI)I", android_media_AudioSystem_setVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("getVolumeIndexForGroup", "(II)I", android_media_AudioSystem_getVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("getMinVolumeIndexForGroup", "(I)I", android_media_AudioSystem_getMinVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("setMinVolumeIndexForGroup", "(II)I", android_media_AudioSystem_setMinVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("getMaxVolumeIndexForGroup", "(I)I", android_media_AudioSystem_getMaxVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("setMaxVolumeIndexForGroup", "(II)I", android_media_AudioSystem_setMaxVolumeIndexForGroup), MAKE_AUDIO_SYSTEM_METHOD(setMasterVolume), MAKE_AUDIO_SYSTEM_METHOD(getMasterVolume), MAKE_AUDIO_SYSTEM_METHOD(setMasterMute), Loading media/java/android/media/AudioSystem.java +81 −5 Original line number Diff line number Diff line Loading @@ -1814,11 +1814,13 @@ public class AudioSystem return 0; } /** * @hide * Send the current audio mode to audio policy manager and audio HAL. * * @param state the audio mode * @param uid the UID of the app owning the audio mode * @return command completion status. * * @hide */ public static native int setPhoneState(int state, int uid); /** @hide */ Loading @@ -1839,41 +1841,115 @@ public class AudioSystem int device); /** @hide */ public static native int getStreamVolumeIndex(int stream, int device); /** * @hide * set a volume for the given {@link AudioAttributes} and for all other stream that belong to * the same volume group. * * @param attributes the {@link AudioAttributes} to be considered * @param index to be applied * @param device the volume device to be considered * @return command completion status. * * @hide */ public static native int setVolumeIndexForAttributes(@NonNull AudioAttributes attributes, int index, boolean muted, int device); /** * @hide * get the volume index for the given {@link AudioAttributes}. * * @param attributes the {@link AudioAttributes} to be considered * @param device the volume device to be considered * @return volume index for the given {@link AudioAttributes} and volume device. * * @hide */ public static native int getVolumeIndexForAttributes(@NonNull AudioAttributes attributes, int device); /** * @hide * get the minimum volume index for the given {@link AudioAttributes}. * * @param attributes the {@link AudioAttributes} to be considered * @return minimum volume index for the given {@link AudioAttributes}. * * @hide */ public static native int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attributes); /** * @hide * get the maximum volume index for the given {@link AudioAttributes}. * * @param attributes the {@link AudioAttributes} to be considered * @return maximum volume index for the given {@link AudioAttributes}. * * @hide */ public static native int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attributes); /** * Set a volume for the given group id and device type. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @param index to be applied * @param muted state of the group * @param device the volume device to be considered * @return command completion status. * * @hide */ public static native int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device); /** * Get the volume index for the given group id and device. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @param device the volume device to be considered * @return volume index for the given volume group and volume device. * * @hide */ public static native int getVolumeIndexForGroup(int groupId, int device); /** * Get the minimum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @return minimum volume index for the given volume group. * * @hide */ public static native int getMinVolumeIndexForGroup(int groupId); /** * Set the minimum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be set * @return minimum volume index for the given volume group. * * @hide */ public static native int setMinVolumeIndexForGroup(int groupId, int index); /** * Get the maximum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @return maximum volume index for the given volume group. * * @hide */ public static native int getMaxVolumeIndexForGroup(int groupId); /** * Set the maximum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be set * @return maximum volume index for the given volume group. * * @hide */ public static native int setMaxVolumeIndexForGroup(int groupId, int index); /** @hide */ public static native int setMasterVolume(float value); /** @hide */ Loading services/core/java/com/android/server/audio/AudioService.java +104 −21 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import static android.media.audio.Flags.roForegroundAudioControl; import static android.media.audio.Flags.scoManagedByAudio; import static android.media.audio.Flags.unifyAbsoluteVolumeManagement; import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; import static android.media.audiopolicy.Flags.volumeGroupManagementUpdate; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; Loading Loading @@ -1410,14 +1411,25 @@ public class AudioService extends IAudioService.Stub int numStreamTypes = AudioSystem.getNumStreamTypes(); for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { int maxVolume = -1; int minVolume = -1; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(streamType); if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { maxVolume = AudioSystem.getMaxVolumeIndexForGroup(groupId); minVolume = AudioSystem.getMinVolumeIndexForGroup(groupId); } } else { AudioAttributes attr = AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( streamType); int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); } if (maxVolume != -1) { MAX_STREAM_VOLUME[streamType] = maxVolume; } int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); if (minVolume != -1) { MIN_STREAM_VOLUME[streamType] = minVolume; } Loading Loading @@ -2283,11 +2295,21 @@ public class AudioService extends IAudioService.Stub if (streamState == null) { continue; } final int res = AudioSystem.initStreamVolume( streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]); if (res != AudioSystem.AUDIO_STATUS_OK) { status = res; Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); int result; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(streamType); result = initMinMaxForVolumeGroup(groupId, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType], /* logEvent= */ false); } else { result = AudioSystem.initStreamVolume(streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]); if (result != AudioSystem.AUDIO_STATUS_OK) { Log.e(TAG, "Failed to initStreamVolume (" + result + ") for stream " + streamType); } } if (result != AudioSystem.AUDIO_STATUS_OK) { status = result; // stream volume initialization failed, no need to try the others, it will be // attempted again when MSG_REINIT_VOLUMES is handled break; Loading Loading @@ -2341,10 +2363,23 @@ public class AudioService extends IAudioService.Stub AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, AudioSystem.STREAM_ACCESSIBILITY }; for (int streamType : basicStreams) { int maxVolumeIndex; int minVolumeIndex; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(streamType); if (groupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { success = false; break; } maxVolumeIndex = AudioSystem.getMaxVolumeIndexForGroup(groupId); minVolumeIndex = AudioSystem.getMinVolumeIndexForGroup(groupId); } else { final AudioAttributes aa = new AudioAttributes.Builder() .setInternalLegacyStreamType(streamType).build(); if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { maxVolumeIndex = AudioSystem.getMaxVolumeIndexForAttributes(aa); minVolumeIndex = AudioSystem.getMinVolumeIndexForAttributes(aa); } if (maxVolumeIndex < 0 || minVolumeIndex < 0) { success = false; break; } Loading Loading @@ -8859,6 +8894,35 @@ public class AudioService extends IAudioService.Stub attributes, /* fallbackOnDefault= */ false); } private static int initMinMaxForVolumeGroup(int groupId, int minVol, int maxVol, boolean logEvent) { int status = AudioSystem.setMinVolumeIndexForGroup(groupId, minVol); if (status != AudioSystem.AUDIO_STATUS_OK) { if (logEvent) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed setMinVolumeIndexForGroup with status=" + status) .printSlog(ALOGE, TAG)); } else { Log.e(TAG, "Failed to setMinVolumeIndexForGroup (" + status + ") for group " + groupId); } return status; } status = AudioSystem.setMaxVolumeIndexForGroup(groupId, maxVol); if (status != AudioSystem.AUDIO_STATUS_OK) { if (logEvent) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed setMaxVolumeIndexForGroup with status=" + status) .printSlog(ALOGE, TAG)); } else { Log.e(TAG, "Failed to setMaxVolumeIndexForGroup (" + status + ") for group " + groupId); } } return status; } // NOTE: Locking order for synchronized objects related to volume management: // 1 mSettingsLock // 2 mVolumeStateLock Loading Loading @@ -8913,8 +8977,13 @@ public class AudioService extends IAudioService.Stub mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; } } else if (!avg.getAudioAttributes().isEmpty()) { if (volumeGroupManagementUpdate()) { mIndexMin = AudioSystem.getMinVolumeIndexForGroup(mAudioVolumeGroup.getId()); mIndexMax = AudioSystem.getMaxVolumeIndexForGroup(mAudioVolumeGroup.getId()); } else { mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); } } else { throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() + " has neither valid attributes nor valid stream types assigned"); Loading Loading @@ -9110,8 +9179,13 @@ public class AudioService extends IAudioService.Stub } // Set the volume index if (volumeGroupManagementUpdate()) { mAudioSystem.setVolumeIndexForGroup(mAudioVolumeGroup.getId(), index, muted, device); } else { mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, muted, device); } } @GuardedBy("AudioService.this.mVolumeStateLock") private int getIndex(int device) { Loading Loading @@ -9531,15 +9605,24 @@ public class AudioService extends IAudioService.Stub AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); } final int status = AudioSystem.initStreamVolume( mStreamType, indexMinVolCurve, indexMaxVolCurve); int status; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(mStreamType); status = initMinMaxForVolumeGroup(groupId, indexMinVolCurve, indexMaxVolCurve, /* logEvent= */ true); } else { status = AudioSystem.initStreamVolume(mStreamType, indexMinVolCurve, indexMaxVolCurve); if (status != AudioSystem.AUDIO_STATUS_OK) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG)); } } sVolumeLogger.enqueue(new EventLogger.StringEvent( "updateIndexFactors() stream:" + mStreamType + " index min/max:" + mIndexMin / 10 + "/" + mIndexMax / 10 + " indexStepFactor:" + mIndexStepFactor).printSlog(ALOGI, TAG)); if (status != AudioSystem.AUDIO_STATUS_OK) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG)); sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, "updateIndexFactors()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); } Loading services/core/java/com/android/server/audio/AudioSystemAdapter.java +30 −0 Original line number Diff line number Diff line Loading @@ -558,6 +558,36 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, return AudioSystem.setVolumeIndexForAttributes(attributes, index, muted, device); } /** Same as {@link AudioSystem#setVolumeIndexForGroup(int, int, boolean, int)} */ public int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device) { return AudioSystem.setVolumeIndexForGroup(groupId, index, muted, device); } /** Same as {@link AudioSystem#getVolumeIndexForGroup(int, int)} */ public int getVolumeIndexForGroup(int groupId, int device) { return AudioSystem.getVolumeIndexForGroup(groupId, device); } /** Same as {@link AudioSystem#getMinVolumeIndexForGroup(int)} */ public int getMinVolumeIndexForGroup(int groupId) { return AudioSystem.getMinVolumeIndexForGroup(groupId); } /** Same as {@link AudioSystem#setMinVolumeIndexForGroup(int, int)} */ public int setMinVolumeIndexForGroup(int groupId, int index) { return AudioSystem.setMinVolumeIndexForGroup(groupId, index); } /** Same as {@link AudioSystem#getMaxVolumeIndexForGroup(int)} */ public int getMaxVolumeIndexForGroup(int groupId) { return AudioSystem.getMaxVolumeIndexForGroup(groupId); } /** Same as {@link AudioSystem#setMaxVolumeIndexForGroup(int, int)} */ public int setMaxVolumeIndexForGroup(int groupId, int index) { return AudioSystem.setMaxVolumeIndexForGroup(groupId, index); } /** * Same as {@link AudioSystem#setPhoneState(int, int)} * @param state Loading services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java +30 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,36 @@ public class NoOpAudioSystemAdapter extends AudioSystemAdapter { return AudioSystem.AUDIO_STATUS_OK; } @Override public int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int getVolumeIndexForGroup(int groupId, int device) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int getMinVolumeIndexForGroup(int groupId) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int setMinVolumeIndexForGroup(int groupId, int index) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int getMaxVolumeIndexForGroup(int groupId) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int setMaxVolumeIndexForGroup(int groupId, int index) { return AudioSystem.AUDIO_STATUS_OK; } @Override @NonNull public ArrayList<AudioDeviceAttributes> getDevicesForAttributes( Loading Loading
core/jni/android_media_AudioSystem.cpp +84 −23 Original line number Diff line number Diff line Loading @@ -788,12 +788,8 @@ static jint android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env, j static_cast<audio_devices_t>(device))); } static jint android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jint device) { static jint android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { // read the AudioAttributes values JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique(); jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get()); Loading @@ -801,19 +797,16 @@ android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, return jStatus; } int index; if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, static_cast<audio_devices_t>(device)) != NO_ERROR) { status_t status = AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index); if (status != NO_ERROR) { index = -1; ALOGE("%s AudioSystem::getMinVolumeIndexForAttributes error %d", __func__, status); } return index; } static jint android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { static jint android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { // read the AudioAttributes values JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique(); jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get()); Loading @@ -821,18 +814,16 @@ android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, return jStatus; } int index; if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index) != NO_ERROR) { status_t status = AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index); if (status != NO_ERROR) { index = -1; ALOGE("%s AudioSystem::getMaxVolumeIndexForAttributes error %d", __func__, status); } return index; } static jint android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa) { static jint android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jint device) { // read the AudioAttributes values JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique(); jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get()); Loading @@ -840,13 +831,71 @@ android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, return jStatus; } int index; if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index) != NO_ERROR) { status_t status = AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index, static_cast<audio_devices_t>(device)); if (status != NO_ERROR) { ALOGE("%s AudioSystem::getVolumeIndexForAttributes error %d", __func__, status); index = -1; } return index; } static jint android_media_AudioSystem_setVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint index, jboolean muted, int device) { return (jint)check_AudioSystem_Command( AudioSystem::setVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index, muted, static_cast<audio_devices_t>(device))); } static jint android_media_AudioSystem_getVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint device) { int index; status_t status = AudioSystem::getVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index, static_cast<audio_devices_t>(device)); if (status != NO_ERROR) { ALOGE("%s AudioSystem::getVolumeIndexForGroup error %d", __func__, status); index = -1; } return (jint)index; } static jint android_media_AudioSystem_getMinVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId) { int index; if (AudioSystem::getMinVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index) != NO_ERROR) { index = -1; } return index; } static jint android_media_AudioSystem_setMinVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint index) { return check_AudioSystem_Command( AudioSystem::setMinVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index)); } static jint android_media_AudioSystem_getMaxVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId) { int index; status_t status = AudioSystem::getMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index); if (status != NO_ERROR) { ALOGE("%s AudioSystem::getMaxVolumeIndexForGroup error %d", __func__, status); index = -1; } return index; } static jint android_media_AudioSystem_setMaxVolumeIndexForGroup(JNIEnv *env, jobject thiz, jint groupId, jint index) { return check_AudioSystem_Command( AudioSystem::setMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index)); } static jint android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value) { Loading Loading @@ -3497,6 +3546,18 @@ static const JNINativeMethod gMethods[] = { MAKE_JNI_NATIVE_METHOD("getMaxVolumeIndexForAttributes", "(Landroid/media/AudioAttributes;)I", android_media_AudioSystem_getMaxVolumeIndexForAttributes), MAKE_JNI_NATIVE_METHOD("setVolumeIndexForGroup", "(IIZI)I", android_media_AudioSystem_setVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("getVolumeIndexForGroup", "(II)I", android_media_AudioSystem_getVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("getMinVolumeIndexForGroup", "(I)I", android_media_AudioSystem_getMinVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("setMinVolumeIndexForGroup", "(II)I", android_media_AudioSystem_setMinVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("getMaxVolumeIndexForGroup", "(I)I", android_media_AudioSystem_getMaxVolumeIndexForGroup), MAKE_JNI_NATIVE_METHOD("setMaxVolumeIndexForGroup", "(II)I", android_media_AudioSystem_setMaxVolumeIndexForGroup), MAKE_AUDIO_SYSTEM_METHOD(setMasterVolume), MAKE_AUDIO_SYSTEM_METHOD(getMasterVolume), MAKE_AUDIO_SYSTEM_METHOD(setMasterMute), Loading
media/java/android/media/AudioSystem.java +81 −5 Original line number Diff line number Diff line Loading @@ -1814,11 +1814,13 @@ public class AudioSystem return 0; } /** * @hide * Send the current audio mode to audio policy manager and audio HAL. * * @param state the audio mode * @param uid the UID of the app owning the audio mode * @return command completion status. * * @hide */ public static native int setPhoneState(int state, int uid); /** @hide */ Loading @@ -1839,41 +1841,115 @@ public class AudioSystem int device); /** @hide */ public static native int getStreamVolumeIndex(int stream, int device); /** * @hide * set a volume for the given {@link AudioAttributes} and for all other stream that belong to * the same volume group. * * @param attributes the {@link AudioAttributes} to be considered * @param index to be applied * @param device the volume device to be considered * @return command completion status. * * @hide */ public static native int setVolumeIndexForAttributes(@NonNull AudioAttributes attributes, int index, boolean muted, int device); /** * @hide * get the volume index for the given {@link AudioAttributes}. * * @param attributes the {@link AudioAttributes} to be considered * @param device the volume device to be considered * @return volume index for the given {@link AudioAttributes} and volume device. * * @hide */ public static native int getVolumeIndexForAttributes(@NonNull AudioAttributes attributes, int device); /** * @hide * get the minimum volume index for the given {@link AudioAttributes}. * * @param attributes the {@link AudioAttributes} to be considered * @return minimum volume index for the given {@link AudioAttributes}. * * @hide */ public static native int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attributes); /** * @hide * get the maximum volume index for the given {@link AudioAttributes}. * * @param attributes the {@link AudioAttributes} to be considered * @return maximum volume index for the given {@link AudioAttributes}. * * @hide */ public static native int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attributes); /** * Set a volume for the given group id and device type. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @param index to be applied * @param muted state of the group * @param device the volume device to be considered * @return command completion status. * * @hide */ public static native int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device); /** * Get the volume index for the given group id and device. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @param device the volume device to be considered * @return volume index for the given volume group and volume device. * * @hide */ public static native int getVolumeIndexForGroup(int groupId, int device); /** * Get the minimum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @return minimum volume index for the given volume group. * * @hide */ public static native int getMinVolumeIndexForGroup(int groupId); /** * Set the minimum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be set * @return minimum volume index for the given volume group. * * @hide */ public static native int setMinVolumeIndexForGroup(int groupId, int index); /** * Get the maximum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be considered * @return maximum volume index for the given volume group. * * @hide */ public static native int getMaxVolumeIndexForGroup(int groupId); /** * Set the maximum volume index for the given group id. * * @param groupId the {@link AudioVolumeGroup} id to be set * @return maximum volume index for the given volume group. * * @hide */ public static native int setMaxVolumeIndexForGroup(int groupId, int index); /** @hide */ public static native int setMasterVolume(float value); /** @hide */ Loading
services/core/java/com/android/server/audio/AudioService.java +104 −21 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import static android.media.audio.Flags.roForegroundAudioControl; import static android.media.audio.Flags.scoManagedByAudio; import static android.media.audio.Flags.unifyAbsoluteVolumeManagement; import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; import static android.media.audiopolicy.Flags.volumeGroupManagementUpdate; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; Loading Loading @@ -1410,14 +1411,25 @@ public class AudioService extends IAudioService.Stub int numStreamTypes = AudioSystem.getNumStreamTypes(); for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { int maxVolume = -1; int minVolume = -1; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(streamType); if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { maxVolume = AudioSystem.getMaxVolumeIndexForGroup(groupId); minVolume = AudioSystem.getMinVolumeIndexForGroup(groupId); } } else { AudioAttributes attr = AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( streamType); int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); } if (maxVolume != -1) { MAX_STREAM_VOLUME[streamType] = maxVolume; } int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); if (minVolume != -1) { MIN_STREAM_VOLUME[streamType] = minVolume; } Loading Loading @@ -2283,11 +2295,21 @@ public class AudioService extends IAudioService.Stub if (streamState == null) { continue; } final int res = AudioSystem.initStreamVolume( streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]); if (res != AudioSystem.AUDIO_STATUS_OK) { status = res; Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); int result; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(streamType); result = initMinMaxForVolumeGroup(groupId, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType], /* logEvent= */ false); } else { result = AudioSystem.initStreamVolume(streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]); if (result != AudioSystem.AUDIO_STATUS_OK) { Log.e(TAG, "Failed to initStreamVolume (" + result + ") for stream " + streamType); } } if (result != AudioSystem.AUDIO_STATUS_OK) { status = result; // stream volume initialization failed, no need to try the others, it will be // attempted again when MSG_REINIT_VOLUMES is handled break; Loading Loading @@ -2341,10 +2363,23 @@ public class AudioService extends IAudioService.Stub AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, AudioSystem.STREAM_ACCESSIBILITY }; for (int streamType : basicStreams) { int maxVolumeIndex; int minVolumeIndex; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(streamType); if (groupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { success = false; break; } maxVolumeIndex = AudioSystem.getMaxVolumeIndexForGroup(groupId); minVolumeIndex = AudioSystem.getMinVolumeIndexForGroup(groupId); } else { final AudioAttributes aa = new AudioAttributes.Builder() .setInternalLegacyStreamType(streamType).build(); if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { maxVolumeIndex = AudioSystem.getMaxVolumeIndexForAttributes(aa); minVolumeIndex = AudioSystem.getMinVolumeIndexForAttributes(aa); } if (maxVolumeIndex < 0 || minVolumeIndex < 0) { success = false; break; } Loading Loading @@ -8859,6 +8894,35 @@ public class AudioService extends IAudioService.Stub attributes, /* fallbackOnDefault= */ false); } private static int initMinMaxForVolumeGroup(int groupId, int minVol, int maxVol, boolean logEvent) { int status = AudioSystem.setMinVolumeIndexForGroup(groupId, minVol); if (status != AudioSystem.AUDIO_STATUS_OK) { if (logEvent) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed setMinVolumeIndexForGroup with status=" + status) .printSlog(ALOGE, TAG)); } else { Log.e(TAG, "Failed to setMinVolumeIndexForGroup (" + status + ") for group " + groupId); } return status; } status = AudioSystem.setMaxVolumeIndexForGroup(groupId, maxVol); if (status != AudioSystem.AUDIO_STATUS_OK) { if (logEvent) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed setMaxVolumeIndexForGroup with status=" + status) .printSlog(ALOGE, TAG)); } else { Log.e(TAG, "Failed to setMaxVolumeIndexForGroup (" + status + ") for group " + groupId); } } return status; } // NOTE: Locking order for synchronized objects related to volume management: // 1 mSettingsLock // 2 mVolumeStateLock Loading Loading @@ -8913,8 +8977,13 @@ public class AudioService extends IAudioService.Stub mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; } } else if (!avg.getAudioAttributes().isEmpty()) { if (volumeGroupManagementUpdate()) { mIndexMin = AudioSystem.getMinVolumeIndexForGroup(mAudioVolumeGroup.getId()); mIndexMax = AudioSystem.getMaxVolumeIndexForGroup(mAudioVolumeGroup.getId()); } else { mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); } } else { throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() + " has neither valid attributes nor valid stream types assigned"); Loading Loading @@ -9110,8 +9179,13 @@ public class AudioService extends IAudioService.Stub } // Set the volume index if (volumeGroupManagementUpdate()) { mAudioSystem.setVolumeIndexForGroup(mAudioVolumeGroup.getId(), index, muted, device); } else { mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, muted, device); } } @GuardedBy("AudioService.this.mVolumeStateLock") private int getIndex(int device) { Loading Loading @@ -9531,15 +9605,24 @@ public class AudioService extends IAudioService.Stub AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); } final int status = AudioSystem.initStreamVolume( mStreamType, indexMinVolCurve, indexMaxVolCurve); int status; if (volumeGroupManagementUpdate()) { int groupId = getVolumeGroupForStreamType(mStreamType); status = initMinMaxForVolumeGroup(groupId, indexMinVolCurve, indexMaxVolCurve, /* logEvent= */ true); } else { status = AudioSystem.initStreamVolume(mStreamType, indexMinVolCurve, indexMaxVolCurve); if (status != AudioSystem.AUDIO_STATUS_OK) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG)); } } sVolumeLogger.enqueue(new EventLogger.StringEvent( "updateIndexFactors() stream:" + mStreamType + " index min/max:" + mIndexMin / 10 + "/" + mIndexMax / 10 + " indexStepFactor:" + mIndexStepFactor).printSlog(ALOGI, TAG)); if (status != AudioSystem.AUDIO_STATUS_OK) { sVolumeLogger.enqueue(new EventLogger.StringEvent( "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG)); sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, "updateIndexFactors()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); } Loading
services/core/java/com/android/server/audio/AudioSystemAdapter.java +30 −0 Original line number Diff line number Diff line Loading @@ -558,6 +558,36 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, return AudioSystem.setVolumeIndexForAttributes(attributes, index, muted, device); } /** Same as {@link AudioSystem#setVolumeIndexForGroup(int, int, boolean, int)} */ public int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device) { return AudioSystem.setVolumeIndexForGroup(groupId, index, muted, device); } /** Same as {@link AudioSystem#getVolumeIndexForGroup(int, int)} */ public int getVolumeIndexForGroup(int groupId, int device) { return AudioSystem.getVolumeIndexForGroup(groupId, device); } /** Same as {@link AudioSystem#getMinVolumeIndexForGroup(int)} */ public int getMinVolumeIndexForGroup(int groupId) { return AudioSystem.getMinVolumeIndexForGroup(groupId); } /** Same as {@link AudioSystem#setMinVolumeIndexForGroup(int, int)} */ public int setMinVolumeIndexForGroup(int groupId, int index) { return AudioSystem.setMinVolumeIndexForGroup(groupId, index); } /** Same as {@link AudioSystem#getMaxVolumeIndexForGroup(int)} */ public int getMaxVolumeIndexForGroup(int groupId) { return AudioSystem.getMaxVolumeIndexForGroup(groupId); } /** Same as {@link AudioSystem#setMaxVolumeIndexForGroup(int, int)} */ public int setMaxVolumeIndexForGroup(int groupId, int index) { return AudioSystem.setMaxVolumeIndexForGroup(groupId, index); } /** * Same as {@link AudioSystem#setPhoneState(int, int)} * @param state Loading
services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java +30 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,36 @@ public class NoOpAudioSystemAdapter extends AudioSystemAdapter { return AudioSystem.AUDIO_STATUS_OK; } @Override public int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int getVolumeIndexForGroup(int groupId, int device) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int getMinVolumeIndexForGroup(int groupId) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int setMinVolumeIndexForGroup(int groupId, int index) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int getMaxVolumeIndexForGroup(int groupId) { return AudioSystem.AUDIO_STATUS_OK; } @Override public int setMaxVolumeIndexForGroup(int groupId, int index) { return AudioSystem.AUDIO_STATUS_OK; } @Override @NonNull public ArrayList<AudioDeviceAttributes> getDevicesForAttributes( Loading