AbsVol: boost attenuation of the non driving abs vol streams
In order to avoid the double attenuation subtract when playing on
absolute volume devices the attenuation which is already applied by the
absolute volume controller.
Flag: com.android.media.audio.abs_volume_index_fix
Test: logs manual - adb shell setprop log.tag.APM_AudioPolicyManager V
Bug: 340693050
Change-Id: I0c38981565e8d14bf13ac3cd7e26b0edd5e111f6
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index de6eed8..e91e2a3 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -180,10 +180,16 @@
// volume control functions
//
+ // notifies the audio policy manager that the absolute volume mode is enabled/disabled on
+ // the passed device. Also specifies the stream that is controlling the absolute volume.
+ virtual status_t setDeviceAbsoluteVolumeEnabled(audio_devices_t device,
+ const char *address,
+ bool enabled,
+ audio_stream_type_t streamToDriveAbs) = 0;
// initialises stream volume conversion parameters by specifying volume index range.
virtual void initStreamVolume(audio_stream_type_t stream,
- int indexMin,
- int indexMax) = 0;
+ int indexMin,
+ int indexMax) = 0;
// sets the new stream volume at a level corresponding to the supplied index for the
// supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME means
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 87b6c3d..7ec5f48 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3374,6 +3374,27 @@
}
}
+status_t AudioPolicyManager::setDeviceAbsoluteVolumeEnabled(audio_devices_t deviceType,
+ const char *address __unused,
+ bool enabled,
+ audio_stream_type_t streamToDriveAbs)
+{
+ audio_attributes_t attributesToDriveAbs = mEngine->getAttributesForStreamType(streamToDriveAbs);
+ if (attributesToDriveAbs == AUDIO_ATTRIBUTES_INITIALIZER) {
+ ALOGW("%s: no attributes for stream %s, bailing out", __func__,
+ toString(streamToDriveAbs).c_str());
+ return BAD_VALUE;
+ }
+
+ if (enabled) {
+ mAbsoluteVolumeDrivingStreams[deviceType] = attributesToDriveAbs;
+ } else {
+ mAbsoluteVolumeDrivingStreams.erase(deviceType);
+ }
+
+ return NO_ERROR;
+}
+
void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
{
ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
@@ -4487,6 +4508,13 @@
dst->appendFormat("\nPolicy Engine dump:\n");
mEngine->dump(dst);
+
+ dst->appendFormat("\nAbsolute volume devices with driving streams:\n");
+ for (const auto it : mAbsoluteVolumeDrivingStreams) {
+ dst->appendFormat(" - device type: %s, driving stream %d\n",
+ dumpDeviceTypes({it.first}).c_str(),
+ mEngine->getVolumeGroupForAttributes(it.second));
+ }
}
status_t AudioPolicyManager::dump(int fd)
@@ -7986,14 +8014,57 @@
return nullptr;
}
+float AudioPolicyManager::adjustDeviceAttenuationForAbsVolume(IVolumeCurves &curves,
+ VolumeSource volumeSource,
+ int index,
+ const DeviceTypeSet &deviceTypes)
+{
+ audio_devices_t volumeDevice = Volume::getDeviceForVolume(deviceTypes);
+ device_category deviceCategory = Volume::getDeviceCategory({volumeDevice});
+ float volumeDb = curves.volIndexToDb(deviceCategory, index);
+
+ if (com_android_media_audio_abs_volume_index_fix()) {
+ if (mAbsoluteVolumeDrivingStreams.find(volumeDevice) !=
+ mAbsoluteVolumeDrivingStreams.end()) {
+ audio_attributes_t attributesToDriveAbs = mAbsoluteVolumeDrivingStreams[volumeDevice];
+ auto groupToDriveAbs = mEngine->getVolumeGroupForAttributes(attributesToDriveAbs);
+ if (groupToDriveAbs == VOLUME_GROUP_NONE) {
+ ALOGD("%s: no group matching with %s", __FUNCTION__,
+ toString(attributesToDriveAbs).c_str());
+ return volumeDb;
+ }
+
+ float volumeDbMax = curves.volIndexToDb(deviceCategory, curves.getVolumeIndexMax());
+ VolumeSource vsToDriveAbs = toVolumeSource(groupToDriveAbs);
+ if (vsToDriveAbs == volumeSource) {
+ // attenuation is applied by the abs volume controller
+ return volumeDbMax;
+ } else {
+ IVolumeCurves &curvesAbs = getVolumeCurves(vsToDriveAbs);
+ int indexAbs = curvesAbs.getVolumeIndex({volumeDevice});
+ float volumeDbAbs = curvesAbs.volIndexToDb(deviceCategory, indexAbs);
+ float volumeDbAbsMax = curvesAbs.volIndexToDb(deviceCategory,
+ curvesAbs.getVolumeIndexMax());
+ float newVolumeDb = fminf(volumeDb + volumeDbAbsMax - volumeDbAbs, volumeDbMax);
+ ALOGV("%s: abs vol stream %d with attenuation %f is adjusting stream %d from "
+ "attenuation %f to attenuation %f %f", __func__, vsToDriveAbs, volumeDbAbs,
+ volumeSource, volumeDb, newVolumeDb, volumeDbMax);
+ return newVolumeDb;
+ }
+ }
+ return volumeDb;
+ } else {
+ return volumeDb;
+ }
+}
+
float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
VolumeSource volumeSource,
int index,
const DeviceTypeSet& deviceTypes,
bool computeInternalInteraction)
{
- float volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(deviceTypes), index);
-
+ float volumeDb = adjustDeviceAttenuationForAbsVolume(curves, volumeSource, index, deviceTypes);
ALOGV("%s volume source %d, index %d, devices %s, compute internal %b ", __func__,
volumeSource, index, dumpDeviceTypes(deviceTypes).c_str(), computeInternalInteraction);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 83597d8..585f982 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -103,7 +103,7 @@
virtual status_t setDeviceConnectionState(audio_policy_dev_state_t state,
const android::media::audio::common::AudioPort& port, audio_format_t encodedFormat);
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
- const char *device_address);
+ const char *device_address);
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name,
@@ -151,6 +151,10 @@
virtual status_t stopInput(audio_port_handle_t portId);
virtual void releaseInput(audio_port_handle_t portId);
virtual void checkCloseInputs();
+ virtual status_t setDeviceAbsoluteVolumeEnabled(audio_devices_t deviceType,
+ const char *address,
+ bool enabled,
+ audio_stream_type_t streamToDriveAbs);
/**
* @brief initStreamVolume: even if the engine volume files provides min and max, keep this
* api for compatibility reason.
@@ -1388,6 +1392,15 @@
audio_session_t sessionId) const;
void updateClientsInternalMute(const sp<SwAudioOutputDescriptor>& desc);
+
+ float adjustDeviceAttenuationForAbsVolume(IVolumeCurves &curves,
+ VolumeSource volumeSource,
+ int index,
+ const DeviceTypeSet &deviceTypes);
+
+ // Contains for devices that support absolute volume the audio attributes
+ // corresponding to the streams that are driving the volume changes
+ std::unordered_map<audio_devices_t, audio_attributes_t> mAbsoluteVolumeDrivingStreams;
};
};
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index a862037..771776f 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1020,6 +1020,32 @@
return Status::ok();
}
+Status AudioPolicyService::setDeviceAbsoluteVolumeEnabled(const AudioDevice& deviceAidl,
+ bool enabled,
+ AudioStreamType streamToDriveAbsAidl) {
+ audio_stream_type_t streamToDriveAbs = VALUE_OR_RETURN_BINDER_STATUS(
+ aidl2legacy_AudioStreamType_audio_stream_type_t(streamToDriveAbsAidl));
+ audio_devices_t deviceType;
+ std::string address;
+ RETURN_BINDER_STATUS_IF_ERROR(
+ aidl2legacy_AudioDevice_audio_device(deviceAidl, &deviceType, &address));
+
+ if (mAudioPolicyManager == nullptr) {
+ return binderStatusFromStatusT(NO_INIT);
+ }
+ if (!settingsAllowed()) {
+ return binderStatusFromStatusT(PERMISSION_DENIED);
+ }
+ if (uint32_t(streamToDriveAbs) >= AUDIO_STREAM_PUBLIC_CNT) {
+ return binderStatusFromStatusT(BAD_VALUE);
+ }
+ audio_utils::lock_guard _l(mMutex);
+ AutoCallerClear acc;
+ return binderStatusFromStatusT(
+ mAudioPolicyManager->setDeviceAbsoluteVolumeEnabled(deviceType, address.c_str(),
+ enabled, streamToDriveAbs));
+}
+
Status AudioPolicyService::initStreamVolume(AudioStreamType streamAidl,
int32_t indexMinAidl,
int32_t indexMaxAidl) {
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index f372c71..ebe6fb5 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -79,6 +79,7 @@
BINDER_METHOD_ENTRY(startInput) \
BINDER_METHOD_ENTRY(stopInput) \
BINDER_METHOD_ENTRY(releaseInput) \
+BINDER_METHOD_ENTRY(setDeviceAbsoluteVolumeEnabled) \
BINDER_METHOD_ENTRY(initStreamVolume) \
BINDER_METHOD_ENTRY(setStreamVolumeIndex) \
BINDER_METHOD_ENTRY(getStreamVolumeIndex) \
@@ -1321,6 +1322,7 @@
case TRANSACTION_setPhoneState:
//FIXME: Allow setForceUse calls from system apps until a better use case routing API is available
// case TRANSACTION_setForceUse:
+ case TRANSACTION_setDeviceAbsoluteVolumeEnabled:
case TRANSACTION_initStreamVolume:
case TRANSACTION_setStreamVolumeIndex:
case TRANSACTION_setVolumeIndexForAttributes:
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index eb9d081..d9f4f67 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -121,6 +121,9 @@
binder::Status startInput(int32_t portId) override;
binder::Status stopInput(int32_t portId) override;
binder::Status releaseInput(int32_t portId) override;
+ binder::Status setDeviceAbsoluteVolumeEnabled(const AudioDevice& device,
+ bool enabled,
+ AudioStreamType streamToDriveAbs) override;
binder::Status initStreamVolume(AudioStreamType stream, int32_t indexMin,
int32_t indexMax) override;
binder::Status setStreamVolumeIndex(AudioStreamType stream,