Merge "audio policy: fix volume burst on user switch." into nyc-dev
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
index 8dc3eda..a3de686 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
@@ -42,6 +42,8 @@
{
switchVolumeCurve(stream, stream);
}
+ virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
+ audio_devices_t device) const = 0;
virtual status_t dump(int fd) const = 0;
diff --git a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
index af178f9..424df84 100644
--- a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
@@ -38,6 +38,11 @@
int getVolumeIndexMax() const { return mIndexMax; }
void setVolumeIndexMin(int volIndexMin);
void setVolumeIndexMax(int volIndexMax);
+ bool hasVolumeIndexForDevice(audio_devices_t device) const
+ {
+ device = Volume::getDeviceForVolume(device);
+ return mIndexCur.indexOfKey(device) >= 0;
+ }
void dump(int fd) const;
@@ -85,6 +90,11 @@
virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
virtual void initializeVolumeCurves(bool isSpeakerDrcEnabled);
virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
+ virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
+ audio_devices_t device) const
+ {
+ return valueFor(stream).hasVolumeIndexForDevice(device);
+ }
virtual status_t dump(int fd) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
index 009a26f..7c486c8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
@@ -44,8 +44,8 @@
return lhs.mIndex < rhs.mIndex;
}
-// A volume curve for a given use case and device cateory
-// It contains of list of points of this cuive expressing the atteunation in Millibels for
+// A volume curve for a given use case and device category
+// It contains of list of points of this curve expressing the attenuation in Millibels for
// a given volume index from 0 to 100
class VolumeCurve : public RefBase
{
@@ -105,6 +105,12 @@
void setVolumeIndexMax(int volIndexMax) { mIndexMax = volIndexMax; }
int getVolumeIndexMax() const { return mIndexMax; }
+ bool hasVolumeIndexForDevice(audio_devices_t device) const
+ {
+ device = Volume::getDeviceForVolume(device);
+ return mIndexCur.indexOfKey(device) >= 0;
+ }
+
const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const
{
ALOG_ASSERT(mOriginVolumeCurves.indexOfKey(deviceCategory) >= 0, "Invalid device category");
@@ -200,6 +206,11 @@
{
return getCurvesFor(stream).volIndexToDb(cat, indexInUi);
}
+ virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
+ audio_devices_t device) const
+ {
+ return getCurvesFor(stream).hasVolumeIndexForDevice(device);
+ }
virtual status_t dump(int fd) const;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 35c868e..07c470d 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1821,15 +1821,9 @@
// Force max volume if stream cannot be muted
if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
- ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
+ ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
stream, device, index);
- // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
- // clear all device specific values
- if (device == AUDIO_DEVICE_OUT_DEFAULT) {
- mVolumeCurves->clearCurrentVolumeIndex(stream);
- }
-
// update other private stream volumes which follow this one
for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
@@ -1838,8 +1832,14 @@
mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
}
- // update volume on all outputs whose current device is also selected by the same
- // strategy as the device specified by the caller
+ // update volume on all outputs and streams matching the following:
+ // - The requested stream (or a stream matching for volume control) is active on the output
+ // - The device (or devices) selected by the strategy corresponding to this stream includes
+ // the requested device
+ // - For non default requested device, currently selected device on the output is either the
+ // requested device or one of the devices selected by the strategy
+ // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT), apply volume only if no specific
+ // device volume value exists for currently selected device.
status_t status = NO_ERROR;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -1848,16 +1848,23 @@
if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
continue;
}
+ if (!desc->isStreamActive((audio_stream_type_t)curStream)) {
+ continue;
+ }
routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, true /*fromCache*/);
- // it is possible that the requested device is not selected by the strategy
- // (e.g an explicit audio patch is active causing getDevicesForStream()
- // to return this device. We must make sure that the device passed is part of the
- // devices considered when applying volume below.
- curStreamDevice |= device;
+ if ((curStreamDevice & device) == 0) {
+ continue;
+ }
+ bool applyDefault = false;
+ if (device != AUDIO_DEVICE_OUT_DEFAULT) {
+ curStreamDevice |= device;
+ } else if (!mVolumeCurves->hasVolumeIndexForDevice(
+ stream, Volume::getDeviceForVolume(curStreamDevice))) {
+ applyDefault = true;
+ }
- if (((device == AUDIO_DEVICE_OUT_DEFAULT) ||
- ((curDevice & curStreamDevice) != 0))) {
+ if (applyDefault || ((curDevice & curStreamDevice) != 0)) {
status_t volStatus =
checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice);
if (volStatus != NO_ERROR) {