Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +18 −15 Original line number Diff line number Diff line Loading @@ -7834,10 +7834,18 @@ sp<IOProfile> AudioPolicyManager::getInputProfile(const sp<DeviceDescriptor> &de float AudioPolicyManager::computeVolume(IVolumeCurves &curves, VolumeSource volumeSource, int index, const DeviceTypeSet& deviceTypes) const DeviceTypeSet& deviceTypes, bool computeInternalInteraction) { float volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(deviceTypes), index); ALOGV("%s volume source %d, index %d, devices %s, compute internal %b ", __func__, volumeSource, index, dumpDeviceTypes(deviceTypes).c_str(), computeInternalInteraction); if (!computeInternalInteraction) { return volumeDb; } // handle the case of accessibility active while a ringtone is playing: if the ringtone is much // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch // exploration of the dialer UI. In this situation, bring the accessibility volume closer to Loading @@ -7847,14 +7855,11 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC, false); const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM, false); const auto a11yVolumeSrc = toVolumeSource(AUDIO_STREAM_ACCESSIBILITY, false); // Verify that the current volume source is not the ringer volume to prevent recursively // calling to compute volume. This could happen in cases where a11y and ringer sounds belong // to the same volume group. if (volumeSource != ringVolumeSrc && volumeSource == a11yVolumeSrc && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) && if (AUDIO_MODE_RINGTONE == mEngine->getPhoneState() && mOutputs.isActive(ringVolumeSrc, 0)) { auto &ringCurves = getVolumeCurves(AUDIO_STREAM_RING); const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, deviceTypes); const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, deviceTypes, /* computeInternalInteraction= */ false); return ringVolumeDb - 4 > volumeDb ? ringVolumeDb - 4 : volumeDb; } Loading @@ -7871,7 +7876,8 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, auto &voiceCurves = getVolumeCurves(callVolumeSrc); int voiceVolumeIndex = voiceCurves.getVolumeIndex(deviceTypes); const float maxVoiceVolDb = computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, deviceTypes) computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, deviceTypes, /* computeInternalInteraction= */ false) + IN_CALL_EARPIECE_HEADROOM_DB; // FIXME: Workaround for call screening applications until a proper audio mode is defined // to support this scenario : Exempt the RING stream from the audio cap if the audio was Loading Loading @@ -7913,12 +7919,8 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, // when the phone is ringing we must consider that music could have been paused just before // by the music application and behave as if music was active if the last music track was // just stopped // Verify that the current volume source is not the music volume to prevent recursively // calling to compute volume. This could happen in cases where music and // (alarm, ring, notification, system, etc.) sounds belong to the same volume group. if (volumeSource != musicVolumeSrc && (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || mLimitRingtoneVolume)) { if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || mLimitRingtoneVolume) { volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB; DeviceTypeSet musicDevice = mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA), Loading @@ -7927,7 +7929,8 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, float musicVolDb = computeVolume(musicCurves, musicVolumeSrc, musicCurves.getVolumeIndex(musicDevice), musicDevice); musicDevice, /* computeInternalInteraction= */ false); float minVolDb = (musicVolDb > SONIFICATION_HEADSET_VOLUME_MIN_DB) ? musicVolDb : SONIFICATION_HEADSET_VOLUME_MIN_DB; if (volumeDb > minVolDb) { Loading services/audiopolicy/managerdefault/AudioPolicyManager.h +30 −6 Original line number Diff line number Diff line Loading @@ -565,12 +565,36 @@ protected: status_t resetInputDevice(audio_io_handle_t input, audio_patch_handle_t *patchHandle = NULL); // compute the actual volume for a given stream according to the requested index and a particular // device virtual float computeVolume(IVolumeCurves &curves, VolumeSource volumeSource, int index, const DeviceTypeSet& deviceTypes); /** * Compute volume in DB that should be applied for a volume source and device types for a * particular volume index. * * <p><b>Note:</b>Internally the compute method recursively calls itself to accurately * determine the volume given the currently active sources and devices. Some of the * interaction that require recursive computation are: * <ul> * <li>Match accessibility volume if ringtone volume is much louder</li> * <li>If voice call is active cap other volumes (except ringtone and accessibility)</li> * <li>Attenuate notification if headset is connected to prevent burst in user's ear</li> * <li>Attenuate ringtone if headset is connected and music is not playing and speaker is * part of the devices to prevent burst in user's ear</li> * <li>Limit music volume if headset is connected and notification is also active</li> * </ul> * * @param curves volume curves to use for calculating volume value given the index * @param volumeSource source (use case) of the volume * @param index index to match in the volume curves for the calculation * @param deviceTypes devices that should be considered in the volume curves for the * calculation * @param computeInternalInteraction boolean indicating whether recursive volume computation * should continue within the volume computation. Defaults to {@code true} so the * volume interactions can be computed. Calls within the method should always set the * the value to {@code false} to prevent infinite recursion. * @return computed volume in DB */ virtual float computeVolume(IVolumeCurves &curves, VolumeSource volumeSource, int index, const DeviceTypeSet& deviceTypes, bool computeInternalInteraction = true); // rescale volume index from srcStream within range of dstStream int rescaleVolumeIndex(int srcIndex, Loading Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +18 −15 Original line number Diff line number Diff line Loading @@ -7834,10 +7834,18 @@ sp<IOProfile> AudioPolicyManager::getInputProfile(const sp<DeviceDescriptor> &de float AudioPolicyManager::computeVolume(IVolumeCurves &curves, VolumeSource volumeSource, int index, const DeviceTypeSet& deviceTypes) const DeviceTypeSet& deviceTypes, bool computeInternalInteraction) { float volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(deviceTypes), index); ALOGV("%s volume source %d, index %d, devices %s, compute internal %b ", __func__, volumeSource, index, dumpDeviceTypes(deviceTypes).c_str(), computeInternalInteraction); if (!computeInternalInteraction) { return volumeDb; } // handle the case of accessibility active while a ringtone is playing: if the ringtone is much // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch // exploration of the dialer UI. In this situation, bring the accessibility volume closer to Loading @@ -7847,14 +7855,11 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC, false); const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM, false); const auto a11yVolumeSrc = toVolumeSource(AUDIO_STREAM_ACCESSIBILITY, false); // Verify that the current volume source is not the ringer volume to prevent recursively // calling to compute volume. This could happen in cases where a11y and ringer sounds belong // to the same volume group. if (volumeSource != ringVolumeSrc && volumeSource == a11yVolumeSrc && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) && if (AUDIO_MODE_RINGTONE == mEngine->getPhoneState() && mOutputs.isActive(ringVolumeSrc, 0)) { auto &ringCurves = getVolumeCurves(AUDIO_STREAM_RING); const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, deviceTypes); const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, deviceTypes, /* computeInternalInteraction= */ false); return ringVolumeDb - 4 > volumeDb ? ringVolumeDb - 4 : volumeDb; } Loading @@ -7871,7 +7876,8 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, auto &voiceCurves = getVolumeCurves(callVolumeSrc); int voiceVolumeIndex = voiceCurves.getVolumeIndex(deviceTypes); const float maxVoiceVolDb = computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, deviceTypes) computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, deviceTypes, /* computeInternalInteraction= */ false) + IN_CALL_EARPIECE_HEADROOM_DB; // FIXME: Workaround for call screening applications until a proper audio mode is defined // to support this scenario : Exempt the RING stream from the audio cap if the audio was Loading Loading @@ -7913,12 +7919,8 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, // when the phone is ringing we must consider that music could have been paused just before // by the music application and behave as if music was active if the last music track was // just stopped // Verify that the current volume source is not the music volume to prevent recursively // calling to compute volume. This could happen in cases where music and // (alarm, ring, notification, system, etc.) sounds belong to the same volume group. if (volumeSource != musicVolumeSrc && (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || mLimitRingtoneVolume)) { if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || mLimitRingtoneVolume) { volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB; DeviceTypeSet musicDevice = mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA), Loading @@ -7927,7 +7929,8 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves, float musicVolDb = computeVolume(musicCurves, musicVolumeSrc, musicCurves.getVolumeIndex(musicDevice), musicDevice); musicDevice, /* computeInternalInteraction= */ false); float minVolDb = (musicVolDb > SONIFICATION_HEADSET_VOLUME_MIN_DB) ? musicVolDb : SONIFICATION_HEADSET_VOLUME_MIN_DB; if (volumeDb > minVolDb) { Loading
services/audiopolicy/managerdefault/AudioPolicyManager.h +30 −6 Original line number Diff line number Diff line Loading @@ -565,12 +565,36 @@ protected: status_t resetInputDevice(audio_io_handle_t input, audio_patch_handle_t *patchHandle = NULL); // compute the actual volume for a given stream according to the requested index and a particular // device virtual float computeVolume(IVolumeCurves &curves, VolumeSource volumeSource, int index, const DeviceTypeSet& deviceTypes); /** * Compute volume in DB that should be applied for a volume source and device types for a * particular volume index. * * <p><b>Note:</b>Internally the compute method recursively calls itself to accurately * determine the volume given the currently active sources and devices. Some of the * interaction that require recursive computation are: * <ul> * <li>Match accessibility volume if ringtone volume is much louder</li> * <li>If voice call is active cap other volumes (except ringtone and accessibility)</li> * <li>Attenuate notification if headset is connected to prevent burst in user's ear</li> * <li>Attenuate ringtone if headset is connected and music is not playing and speaker is * part of the devices to prevent burst in user's ear</li> * <li>Limit music volume if headset is connected and notification is also active</li> * </ul> * * @param curves volume curves to use for calculating volume value given the index * @param volumeSource source (use case) of the volume * @param index index to match in the volume curves for the calculation * @param deviceTypes devices that should be considered in the volume curves for the * calculation * @param computeInternalInteraction boolean indicating whether recursive volume computation * should continue within the volume computation. Defaults to {@code true} so the * volume interactions can be computed. Calls within the method should always set the * the value to {@code false} to prevent infinite recursion. * @return computed volume in DB */ virtual float computeVolume(IVolumeCurves &curves, VolumeSource volumeSource, int index, const DeviceTypeSet& deviceTypes, bool computeInternalInteraction = true); // rescale volume index from srcStream within range of dstStream int rescaleVolumeIndex(int srcIndex, Loading