Revert "Revert "audiopolicy: moves Stream Volume Curves to Engine""
This reverts commit efdbe3bfeff7c150d99900fddca005d48048f188.
Test: make
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index e5ebab7..c9037a1 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -19,7 +19,6 @@
"src/Serializer.cpp",
"src/SoundTriggerSession.cpp",
"src/TypeConverter.cpp",
- "src/VolumeCurve.cpp",
],
shared_libs: [
"libcutils",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index d52eb3d..2264d8f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -20,7 +20,6 @@
#include <unordered_set>
#include <AudioGain.h>
-#include <VolumeCurve.h>
#include <AudioPort.h>
#include <AudioPatch.h>
#include <DeviceDescriptor.h>
@@ -40,13 +39,11 @@
AudioPolicyConfig(HwModuleCollection &hwModules,
DeviceVector &availableOutputDevices,
DeviceVector &availableInputDevices,
- sp<DeviceDescriptor> &defaultOutputDevice,
- VolumeCurvesCollection *volumes = nullptr)
+ sp<DeviceDescriptor> &defaultOutputDevice)
: mHwModules(hwModules),
mAvailableOutputDevices(availableOutputDevices),
mAvailableInputDevices(availableInputDevices),
mDefaultOutputDevice(defaultOutputDevice),
- mVolumeCurves(volumes),
mIsSpeakerDrcEnabled(false)
{}
@@ -58,13 +55,6 @@
mSource = file;
}
- void setVolumes(const VolumeCurvesCollection &volumes)
- {
- if (mVolumeCurves != nullptr) {
- *mVolumeCurves = volumes;
- }
- }
-
void setHwModules(const HwModuleCollection &hwModules)
{
mHwModules = hwModules;
@@ -182,7 +172,6 @@
DeviceVector &mAvailableOutputDevices;
DeviceVector &mAvailableInputDevices;
sp<DeviceDescriptor> &mDefaultOutputDevice;
- VolumeCurvesCollection *mVolumeCurves;
// TODO: remove when legacy conf file is removed. true on devices that use DRC on the
// DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
// Note: remove also speaker_drc_enabled from global configuration of XML config file.
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h
new file mode 100644
index 0000000..93022fb
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+#include <Volume.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <vector>
+
+namespace android {
+
+class IVolumeCurves
+{
+public:
+ virtual ~IVolumeCurves() = default;
+
+ virtual void clearCurrentVolumeIndex() = 0;
+ virtual void addCurrentVolumeIndex(audio_devices_t device, int index) = 0;
+ virtual bool canBeMuted() const = 0;
+ virtual int getVolumeIndexMin() const = 0;
+ virtual int getVolumeIndex(audio_devices_t device) const = 0;
+ virtual int getVolumeIndexMax() const = 0;
+ virtual float volIndexToDb(device_category device, int indexInUi) const = 0;
+ virtual bool hasVolumeIndexForDevice(audio_devices_t device) const = 0;
+ virtual status_t initVolume(int indexMin, int indexMax) = 0;
+ virtual void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const = 0;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
deleted file mode 100644
index 750da55..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <system/audio.h>
-#include <Volume.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-
-namespace android {
-
-class IVolumeCurvesCollection
-{
-public:
- virtual ~IVolumeCurvesCollection() = default;
-
- virtual void clearCurrentVolumeIndex(audio_stream_type_t stream) = 0;
- virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device,
- int index) = 0;
- virtual bool canBeMuted(audio_stream_type_t stream) = 0;
- virtual int getVolumeIndexMin(audio_stream_type_t stream) const = 0;
- virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device) = 0;
- virtual int getVolumeIndexMax(audio_stream_type_t stream) const = 0;
- virtual float volIndexToDb(audio_stream_type_t stream, device_category device,
- int indexInUi) const = 0;
- virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) = 0;
-
- virtual void initializeVolumeCurves(bool /*isSpeakerDrcEnabled*/) {}
- virtual void switchVolumeCurve(audio_stream_type_t src, audio_stream_type_t dst) = 0;
- virtual void restoreOriginVolumeCurve(audio_stream_type_t stream)
- {
- switchVolumeCurve(stream, stream);
- }
- virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
- audio_devices_t device) const = 0;
-
- virtual void dump(String8 *dst) const = 0;
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
deleted file mode 100644
index 76ec198..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "IVolumeCurvesCollection.h"
-#include <policy.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
-#include <system/audio.h>
-#include <cutils/config_utils.h>
-#include <string>
-#include <utility>
-
-namespace android {
-
-struct CurvePoint
-{
- CurvePoint() {}
- CurvePoint(int index, int attenuationInMb) :
- mIndex(index), mAttenuationInMb(attenuationInMb) {}
- uint32_t mIndex;
- int mAttenuationInMb;
-};
-
-inline bool operator< (const CurvePoint &lhs, const CurvePoint &rhs)
-{
- return lhs.mIndex < rhs.mIndex;
-}
-
-// 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
-{
-public:
- VolumeCurve(device_category device, audio_stream_type_t stream) :
- mDeviceCategory(device), mStreamType(stream) {}
-
- device_category getDeviceCategory() const { return mDeviceCategory; }
- audio_stream_type_t getStreamType() const { return mStreamType; }
-
- void add(const CurvePoint &point) { mCurvePoints.add(point); }
-
- float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const;
-
- void dump(String8 *result) const;
-
-private:
- SortedVector<CurvePoint> mCurvePoints;
- device_category mDeviceCategory;
- audio_stream_type_t mStreamType;
-};
-
-// Volume Curves for a given use case indexed by device category
-class VolumeCurvesForStream : public KeyedVector<device_category, sp<VolumeCurve> >
-{
-public:
- VolumeCurvesForStream() : mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
- {
- mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
- }
-
- sp<VolumeCurve> getCurvesFor(device_category device) const
- {
- if (indexOfKey(device) < 0) {
- return 0;
- }
- return valueFor(device);
- }
-
- int getVolumeIndex(audio_devices_t device) const
- {
- device = Volume::getDeviceForVolume(device);
- // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
- if (mIndexCur.indexOfKey(device) < 0) {
- device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
- }
- return mIndexCur.valueFor(device);
- }
-
- bool canBeMuted() const { return mCanBeMuted; }
- void clearCurrentVolumeIndex() { mIndexCur.clear(); }
- void addCurrentVolumeIndex(audio_devices_t device, int index) { mIndexCur.add(device, index); }
-
- void setVolumeIndexMin(int volIndexMin) { mIndexMin = volIndexMin; }
- int getVolumeIndexMin() const { return mIndexMin; }
-
- 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");
- return mOriginVolumeCurves.valueFor(deviceCategory);
- }
- void setVolumeCurve(device_category deviceCategory, const sp<VolumeCurve> &volumeCurve)
- {
- ALOG_ASSERT(indexOfKey(deviceCategory) >= 0, "Invalid device category for Volume Curve");
- replaceValueFor(deviceCategory, volumeCurve);
- }
-
- ssize_t add(const sp<VolumeCurve> &volumeCurve)
- {
- device_category deviceCategory = volumeCurve->getDeviceCategory();
- ssize_t index = indexOfKey(deviceCategory);
- if (index < 0) {
- // Keep track of original Volume Curves per device category in order to switch curves.
- mOriginVolumeCurves.add(deviceCategory, volumeCurve);
- return KeyedVector::add(deviceCategory, volumeCurve);
- }
- return index;
- }
-
- float volIndexToDb(device_category deviceCat, int indexInUi) const
- {
- sp<VolumeCurve> vc = getCurvesFor(deviceCat);
- if (vc != 0) {
- return vc->volIndexToDb(indexInUi, mIndexMin, mIndexMax);
- } else {
- ALOGE("Invalid device category %d for Volume Curve", deviceCat);
- return 0.0f;
- }
- }
-
- void dump(String8 *dst, int spaces, bool curvePoints = false) const;
-
-private:
- KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves;
- KeyedVector<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
- int mIndexMin; /**< min volume index. */
- int mIndexMax; /**< max volume index. */
- bool mCanBeMuted; /**< true is the stream can be muted. */
-};
-
-// Collection of Volume Curves indexed by use case
-class VolumeCurvesCollection : public KeyedVector<audio_stream_type_t, VolumeCurvesForStream>,
- public IVolumeCurvesCollection
-{
-public:
- VolumeCurvesCollection()
- {
- // Create an empty collection of curves
- for (ssize_t i = 0 ; i < AUDIO_STREAM_CNT; i++) {
- audio_stream_type_t stream = static_cast<audio_stream_type_t>(i);
- KeyedVector::add(stream, VolumeCurvesForStream());
- }
- }
-
- // Once XML has been parsed, must be call first to sanity check table and initialize indexes
- virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
- {
- editValueAt(stream).setVolumeIndexMin(indexMin);
- editValueAt(stream).setVolumeIndexMax(indexMax);
- return NO_ERROR;
- }
- virtual void clearCurrentVolumeIndex(audio_stream_type_t stream)
- {
- editCurvesFor(stream).clearCurrentVolumeIndex();
- }
- virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device, int index)
- {
- editCurvesFor(stream).addCurrentVolumeIndex(device, index);
- }
- virtual bool canBeMuted(audio_stream_type_t stream) { return getCurvesFor(stream).canBeMuted(); }
-
- virtual int getVolumeIndexMin(audio_stream_type_t stream) const
- {
- return getCurvesFor(stream).getVolumeIndexMin();
- }
- virtual int getVolumeIndexMax(audio_stream_type_t stream) const
- {
- return getCurvesFor(stream).getVolumeIndexMax();
- }
- virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device)
- {
- return getCurvesFor(stream).getVolumeIndex(device);
- }
- virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst)
- {
- const VolumeCurvesForStream &sourceCurves = getCurvesFor(streamSrc);
- VolumeCurvesForStream &dstCurves = editCurvesFor(streamDst);
- ALOG_ASSERT(sourceCurves.size() == dstCurves.size(), "device category not aligned");
- for (size_t index = 0; index < sourceCurves.size(); index++) {
- device_category cat = sourceCurves.keyAt(index);
- dstCurves.setVolumeCurve(cat, sourceCurves.getOriginVolumeCurve(cat));
- }
- }
- virtual float volIndexToDb(audio_stream_type_t stream, device_category cat, int indexInUi) const
- {
- return getCurvesFor(stream).volIndexToDb(cat, indexInUi);
- }
- virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
- audio_devices_t device) const
- {
- return getCurvesFor(stream).hasVolumeIndexForDevice(device);
- }
-
- void dump(String8 *dst) const override;
-
- ssize_t add(const sp<VolumeCurve> &volumeCurve)
- {
- audio_stream_type_t streamType = volumeCurve->getStreamType();
- return editCurvesFor(streamType).add(volumeCurve);
- }
- VolumeCurvesForStream &editCurvesFor(audio_stream_type_t stream)
- {
- ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve");
- return editValueAt(stream);
- }
- const VolumeCurvesForStream &getCurvesFor(audio_stream_type_t stream) const
- {
- ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve");
- return valueFor(stream);
- }
-};
-
-} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 98d375c..81d3968 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -201,25 +201,6 @@
static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
};
-struct VolumeTraits : public AndroidCollectionTraits<VolumeCurve, VolumeCurvesCollection>
-{
- static constexpr const char *tag = "volume";
- static constexpr const char *collectionTag = "volumes";
- static constexpr const char *volumePointTag = "point";
- static constexpr const char *referenceTag = "reference";
-
- struct Attributes
- {
- static constexpr const char *stream = "stream";
- static constexpr const char *deviceCategory = "deviceCategory";
- static constexpr const char *reference = "ref";
- static constexpr const char *referenceName = "name";
- };
-
- static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
- // No Children
-};
-
struct SurroundSoundTraits
{
static constexpr const char *tag = "surroundSound";
@@ -703,67 +684,6 @@
return NO_ERROR;
}
-Return<VolumeTraits::Element> VolumeTraits::deserialize(const xmlNode *cur,
- PtrSerializingCtx /*serializingContext*/)
-{
- std::string streamTypeLiteral = getXmlAttribute(cur, Attributes::stream);
- if (streamTypeLiteral.empty()) {
- ALOGE("%s: No %s found", __func__, Attributes::stream);
- return Status::fromStatusT(BAD_VALUE);
- }
- audio_stream_type_t streamType;
- if (!StreamTypeConverter::fromString(streamTypeLiteral, streamType)) {
- ALOGE("%s: Invalid %s", __func__, Attributes::stream);
- return Status::fromStatusT(BAD_VALUE);
- }
- std::string deviceCategoryLiteral = getXmlAttribute(cur, Attributes::deviceCategory);
- if (deviceCategoryLiteral.empty()) {
- ALOGE("%s: No %s found", __func__, Attributes::deviceCategory);
- return Status::fromStatusT(BAD_VALUE);
- }
- device_category deviceCategory;
- if (!DeviceCategoryConverter::fromString(deviceCategoryLiteral, deviceCategory)) {
- ALOGE("%s: Invalid %s=%s", __func__, Attributes::deviceCategory,
- deviceCategoryLiteral.c_str());
- return Status::fromStatusT(BAD_VALUE);
- }
-
- std::string referenceName = getXmlAttribute(cur, Attributes::reference);
- const xmlNode *ref = NULL;
- if (!referenceName.empty()) {
- ref = getReference<VolumeTraits>(cur->parent, referenceName);
- if (ref == NULL) {
- ALOGE("%s: No reference Ptr found for %s", __func__, referenceName.c_str());
- return Status::fromStatusT(BAD_VALUE);
- }
- }
-
- Element volCurve = new VolumeCurve(deviceCategory, streamType);
-
- for (const xmlNode *child = referenceName.empty() ? cur->xmlChildrenNode : ref->xmlChildrenNode;
- child != NULL; child = child->next) {
- if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>(volumePointTag))) {
- auto pointDefinition = make_xmlUnique(xmlNodeListGetString(
- child->doc, child->xmlChildrenNode, 1));
- if (pointDefinition == nullptr) {
- return Status::fromStatusT(BAD_VALUE);
- }
- ALOGV("%s: %s=%s",
- __func__, tag, reinterpret_cast<const char*>(pointDefinition.get()));
- std::vector<int32_t> point;
- collectionFromString<DefaultTraits<int32_t>>(
- reinterpret_cast<const char*>(pointDefinition.get()), point, ",");
- if (point.size() != 2) {
- ALOGE("%s: Invalid %s: %s", __func__, volumePointTag,
- reinterpret_cast<const char*>(pointDefinition.get()));
- return Status::fromStatusT(BAD_VALUE);
- }
- volCurve->add(CurvePoint(point[0], point[1]));
- }
- }
- return volCurve;
-}
-
status_t SurroundSoundTraits::deserialize(const xmlNode *root, AudioPolicyConfig *config)
{
config->setDefaultSurroundFormats();
@@ -851,14 +771,6 @@
}
config->setHwModules(modules);
- // deserialize volume section
- VolumeTraits::Collection volumes;
- status = deserializeCollection<VolumeTraits>(root, &volumes, config);
- if (status != NO_ERROR) {
- return status;
- }
- config->setVolumes(volumes);
-
// Global Configuration
GlobalConfigTraits::deserialize(root, config);
diff --git a/services/audiopolicy/config/audio_policy_configuration.xml b/services/audiopolicy/config/audio_policy_configuration.xml
index 42c52de..b4cc1d3 100644
--- a/services/audiopolicy/config/audio_policy_configuration.xml
+++ b/services/audiopolicy/config/audio_policy_configuration.xml
@@ -191,7 +191,11 @@
</modules>
<!-- End of Modules section -->
- <!-- Volume section -->
+ <!-- Volume section:
+ IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+ Keep it here for legacy.
+ Engine will fallback on these files if none are provided by engine.
+ -->
<xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/>
diff --git a/services/audiopolicy/config/audio_policy_configuration_generic.xml b/services/audiopolicy/config/audio_policy_configuration_generic.xml
index 40dcc22..9ad609d 100644
--- a/services/audiopolicy/config/audio_policy_configuration_generic.xml
+++ b/services/audiopolicy/config/audio_policy_configuration_generic.xml
@@ -30,7 +30,11 @@
</modules>
<!-- End of Modules section -->
- <!-- Volume section -->
+ <!-- Volume section:
+ IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+ Keep it here for legacy.
+ Engine will fallback on these files if none are provided by engine.
+ -->
<xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/>
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 5c33fb3..bc027e2 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -19,6 +19,7 @@
#include <EngineConfig.h>
#include <AudioPolicyManagerInterface.h>
#include <ProductStrategy.h>
+#include <StreamVolumeCurves.h>
namespace android {
namespace audio_policy {
@@ -67,6 +68,10 @@
status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const override;
+ VolumeCurves *getVolumeCurvesForAttributes(const audio_attributes_t &attr) override;
+
+ VolumeCurves *getVolumeCurvesForStreamType(audio_stream_type_t stream) override;
+
void dump(String8 *dst) const override;
@@ -87,7 +92,16 @@
return is_state_in_call(getPhoneState());
}
-private:
+ VolumeSource toVolumeSource(audio_stream_type_t stream) const
+ {
+ return static_cast<VolumeSource>(stream);
+ }
+
+ status_t switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
+
+ status_t restoreOriginVolumeCurve(audio_stream_type_t stream);
+
+ private:
AudioPolicyManagerObserver *mApmObserver = nullptr;
ProductStrategyMap mProductStrategies;
@@ -95,6 +109,8 @@
/** current forced use configuration. */
audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT] = {};
+
+ StreamVolumeCurves mStreamVolumeCurves;
};
} // namespace audio_policy
diff --git a/services/audiopolicy/engine/common/include/StreamVolumeCurves.h b/services/audiopolicy/engine/common/include/StreamVolumeCurves.h
new file mode 100644
index 0000000..5b0b7d6
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/StreamVolumeCurves.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VolumeCurve.h>
+#include <map>
+
+namespace android {
+
+class StreamVolumeCurves
+{
+public:
+ StreamVolumeCurves() = default;
+
+ /**
+ * @brief switchVolumeCurve control API for Engine, allows to switch the volume curves
+ * from one stream type to another.
+ * @param src source stream type
+ * @param dst destination stream type
+ */
+ status_t switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst)
+ {
+ if (!hasCurvesFor(streamSrc) || !hasCurvesFor(streamDst)) {
+ ALOGE("%s: No curves defined for streams %d %d", __FUNCTION__, streamSrc, streamDst);
+ return NO_INIT;
+ }
+ const VolumeCurves &sourceCurves = getCurvesFor(streamSrc);
+ VolumeCurves &dstCurves = editCurvesFor(streamDst);
+ return dstCurves.switchCurvesFrom(sourceCurves);
+ }
+ void dump(String8 *dst, int spaces = 0) const;
+
+ void add(const VolumeCurves &curves, audio_stream_type_t streamType)
+ {
+ mCurves.emplace(streamType, curves);
+ }
+
+ bool hasCurvesFor(audio_stream_type_t stream)
+ {
+ return mCurves.find(stream) != end(mCurves);
+ }
+
+ VolumeCurves &editCurvesFor(audio_stream_type_t stream)
+ {
+ ALOG_ASSERT(mCurves.find(stream) != end(mCurves), "Invalid stream type for Volume Curve");
+ return mCurves[stream];
+ }
+ const VolumeCurves &getCurvesFor(audio_stream_type_t stream) const
+ {
+ ALOG_ASSERT(mCurves.find(stream) != end(mCurves), "Invalid stream type for Volume Curve");
+ return mCurves.at(stream);
+ }
+ /**
+ * @brief getVolumeCurvesForStream
+ * @param stream type for which the volume curves interface is requested
+ * @return the VolumeCurves for a given stream type.
+ */
+ VolumeCurves &getVolumeCurvesForStream(audio_stream_type_t stream)
+ {
+ ALOG_ASSERT(mCurves.find(stream) != end(mCurves), "Invalid stream type for Volume Curve");
+ return mCurves[stream];
+ }
+ /**
+ * @brief restoreOriginVolumeCurve helper control API for engine to restore the original volume
+ * curves for a given stream type
+ * @param stream for which the volume curves will be restored.
+ */
+ status_t restoreOriginVolumeCurve(audio_stream_type_t stream)
+ {
+ if (!hasCurvesFor(stream)) {
+ ALOGE("%s: No curves defined for streams", __FUNCTION__);
+ return NO_INIT;
+ }
+ return switchVolumeCurve(stream, stream);
+ }
+
+private:
+ std::map<audio_stream_type_t, VolumeCurves> mCurves;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/include/VolumeCurve.h b/services/audiopolicy/engine/common/include/VolumeCurve.h
new file mode 100644
index 0000000..c2a1da7
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/VolumeCurve.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "IVolumeCurves.h"
+#include <policy.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <system/audio.h>
+#include <cutils/config_utils.h>
+#include <string>
+#include <map>
+#include <utility>
+
+namespace android {
+
+struct CurvePoint
+{
+ CurvePoint() {}
+ CurvePoint(int index, int attenuationInMb) :
+ mIndex(index), mAttenuationInMb(attenuationInMb) {}
+ uint32_t mIndex;
+ int mAttenuationInMb;
+};
+
+inline bool operator< (const CurvePoint &lhs, const CurvePoint &rhs)
+{
+ return lhs.mIndex < rhs.mIndex;
+}
+
+// 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
+{
+public:
+ VolumeCurve(device_category device) : mDeviceCategory(device) {}
+
+ void add(const CurvePoint &point) { mCurvePoints.add(point); }
+
+ float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const;
+
+ void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const;
+
+ device_category getDeviceCategory() const { return mDeviceCategory; }
+
+private:
+ const device_category mDeviceCategory;
+ SortedVector<CurvePoint> mCurvePoints;
+};
+
+// Volume Curves for a given use case indexed by device category
+class VolumeCurves : public KeyedVector<device_category, sp<VolumeCurve> >,
+ public IVolumeCurves
+{
+public:
+ VolumeCurves(int indexMin = 0, int indexMax = 100) :
+ mIndexMin(indexMin), mIndexMax(indexMax), mStream(AUDIO_STREAM_DEFAULT)
+ {
+ addCurrentVolumeIndex(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
+ }
+ VolumeCurves(audio_stream_type_t stream, int indexMin, int indexMax) :
+ mIndexMin(indexMin), mIndexMax(indexMax), mStream(stream)
+ {
+ addCurrentVolumeIndex(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
+ }
+
+ // Once XML has been parsed, must be call first to sanity check table and initialize indexes
+ virtual status_t initVolume(int indexMin, int indexMax)
+ {
+ mIndexMin = indexMin;
+ mIndexMax = indexMax;
+ return NO_ERROR;
+ }
+
+ sp<VolumeCurve> getCurvesFor(device_category device) const
+ {
+ if (indexOfKey(device) < 0) {
+ return 0;
+ }
+ return valueFor(device);
+ }
+
+ virtual int getVolumeIndex(audio_devices_t device) const
+ {
+ device = Volume::getDeviceForVolume(device);
+ // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
+ if (mIndexCur.find(device) == end(mIndexCur)) {
+ device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
+ }
+ return mIndexCur.at(device);
+ }
+
+ virtual bool canBeMuted() const { return mCanBeMuted; }
+ virtual void clearCurrentVolumeIndex() { mIndexCur.clear(); }
+ void addCurrentVolumeIndex(audio_devices_t device, int index) override
+ {
+ mIndexCur[device] = index;
+ }
+
+ int getVolumeIndexMin() const { return mIndexMin; }
+
+ int getVolumeIndexMax() const { return mIndexMax; }
+
+ bool hasVolumeIndexForDevice(audio_devices_t device) const
+ {
+ device = Volume::getDeviceForVolume(device);
+ return mIndexCur.find(device) != end(mIndexCur);
+ }
+
+ status_t switchCurvesFrom(const VolumeCurves &referenceCurves)
+ {
+ if (size() != referenceCurves.size()) {
+ ALOGE("%s! device category not aligned, cannot switch", __FUNCTION__);
+ return BAD_TYPE;
+ }
+ for (size_t index = 0; index < size(); index++) {
+ device_category cat = keyAt(index);
+ setVolumeCurve(cat, referenceCurves.getOriginVolumeCurve(cat));
+ }
+ return NO_ERROR;
+ }
+ status_t restoreOriginVolumeCurve()
+ {
+ return switchCurvesFrom(*this);
+ }
+
+ const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const
+ {
+ ALOG_ASSERT(mOriginVolumeCurves.indexOfKey(deviceCategory) >= 0, "Invalid device category");
+ return mOriginVolumeCurves.valueFor(deviceCategory);
+ }
+ void setVolumeCurve(device_category deviceCategory, const sp<VolumeCurve> &volumeCurve)
+ {
+ ALOG_ASSERT(indexOfKey(deviceCategory) >= 0, "Invalid device category for Volume Curve");
+ replaceValueFor(deviceCategory, volumeCurve);
+ }
+
+ ssize_t add(const sp<VolumeCurve> &volumeCurve)
+ {
+ device_category deviceCategory = volumeCurve->getDeviceCategory();
+ ssize_t index = indexOfKey(deviceCategory);
+ if (index < 0) {
+ // Keep track of original Volume Curves per device category in order to switch curves.
+ mOriginVolumeCurves.add(deviceCategory, volumeCurve);
+ return KeyedVector::add(deviceCategory, volumeCurve);
+ }
+ return index;
+ }
+
+ virtual float volIndexToDb(device_category deviceCat, int indexInUi) const
+ {
+ sp<VolumeCurve> vc = getCurvesFor(deviceCat);
+ if (vc != 0) {
+ return vc->volIndexToDb(indexInUi, mIndexMin, mIndexMax);
+ } else {
+ ALOGE("Invalid device category %d for Volume Curve", deviceCat);
+ return 0.0f;
+ }
+ }
+
+ audio_stream_type_t getStreamType() const { return mStream; }
+
+ void dump(String8 *dst, int spaces = 0, bool curvePoints = false) const override;
+
+private:
+ KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves;
+ std::map<audio_devices_t, int> mIndexCur; /**< current volume index per device. */
+ /*const*/ int mIndexMin; /**< min volume index. */
+ /*const*/ int mIndexMax; /**< max volume index. */
+ const bool mCanBeMuted = true; /**< true is the stream can be muted. */
+
+ const audio_stream_type_t mStream; /**< Keep it for legacy. */
+};
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 755f2a8..2449b61 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -55,8 +55,10 @@
if (!is_state_in_call(oldState) && is_state_in_call(state)) {
ALOGV(" Entering call in setPhoneState()");
+ switchVolumeCurve(AUDIO_STREAM_VOICE_CALL, AUDIO_STREAM_DTMF);
} else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
ALOGV(" Exiting call in setPhoneState()");
+ restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
}
return NO_ERROR;
}
@@ -108,6 +110,31 @@
productStrategies[strategyId] = strategy;
}
};
+ auto loadVolumeCurves = [](const auto &configVolumes, auto &streamVolumeCollection) {
+ for (auto &configVolume : configVolumes) {
+ audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
+ if (configVolume.stream.empty() ||
+ !StreamTypeConverter::fromString(configVolume.stream, streamType)) {
+ ALOGE("%s: Invalid stream type", __FUNCTION__);
+ continue;
+ }
+ VolumeCurves volumeCurves(streamType, configVolume.indexMin, configVolume.indexMax);
+ for (auto &configCurve : configVolume.volumeCurves) {
+ device_category deviceCategory = DEVICE_CATEGORY_SPEAKER;
+ if (!DeviceCategoryConverter::fromString(configCurve.deviceCategory,
+ deviceCategory)) {
+ ALOGE("%s: Invalid %s", __FUNCTION__, configCurve.deviceCategory.c_str());
+ continue;
+ }
+ sp<VolumeCurve> curve = new VolumeCurve(deviceCategory);
+ for (auto &point : configCurve.curvePoints) {
+ curve->add({point.index, point.attenuationInMb});
+ }
+ volumeCurves.add(curve);
+ }
+ streamVolumeCollection.add(volumeCurves, streamType);
+ }
+ };
auto result = engineConfig::parse();
if (result.parsedConfig == nullptr) {
@@ -116,6 +143,7 @@
}
ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
loadProductStrategies(result.parsedConfig->productStrategies, mProductStrategies);
+ loadVolumeCurves(result.parsedConfig->volumeGroups, mStreamVolumeCurves);
return result;
}
@@ -173,9 +201,30 @@
return NO_ERROR;
}
+VolumeCurves *EngineBase::getVolumeCurvesForAttributes(const audio_attributes_t &attr)
+{
+ return &mStreamVolumeCurves.getVolumeCurvesForStream(getStreamTypeForAttributes(attr));
+}
+
+VolumeCurves *EngineBase::getVolumeCurvesForStreamType(audio_stream_type_t stream)
+{
+ return &mStreamVolumeCurves.getVolumeCurvesForStream(stream);
+}
+
+status_t EngineBase::switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst)
+{
+ return mStreamVolumeCurves.switchVolumeCurve(streamSrc, streamDst);;
+}
+
+status_t EngineBase::restoreOriginVolumeCurve(audio_stream_type_t stream)
+{
+ return mStreamVolumeCurves.restoreOriginVolumeCurve(stream);
+}
+
void EngineBase::dump(String8 *dst) const
{
mProductStrategies.dump(dst, 2);
+ mStreamVolumeCurves.dump(dst, 2);
}
} // namespace audio_policy
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
index 3940c0c..86a59b0 100644
--- a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -131,10 +131,131 @@
}
};
+const engineConfig::VolumeGroups gVolumeGroups = {
+ {"voice_call", "AUDIO_STREAM_VOICE_CALL", 1, 10,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -4200}, {33, -2800}, {66, -1400}, {100, 0} } },
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -2400}, {33, -1600}, {66, -800}, {100, 0} } },
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -2700}, {33, -1800}, {66, -900}, {100, 0} } },
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } },
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } },
+ },
+ },
+ {"system", "AUDIO_STREAM_SYSTEM", 0, 100,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {1, -3000}, {33, -2600}, {66, -2200}, {100, -1800} } },
+ {"DEVICE_CATEGORY_SPEAKER", { {1, -5100}, {57, -2800}, {71, -2500}, {85, -2300}, {100, -2100} } },
+ {"DEVICE_CATEGORY_EARPIECE", { {1, -2400}, {33, -1800}, {66, -1200}, {100, -600} } },
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -2100}, {100, -1000} } }, // DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"ring", "AUDIO_STREAM_RING", 0, 100,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {1, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } },
+ {"DEVICE_CATEGORY_EARPIECE", { {1, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -2100}, {100, -1000} } }, // DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"music", "AUDIO_STREAM_MUSIC", 0, 40,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"alarm", "AUDIO_STREAM_ALARM", 0, 100,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {0, -5800}, {20, -4000}, {60, -2100}, {100, -1000} } }, // DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {0, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"notification", "AUDIO_STREAM_NOTIFICATION", 0, 100,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {1, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {1, -4680}, {42, -2070}, {85, -540}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {1, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -2100}, {100, -1000} } }, // DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -4950}, {33, -3350}, {66, -1700}, {100, 0} } }, // DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE
+ },
+ },
+ {"bluetooth_sco", "AUDIO_STREAM_BLUETOOTH_SCO", 1, 10,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -4200}, {33, -2800}, {66, -1400}, {100, 0} } },
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -2400}, {33, -1600}, {66, -800}, {100, 0} } },
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -4200}, {33, -2800}, {66, -1400}, {100, 0} } },
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"enforced_audible", "AUDIO_STREAM_ENFORCED_AUDIBLE", 0, 100,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {1, -3000}, {33, -2600}, {66, -2200}, {100, -1800} } },
+ {"DEVICE_CATEGORY_SPEAKER", { {1, -3400}, {71, -2400}, {100, -2000} } },
+ {"DEVICE_CATEGORY_EARPIECE", { {1, -2400}, {33, -1800}, {66, -1200}, {100, -600} } }, // DEFAULT_SYSTEM_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -2100}, {100, -1000} } }, // DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"dtmf", "AUDIO_STREAM_DTMF", 0, 100,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {1, -3000}, {33, -2600}, {66, -2200}, {100, -1800} } },
+ {"DEVICE_CATEGORY_SPEAKER", { {1, -4000}, {71, -2400}, {100, -1400} } }, // DEFAULT_SYSTEM_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {1, -2400}, {33, -1800}, {66, -1200}, {100, -600} } }, // DEFAULT_SYSTEM_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {1, -5800}, {20, -4000}, {60, -2100}, {100, -1000} } }, // DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {1, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"tts", "AUDIO_STREAM_TTS", 0, 16,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -9600}, {100, -9600} } }, // SILENT_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -9600}, {100, -9600} } }, // SILENT_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {0, -9600}, {100, -9600} } }, // SILENT_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {0, -9600}, {100, -9600} } }, // SILENT_VOLUME_CURVE
+ },
+ },
+ {"accessibility", "AUDIO_STREAM_ACCESSIBILITY", 1, 40,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {0, -5800}, {20, -4000}, {60, -1700}, {100, 0} } }, // DEFAULT_NON_MUTABLE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {0, -12700}, {20, -8000}, {60, -4000}, {100, 0} } }, // DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE
+ },
+ },
+ {"rerouting", "AUDIO_STREAM_REROUTING", 0, 1,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ },
+ },
+ {"patch", "AUDIO_STREAM_PATCH", 0, 1,
+ {
+ {"DEVICE_CATEGORY_HEADSET", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_SPEAKER", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EARPIECE", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_EXT_MEDIA", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ {"DEVICE_CATEGORY_HEARING_AID", { {0, -0}, {100, 0} } }, // FULL_SCALE_VOLUME_CURVE
+ },
+ },
+};
+
const engineConfig::Config gDefaultEngineConfig = {
1.0,
gOrderedStrategies,
{},
- {}
+ {},
+ gVolumeGroups
};
} // namespace android
diff --git a/services/audiopolicy/engine/common/src/StreamVolumeCurves.cpp b/services/audiopolicy/engine/common/src/StreamVolumeCurves.cpp
new file mode 100644
index 0000000..fe3b000
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/StreamVolumeCurves.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::Engine::StreamVolumeCurves"
+//#define LOG_NDEBUG 0
+
+#include "StreamVolumeCurves.h"
+#include <TypeConverter.h>
+
+namespace android {
+
+void StreamVolumeCurves::dump(String8 *dst, int spaces) const
+{
+ if (mCurves.empty()) {
+ return;
+ }
+ dst->appendFormat("\n%*sStreams dump:\n", spaces, "");
+ dst->appendFormat(
+ "%*sStream Can be muted Index Min Index Max Index Cur [device : index]...\n", spaces + 2, "");
+ for (const auto &streamCurve : mCurves) {
+ streamCurve.second.dump(dst, spaces + 2, false);
+ }
+ dst->appendFormat("\n%*sVolume Curves for Use Cases (aka Stream types) dump:\n", spaces, "");
+ for (const auto &streamCurve : mCurves) {
+ std::string streamTypeLiteral;
+ StreamTypeConverter::toString(streamCurve.first, streamTypeLiteral);
+ dst->appendFormat(
+ " %s (%02d): Curve points for device category (index, attenuation in millibel)\n",
+ streamTypeLiteral.c_str(), streamCurve.first);
+ streamCurve.second.dump(dst, spaces + 2, true);
+ }
+}
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
similarity index 68%
rename from services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
rename to services/audiopolicy/engine/common/src/VolumeCurve.cpp
index 2625733..be2ca73 100644
--- a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
+++ b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
@@ -64,8 +64,7 @@
((float)(mCurvePoints[indexInUiPosition].mIndex -
mCurvePoints[indexInUiPosition - 1].mIndex)) );
- ALOGV("VOLUME mDeviceCategory %d, mStreamType %d vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",
- mDeviceCategory, mStreamType,
+ ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",
mCurvePoints[indexInUiPosition - 1].mIndex, volIdx,
mCurvePoints[indexInUiPosition].mIndex,
((float)mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f), decibels,
@@ -74,55 +73,35 @@
return decibels;
}
-void VolumeCurve::dump(String8 *dst) const
+void VolumeCurve::dump(String8 *dst, int spaces, bool curvePoints) const
{
+ if (!curvePoints) {
+ return;
+ }
dst->append(" {");
for (size_t i = 0; i < mCurvePoints.size(); i++) {
- dst->appendFormat("(%3d, %5d)",
+ dst->appendFormat("%*s (%3d, %5d)", spaces, "",
mCurvePoints[i].mIndex, mCurvePoints[i].mAttenuationInMb);
- dst->append(i == (mCurvePoints.size() - 1) ? " }\n" : ", ");
+ dst->appendFormat(i == (mCurvePoints.size() - 1) ? " }\n" : ", ");
}
}
-void VolumeCurvesForStream::dump(String8 *dst, int spaces = 0, bool curvePoints) const
+void VolumeCurves::dump(String8 *dst, int spaces, bool curvePoints) const
{
if (!curvePoints) {
- dst->appendFormat("%s %02d %02d ",
- mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
- for (size_t i = 0; i < mIndexCur.size(); i++) {
- dst->appendFormat("%04x : %02d, ", mIndexCur.keyAt(i), mIndexCur.valueAt(i));
+ dst->appendFormat("%*s%02d %s %03d %03d ", spaces, "",
+ mStream, mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
+ for (const auto &pair : mIndexCur) {
+ dst->appendFormat("%*s %04x : %02d, ", spaces, "", pair.first, pair.second);
}
- dst->append("\n");
+ dst->appendFormat("\n");
return;
}
-
for (size_t i = 0; i < size(); i++) {
std::string deviceCatLiteral;
DeviceCategoryConverter::toString(keyAt(i), deviceCatLiteral);
- dst->appendFormat("%*s %s :",
- spaces, "", deviceCatLiteral.c_str());
- valueAt(i)->dump(dst);
- }
- dst->append("\n");
-}
-
-void VolumeCurvesCollection::dump(String8 *dst) const
-{
- dst->append("\nStreams dump:\n");
- dst->append(
- " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n");
- for (size_t i = 0; i < size(); i++) {
- dst->appendFormat(" %02zu ", i);
- valueAt(i).dump(dst);
- }
- dst->append("\nVolume Curves for Use Cases (aka Stream types) dump:\n");
- for (size_t i = 0; i < size(); i++) {
- std::string streamTypeLiteral;
- StreamTypeConverter::toString(keyAt(i), streamTypeLiteral);
- dst->appendFormat(
- " %s (%02zu): Curve points for device category (index, attenuation in millibel)\n",
- streamTypeLiteral.c_str(), i);
- valueAt(i).dump(dst, 2, true);
+ dst->appendFormat("%*s %s :", spaces, "", deviceCatLiteral.c_str());
+ valueAt(i)->dump(dst, 2, true);
}
}
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index e18f687..f7caad2 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -45,6 +45,27 @@
using AttributesGroups = std::vector<AttributesGroup>;
+struct CurvePoint {
+ int index;
+ int attenuationInMb;
+};
+using CurvePoints = std::vector<CurvePoint>;
+
+struct VolumeCurve {
+ std::string deviceCategory;
+ CurvePoints curvePoints;
+};
+using VolumeCurves = std::vector<VolumeCurve>;
+
+struct VolumeGroup {
+ std::string name;
+ std::string stream;
+ int indexMin;
+ int indexMax;
+ VolumeCurves volumeCurves;
+};
+using VolumeGroups = std::vector<VolumeGroup>;
+
struct ProductStrategy {
std::string name;
AttributesGroups attributesGroups;
@@ -78,6 +99,7 @@
ProductStrategies productStrategies;
Criteria criteria;
CriterionTypes criterionTypes;
+ VolumeGroups volumeGroups;
};
/** Result of `parse(const char*)` */
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 3aa38cf..227ebd8 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -107,6 +107,35 @@
static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
Collection &collection);
};
+struct VolumeTraits : public BaseSerializerTraits<VolumeCurve, VolumeCurves> {
+ static constexpr const char *tag = "volume";
+ static constexpr const char *collectionTag = "volumes";
+ static constexpr const char *volumePointTag = "point";
+
+ struct Attributes {
+ static constexpr const char *deviceCategory = "deviceCategory";
+ static constexpr const char *reference = "ref"; /**< For volume curves factorization. */
+ };
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+struct VolumeGroupTraits : public BaseSerializerTraits<VolumeGroup, VolumeGroups> {
+ static constexpr const char *tag = "volumeGroup";
+ static constexpr const char *collectionTag = "volumeGroups";
+
+ struct Attributes {
+ static constexpr const char *name = "name";
+ static constexpr const char *stream = "stream"; // For legacy volume curves
+ static constexpr const char *indexMin = "indexMin";
+ static constexpr const char *indexMax = "indexMax";
+ };
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+
+using xmlCharUnique = std::unique_ptr<xmlChar, decltype(xmlFree)>;
using xmlCharUnique = std::unique_ptr<xmlChar, decltype(xmlFree)>;
@@ -383,6 +412,100 @@
return NO_ERROR;
}
+status_t VolumeTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &volumes)
+{
+ std::string deviceCategory = getXmlAttribute(root, Attributes::deviceCategory);
+ if (deviceCategory.empty()) {
+ ALOGW("%s: No %s found", __FUNCTION__, Attributes::deviceCategory);
+ }
+
+ std::string referenceName = getXmlAttribute(root, Attributes::reference);
+ const _xmlNode *ref = NULL;
+ if (!referenceName.empty()) {
+ getReference(xmlDocGetRootElement(doc), ref, referenceName, collectionTag);
+ if (ref == NULL) {
+ ALOGE("%s: No reference Ptr found for %s", __FUNCTION__, referenceName.c_str());
+ return BAD_VALUE;
+ }
+ }
+ // Retrieve curve point from reference element if found or directly from current curve
+ CurvePoints curvePoints;
+ for (const xmlNode *child = referenceName.empty() ?
+ root->xmlChildrenNode : ref->xmlChildrenNode; child != NULL; child = child->next) {
+ if (!xmlStrcmp(child->name, (const xmlChar *)volumePointTag)) {
+ xmlCharUnique pointXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+ if (pointXml == NULL) {
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s=%s", __func__, tag, reinterpret_cast<const char*>(pointXml.get()));
+ std::vector<int> point;
+ collectionFromString<DefaultTraits<int>>(
+ reinterpret_cast<const char*>(pointXml.get()), point, ",");
+ if (point.size() != 2) {
+ ALOGE("%s: Invalid %s: %s", __func__, volumePointTag,
+ reinterpret_cast<const char*>(pointXml.get()));
+ return BAD_VALUE;
+ }
+ curvePoints.push_back({point[0], point[1]});
+ }
+ }
+ volumes.push_back({ deviceCategory, curvePoints });
+ return NO_ERROR;
+}
+
+status_t VolumeGroupTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &volumes)
+{
+ std::string name;
+ std::string stream = {};
+ int indexMin = 0;
+ int indexMax = 0;
+
+ for (const xmlNode *child = root->xmlChildrenNode; child != NULL; child = child->next) {
+ if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::name)) {
+ xmlCharUnique nameXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+ if (nameXml == nullptr) {
+ return BAD_VALUE;
+ }
+ name = reinterpret_cast<const char*>(nameXml.get());
+ }
+ if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::stream)) {
+ xmlCharUnique streamXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+ if (streamXml == nullptr) {
+ return BAD_VALUE;
+ }
+ stream = reinterpret_cast<const char*>(streamXml.get());
+ }
+ if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::indexMin)) {
+ xmlCharUnique indexMinXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+ if (indexMinXml == nullptr) {
+ return BAD_VALUE;
+ }
+ std::string indexMinLiteral(reinterpret_cast<const char*>(indexMinXml.get()));
+ if (!convertTo(indexMinLiteral, indexMin)) {
+ return BAD_VALUE;
+ }
+ }
+ if (not xmlStrcmp(child->name, (const xmlChar *)Attributes::indexMax)) {
+ xmlCharUnique indexMaxXml(xmlNodeListGetString(doc, child->xmlChildrenNode, 1), xmlFree);
+ if (indexMaxXml == nullptr) {
+ return BAD_VALUE;
+ }
+ std::string indexMaxLiteral(reinterpret_cast<const char*>(indexMaxXml.get()));
+ if (!convertTo(indexMaxLiteral, indexMax)) {
+ return BAD_VALUE;
+ }
+ }
+ }
+ ALOGV("%s: group=%s stream=%s indexMin=%d, indexMax=%d",
+ __func__, name.c_str(), stream.c_str(), indexMin, indexMax);
+
+ VolumeCurves groupVolumeCurves;
+ size_t skipped = 0;
+ deserializeCollection<VolumeTraits>(doc, root, groupVolumeCurves, skipped);
+ volumes.push_back({ name, stream, indexMin, indexMax, groupVolumeCurves });
+ return NO_ERROR;
+}
+
ParsingResult parse(const char* path) {
xmlDocPtr doc;
doc = xmlParseFile(path);
@@ -414,6 +537,9 @@
doc, cur, config->criteria, nbSkippedElements);
deserializeCollection<CriterionTypeTraits>(
doc, cur, config->criterionTypes, nbSkippedElements);
+ deserializeCollection<VolumeGroupTraits>(
+ doc, cur, config->volumeGroups, nbSkippedElements);
+
return {std::move(config), nbSkippedElements};
}
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 498cc3b..c9e9507 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -18,6 +18,7 @@
#include <AudioPolicyManagerObserver.h>
#include <media/AudioProductStrategy.h>
+#include <IVolumeCurves.h>
#include <policy.h>
#include <Volume.h>
#include <HwModule.h>
@@ -234,6 +235,21 @@
*/
virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const = 0;
+ /**
+ * @brief getVolumeCurvesForAttributes retrieves the Volume Curves interface for the
+ * requested Audio Attributes.
+ * @param attr to be considered
+ * @return IVolumeCurves interface pointer if found, nullptr otherwise
+ */
+ virtual IVolumeCurves *getVolumeCurvesForAttributes(const audio_attributes_t &attr) = 0;
+
+ /**
+ * @brief getVolumeCurvesForStreamType retrieves the Volume Curves interface for the stream
+ * @param stream to be considered
+ * @return IVolumeCurves interface pointer if found, nullptr otherwise
+ */
+ virtual IVolumeCurves *getVolumeCurvesForStreamType(audio_stream_type_t stream) = 0;
+
virtual void dump(String8 *dst) const = 0;
protected:
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
index b7902cf..43ba625 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
@@ -16,7 +16,6 @@
#pragma once
-#include <IVolumeCurvesCollection.h>
#include <AudioGain.h>
#include <AudioPort.h>
#include <AudioPatch.h>
@@ -51,8 +50,6 @@
virtual const DeviceVector &getAvailableInputDevices() const = 0;
- virtual IVolumeCurvesCollection &getVolumeCurves() = 0;
-
virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const = 0;
protected:
diff --git a/services/audiopolicy/engineconfigurable/Android.mk b/services/audiopolicy/engineconfigurable/Android.mk
index bbd9688..2b7e4c8 100644
--- a/services/audiopolicy/engineconfigurable/Android.mk
+++ b/services/audiopolicy/engineconfigurable/Android.mk
@@ -12,6 +12,8 @@
src/EngineInstance.cpp \
src/Stream.cpp \
src/InputSource.cpp \
+ ../engine/common/src/VolumeCurve.cpp \
+ ../engine/common/src/StreamVolumeCurves.cpp \
../engine/common/src/ProductStrategy.cpp \
../engine/common/src/EngineBase.cpp
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
index 95a2ecc..ef476f7 100644
--- a/services/audiopolicy/engineconfigurable/config/example/Android.mk
+++ b/services/audiopolicy/engineconfigurable/config/example/Android.mk
@@ -20,6 +20,8 @@
LOCAL_REQUIRED_MODULES := \
audio_policy_engine_product_strategies_phone.xml \
+ audio_policy_engine_stream_volumes.xml \
+ audio_policy_engine_default_stream_volumes.xml \
audio_policy_engine_criteria.xml \
audio_policy_engine_criterion_types.xml
@@ -34,6 +36,22 @@
LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
include $(BUILD_PREBUILT)
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_default_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
index ab61d8a..4ca33b4 100644
--- a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
@@ -17,6 +17,8 @@
<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="audio_policy_engine_product_strategies.xml"/>
+ <xi:include href="audio_policy_engine_stream_volumes.xml"/>
+ <xi:include href="audio_policy_engine_default_stream_volumes.xml"/>
</configuration>
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_default_stream_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_default_stream_volumes.xml
new file mode 100644
index 0000000..21e6dd5
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_default_stream_volumes.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Default Volume Tables included by Audio Policy Configuration file -->
+<!-- Full Default Volume table for all device category -->
+<volumes>
+ <reference name="FULL_SCALE_VOLUME_CURVE">
+ <!-- Full Scale reference Volume Curve -->
+ <point>0,0</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="SILENT_VOLUME_CURVE">
+ <point>0,-9600</point>
+ <point>100,-9600</point>
+ </reference>
+ <reference name="DEFAULT_SYSTEM_VOLUME_CURVE">
+ <!-- Default System reference Volume Curve -->
+ <point>1,-2400</point>
+ <point>33,-1800</point>
+ <point>66,-1200</point>
+ <point>100,-600</point>
+ </reference>
+ <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+ <!-- Default Media reference Volume Curve -->
+ <point>1,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE">
+ <!--Default Volume Curve -->
+ <point>1,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE">
+ <!-- Default is Speaker Media Volume Curve -->
+ <point>1,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE">
+ <!-- Default is Speaker System Volume Curve -->
+ <point>1,-4680</point>
+ <point>42,-2070</point>
+ <point>85,-540</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE">
+ <!--Default Volume Curve -->
+ <point>1,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE">
+ <!-- Default is Ext Media System Volume Curve -->
+ <point>1,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-2100</point>
+ <point>100,-1000</point>
+ </reference>
+ <reference name="DEFAULT_HEARING_AID_VOLUME_CURVE">
+ <!-- Default Hearing Aid Volume Curve -->
+ <point>1,-12700</point>
+ <point>20,-8000</point>
+ <point>60,-4000</point>
+ <point>100,0</point>
+ </reference>
+ <!-- **************************************************************** -->
+ <!-- Non-mutable default volume curves: -->
+ <!-- * first point is always for index 0 -->
+ <!-- * attenuation is small enough that stream can still be heard -->
+ <reference name="DEFAULT_NON_MUTABLE_VOLUME_CURVE">
+ <!-- Default non-mutable reference Volume Curve -->
+ <!-- based on DEFAULT_MEDIA_VOLUME_CURVE -->
+ <point>0,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE">
+ <!--Default non-mutable Volume Curve for headset -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE -->
+ <point>0,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE">
+ <!-- Default non-mutable Speaker Volume Curve -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE -->
+ <point>0,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE">
+ <!--Default non-mutable Volume Curve -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE -->
+ <point>0,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE">
+ <!-- Default non-mutable Ext Media System Volume Curve -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE -->
+ <point>0,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-2100</point>
+ <point>100,-1000</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE">
+ <!-- Default non-mutable Hearing Aid Volume Curve -->
+ <!-- based on DEFAULT_HEARING_AID_VOLUME_CURVE -->
+ <point>0,-12700</point>
+ <point>20,-8000</point>
+ <point>60,-4000</point>
+ <point>100,0</point>
+ </reference>
+</volumes>
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
new file mode 100644
index 0000000..73bde1f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_stream_volumes.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Volume section defines a volume curve for a given use case and device category.
+It contains a list of points of this curve expressing the attenuation in Millibels for a given
+volume index from 0 to 100.
+<volume stream=”AUDIO_STREAM_MUSIC” deviceCategory=””>
+<point>0,-9600</point>
+<point>100,0</point>
+</volume>
+-->
+
+<volumeGroups>
+ <volumeGroup>
+ <stream>AUDIO_STREAM_VOICE_CALL</stream>
+ <indexMin>1</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+ <point>0,-2700</point>
+ <point>33,-1800</point>
+ <point>66,-900</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_SYSTEM</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>1,-3000</point>
+ <point>33,-2600</point>
+ <point>66,-2200</point>
+ <point>100,-1800</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>1,-5100</point>
+ <point>57,-2800</point>
+ <point>71,-2500</point>
+ <point>85,-2300</point>
+ <point>100,-2100</point>
+ </volume>
+ <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_RING</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_MUSIC</stream>
+ <indexMin>0</indexMin>
+ <indexMax>25</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_ALARM</stream>
+ <indexMin>1</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_NOTIFICATION</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_BLUETOOTH_SCO</stream>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_ENFORCED_AUDIBLE</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>1,-3000</point>
+ <point>33,-2600</point>
+ <point>66,-2200</point>
+ <point>100,-1800</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>1,-3400</point>
+ <point>71,-2400</point>
+ <point>100,-2000</point>
+ </volume>
+ <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_DTMF</stream>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>1,-3000</point>
+ <point>33,-2600</point>
+ <point>66,-2200</point>
+ <point>100,-1800</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>1,-4000</point>
+ <point>71,-2400</point>
+ <point>100,-1400</point>
+ </volume>
+ <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_TTS</stream>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="SILENT_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_ACCESSIBILITY</stream>
+ <indexMin>1</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_REROUTING</stream>
+ <indexMin>0</indexMin>
+ <indexMax>1</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_PATCH</stream>
+ <indexMin>0</indexMin>
+ <indexMax>1</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+ </volumeGroup>
+</volumeGroups>
+
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 719ef01..89a1694 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -113,7 +113,7 @@
const audio_stream_type_t &profile)
{
if (setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream, profile)) {
- getApmObserver()->getVolumeCurves().switchVolumeCurve(profile, stream);
+ switchVolumeCurve(profile, stream);
return true;
}
return false;
diff --git a/services/audiopolicy/enginedefault/Android.mk b/services/audiopolicy/enginedefault/Android.mk
index 95eac1c..94fa788 100644
--- a/services/audiopolicy/enginedefault/Android.mk
+++ b/services/audiopolicy/enginedefault/Android.mk
@@ -8,6 +8,8 @@
LOCAL_SRC_FILES := \
src/Engine.cpp \
src/EngineInstance.cpp \
+ ../engine/common/src/VolumeCurve.cpp \
+ ../engine/common/src/StreamVolumeCurves.cpp \
../engine/common/src/ProductStrategy.cpp \
../engine/common/src/EngineBase.cpp
diff --git a/services/audiopolicy/enginedefault/config/example/Android.mk b/services/audiopolicy/enginedefault/config/example/Android.mk
index 866466f..f06ee4c 100644
--- a/services/audiopolicy/enginedefault/config/example/Android.mk
+++ b/services/audiopolicy/enginedefault/config/example/Android.mk
@@ -16,7 +16,9 @@
LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
LOCAL_REQUIRED_MODULES := \
- audio_policy_engine_product_strategies_phone.xml
+ audio_policy_engine_product_strategies_phone.xml \
+ audio_policy_engine_stream_volumes.xml \
+ audio_policy_engine_default_stream_volumes.xml
include $(BUILD_PREBUILT)
@@ -29,4 +31,20 @@
LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
include $(BUILD_PREBUILT)
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_default_stream_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
index ab61d8a..4ca33b4 100644
--- a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
@@ -17,6 +17,8 @@
<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="audio_policy_engine_product_strategies.xml"/>
+ <xi:include href="audio_policy_engine_stream_volumes.xml"/>
+ <xi:include href="audio_policy_engine_default_stream_volumes.xml"/>
</configuration>
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_default_stream_volumes.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_default_stream_volumes.xml
new file mode 100644
index 0000000..21e6dd5
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_default_stream_volumes.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Default Volume Tables included by Audio Policy Configuration file -->
+<!-- Full Default Volume table for all device category -->
+<volumes>
+ <reference name="FULL_SCALE_VOLUME_CURVE">
+ <!-- Full Scale reference Volume Curve -->
+ <point>0,0</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="SILENT_VOLUME_CURVE">
+ <point>0,-9600</point>
+ <point>100,-9600</point>
+ </reference>
+ <reference name="DEFAULT_SYSTEM_VOLUME_CURVE">
+ <!-- Default System reference Volume Curve -->
+ <point>1,-2400</point>
+ <point>33,-1800</point>
+ <point>66,-1200</point>
+ <point>100,-600</point>
+ </reference>
+ <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+ <!-- Default Media reference Volume Curve -->
+ <point>1,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE">
+ <!--Default Volume Curve -->
+ <point>1,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE">
+ <!-- Default is Speaker Media Volume Curve -->
+ <point>1,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE">
+ <!-- Default is Speaker System Volume Curve -->
+ <point>1,-4680</point>
+ <point>42,-2070</point>
+ <point>85,-540</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE">
+ <!--Default Volume Curve -->
+ <point>1,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE">
+ <!-- Default is Ext Media System Volume Curve -->
+ <point>1,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-2100</point>
+ <point>100,-1000</point>
+ </reference>
+ <reference name="DEFAULT_HEARING_AID_VOLUME_CURVE">
+ <!-- Default Hearing Aid Volume Curve -->
+ <point>1,-12700</point>
+ <point>20,-8000</point>
+ <point>60,-4000</point>
+ <point>100,0</point>
+ </reference>
+ <!-- **************************************************************** -->
+ <!-- Non-mutable default volume curves: -->
+ <!-- * first point is always for index 0 -->
+ <!-- * attenuation is small enough that stream can still be heard -->
+ <reference name="DEFAULT_NON_MUTABLE_VOLUME_CURVE">
+ <!-- Default non-mutable reference Volume Curve -->
+ <!-- based on DEFAULT_MEDIA_VOLUME_CURVE -->
+ <point>0,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE">
+ <!--Default non-mutable Volume Curve for headset -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE -->
+ <point>0,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE">
+ <!-- Default non-mutable Speaker Volume Curve -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE -->
+ <point>0,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE">
+ <!--Default non-mutable Volume Curve -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE -->
+ <point>0,-4950</point>
+ <point>33,-3350</point>
+ <point>66,-1700</point>
+ <point>100,0</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE">
+ <!-- Default non-mutable Ext Media System Volume Curve -->
+ <!-- based on DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE -->
+ <point>0,-5800</point>
+ <point>20,-4000</point>
+ <point>60,-2100</point>
+ <point>100,-1000</point>
+ </reference>
+ <reference name="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE">
+ <!-- Default non-mutable Hearing Aid Volume Curve -->
+ <!-- based on DEFAULT_HEARING_AID_VOLUME_CURVE -->
+ <point>0,-12700</point>
+ <point>20,-8000</point>
+ <point>60,-4000</point>
+ <point>100,0</point>
+ </reference>
+</volumes>
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
new file mode 100644
index 0000000..73bde1f
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_stream_volumes.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Volume section defines a volume curve for a given use case and device category.
+It contains a list of points of this curve expressing the attenuation in Millibels for a given
+volume index from 0 to 100.
+<volume stream=”AUDIO_STREAM_MUSIC” deviceCategory=””>
+<point>0,-9600</point>
+<point>100,0</point>
+</volume>
+-->
+
+<volumeGroups>
+ <volumeGroup>
+ <stream>AUDIO_STREAM_VOICE_CALL</stream>
+ <indexMin>1</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+ <point>0,-2700</point>
+ <point>33,-1800</point>
+ <point>66,-900</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_SYSTEM</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>1,-3000</point>
+ <point>33,-2600</point>
+ <point>66,-2200</point>
+ <point>100,-1800</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>1,-5100</point>
+ <point>57,-2800</point>
+ <point>71,-2500</point>
+ <point>85,-2300</point>
+ <point>100,-2100</point>
+ </volume>
+ <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_RING</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_MUSIC</stream>
+ <indexMin>0</indexMin>
+ <indexMax>25</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_ALARM</stream>
+ <indexMin>1</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_NOTIFICATION</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_BLUETOOTH_SCO</stream>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_ENFORCED_AUDIBLE</stream>
+ <indexMin>0</indexMin>
+ <indexMax>7</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>1,-3000</point>
+ <point>33,-2600</point>
+ <point>66,-2200</point>
+ <point>100,-1800</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>1,-3400</point>
+ <point>71,-2400</point>
+ <point>100,-2000</point>
+ </volume>
+ <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_DTMF</stream>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>1,-3000</point>
+ <point>33,-2600</point>
+ <point>66,-2200</point>
+ <point>100,-1800</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>1,-4000</point>
+ <point>71,-2400</point>
+ <point>100,-1400</point>
+ </volume>
+ <!--volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/-->
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_TTS</stream>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="SILENT_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_ACCESSIBILITY</stream>
+ <indexMin>1</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_REROUTING</stream>
+ <indexMin>0</indexMin>
+ <indexMax>1</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+ </volumeGroup>
+
+ <volumeGroup>
+ <stream>AUDIO_STREAM_PATCH</stream>
+ <indexMin>0</indexMin>
+ <indexMax>1</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
+ <volume deviceCategory="DEVICE_CATEGORY_HEARING_AID" ref="FULL_SCALE_VOLUME_CURVE"/>
+ </volumeGroup>
+</volumeGroups>
+
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 43023a8..fd6a013 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -66,35 +66,6 @@
}
}
-status_t Engine::setPhoneState(audio_mode_t state)
-{
- ALOGV("setPhoneState() state %d", state);
-
- if (state < 0 || state >= AUDIO_MODE_CNT) {
- ALOGW("setPhoneState() invalid state %d", state);
- return BAD_VALUE;
- }
-
- if (state == getPhoneState()) {
- ALOGW("setPhoneState() setting same state %d", state);
- return BAD_VALUE;
- }
-
- // store previous phone state for management of sonification strategy below
- int oldState = getPhoneState();
- EngineBase::setPhoneState(state);
-
- if (!is_state_in_call(oldState) && is_state_in_call(state)) {
- ALOGV(" Entering call in setPhoneState()");
- getApmObserver()->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
- AUDIO_STREAM_DTMF);
- } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
- ALOGV(" Exiting call in setPhoneState()");
- getApmObserver()->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
- }
- return NO_ERROR;
-}
-
status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
{
switch(usage) {
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 15fc358..d8a3698 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -55,8 +55,6 @@
///
/// from EngineBase, so from AudioPolicyManagerInterface
///
- status_t setPhoneState(audio_mode_t mode) override;
-
status_t setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) override;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5b752ea..b563a04 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1710,7 +1710,7 @@
// apply volume rules for current stream and device if necessary
checkAndSetVolume(stream,
- mVolumeCurves->getVolumeIndex(stream, outputDesc->devices().types()),
+ getVolumeCurves(stream).getVolumeIndex(outputDesc->devices().types()),
outputDesc,
outputDesc->devices().types());
@@ -2382,14 +2382,15 @@
ALOGE("%s for stream %d: invalid min %d or max %d", __func__, stream , indexMin, indexMax);
return;
}
- mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
+ // @todo: our proposal now use XML to store Indexes Min & Max
+ getVolumeCurves(stream).initVolume(indexMin, indexMax);
// initialize 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)) {
continue;
}
- mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
+ getVolumeCurves((audio_stream_type_t)curStream).initVolume(indexMin, indexMax);
}
}
@@ -2397,13 +2398,13 @@
int index,
audio_devices_t device)
{
-
+ auto &curves = getVolumeCurves(stream);
// VOICE_CALL and BLUETOOTH_SCO stream have minVolumeIndex > 0 but
// can be muted directly by an app that has MODIFY_PHONE_STATE permission.
- if (((index < mVolumeCurves->getVolumeIndexMin(stream)) &&
+ if (((index < curves.getVolumeIndexMin()) &&
!((stream == AUDIO_STREAM_VOICE_CALL || stream == AUDIO_STREAM_BLUETOOTH_SCO) &&
index == 0)) ||
- (index > mVolumeCurves->getVolumeIndexMax(stream))) {
+ (index > curves.getVolumeIndexMax())) {
return BAD_VALUE;
}
if (!audio_is_output_device(device)) {
@@ -2411,7 +2412,7 @@
}
// Force max volume if stream cannot be muted
- if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
+ if (!curves.canBeMuted()) index = curves.getVolumeIndexMax();
ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
stream, device, index);
@@ -2421,7 +2422,8 @@
if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
continue;
}
- mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
+ auto &curCurves = getVolumeCurves(static_cast<audio_stream_type_t>(curStream));
+ curCurves.addCurrentVolumeIndex(device, index);
}
// update volume on all outputs and streams matching the following:
@@ -2455,8 +2457,7 @@
curStreamDevice |= device;
applyVolume = (Volume::getDeviceForVolume(curDevice) & curStreamDevice) != 0;
} else {
- applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
- stream, curStreamDevice);
+ applyVolume = !curves.hasVolumeIndexForDevice(curStreamDevice);
}
// rescale index before applying to curStream as ranges may be different for
// stream and curStream
@@ -2465,9 +2466,10 @@
//FIXME: workaround for truncated touch sounds
// delayed volume change for system stream to be removed when the problem is
// handled by system UI
- status_t volStatus =
- checkAndSetVolume((audio_stream_type_t)curStream, idx, desc, curDevice,
- (stream == AUDIO_STREAM_SYSTEM) ? TOUCH_SOUND_FIXED_DELAY_MS : 0);
+ status_t volStatus = checkAndSetVolume(
+ (audio_stream_type_t)curStream, idx, desc, curDevice,
+ (stream == AUDIO_STREAM_SYSTEM) ?
+ TOUCH_SOUND_FIXED_DELAY_MS : 0);
if (volStatus != NO_ERROR) {
status = volStatus;
}
@@ -2494,7 +2496,7 @@
}
device = Volume::getDeviceForVolume(device);
- *index = mVolumeCurves->getVolumeIndex(stream, device);
+ *index = getVolumeCurves(stream).getVolumeIndex(device);
ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
return NO_ERROR;
}
@@ -2927,7 +2929,6 @@
mHwModulesAll.dump(dst);
mOutputs.dump(dst);
mInputs.dump(dst);
- mVolumeCurves->dump(dst);
mEffects.dump(dst);
mAudioPatches.dump(dst);
mPolicyMixes.dump(dst);
@@ -4114,9 +4115,7 @@
mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
- mVolumeCurves(new VolumeCurvesCollection()),
- mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
- mDefaultOutputDevice, static_cast<VolumeCurvesCollection*>(mVolumeCurves.get())),
+ mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice),
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
@@ -4150,8 +4149,6 @@
}
status_t AudioPolicyManager::initialize() {
- mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
-
// Once policy config has been parsed, retrieve an instance of the engine and initialize it.
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
@@ -5532,7 +5529,8 @@
int index,
audio_devices_t device)
{
- float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
+ auto &curves = getVolumeCurves(stream);
+ float volumeDB = curves.volIndexToDb(Volume::getDeviceCategory(device), index);
// 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
@@ -5557,8 +5555,7 @@
case AUDIO_STREAM_ENFORCED_AUDIBLE:
case AUDIO_STREAM_DTMF:
case AUDIO_STREAM_ACCESSIBILITY: {
- int voiceVolumeIndex =
- mVolumeCurves->getVolumeIndex(AUDIO_STREAM_VOICE_CALL, device);
+ int voiceVolumeIndex = getVolumeCurves(AUDIO_STREAM_VOICE_CALL).getVolumeIndex(device);
const float maxVoiceVolDb =
computeVolume(AUDIO_STREAM_VOICE_CALL, voiceVolumeIndex, device)
+ IN_CALL_EARPIECE_HEADROOM_DB;
@@ -5592,7 +5589,7 @@
|| ((stream == AUDIO_STREAM_ENFORCED_AUDIBLE) &&
(mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
AUDIO_POLICY_FORCE_NONE))) &&
- mVolumeCurves->canBeMuted(stream)) {
+ getVolumeCurves(stream).canBeMuted()) {
// 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
@@ -5603,9 +5600,8 @@
mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
nullptr, true /*fromCache*/).types();
float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
- mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
- musicDevice),
- musicDevice);
+ getVolumeCurves(AUDIO_STREAM_MUSIC).getVolumeIndex(musicDevice),
+ musicDevice);
float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
if (volumeDB > minVolDB) {
@@ -5640,10 +5636,12 @@
if (srcStream == dstStream) {
return srcIndex;
}
- float minSrc = (float)mVolumeCurves->getVolumeIndexMin(srcStream);
- float maxSrc = (float)mVolumeCurves->getVolumeIndexMax(srcStream);
- float minDst = (float)mVolumeCurves->getVolumeIndexMin(dstStream);
- float maxDst = (float)mVolumeCurves->getVolumeIndexMax(dstStream);
+ auto &srcCurves = getVolumeCurves(srcStream);
+ auto &dstCurves = getVolumeCurves(dstStream);
+ float minSrc = (float)srcCurves.getVolumeIndexMin();
+ float maxSrc = (float)srcCurves.getVolumeIndexMax();
+ float minDst = (float)dstCurves.getVolumeIndexMin();
+ float maxDst = (float)dstCurves.getVolumeIndexMax();
// preserve mute request or correct range
if (srcIndex < minSrc) {
@@ -5658,11 +5656,11 @@
}
status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
- int index,
- const sp<AudioOutputDescriptor>& outputDesc,
- audio_devices_t device,
- int delayMs,
- bool force)
+ int index,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ audio_devices_t device,
+ int delayMs,
+ bool force)
{
// do not change actual stream volume if the stream is muted
if (outputDesc->isMuted(streamToVolumeSource(stream))) {
@@ -5698,7 +5696,7 @@
float voiceVolume;
// Force voice volume to max for bluetooth SCO as volume is managed by the headset
if (stream == AUDIO_STREAM_VOICE_CALL) {
- voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);
+ voiceVolume = (float)index/(float)getVolumeCurves(stream).getVolumeIndexMax();
} else {
voiceVolume = 1.0;
}
@@ -5721,7 +5719,7 @@
for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
checkAndSetVolume((audio_stream_type_t)stream,
- mVolumeCurves->getVolumeIndex((audio_stream_type_t)stream, device),
+ getVolumeCurves((audio_stream_type_t)stream).getVolumeIndex(device),
outputDesc,
device,
delayMs,
@@ -5754,10 +5752,10 @@
ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
stream, on, outputDesc->getMuteCount(stream), device);
-
+ auto &curves = getVolumeCurves(stream);
if (on) {
if (!outputDesc->isMuted(streamToVolumeSource(stream))) {
- if (mVolumeCurves->canBeMuted(stream) &&
+ if (curves.canBeMuted() &&
((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
(mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
@@ -5772,7 +5770,7 @@
}
if (outputDesc->decMuteCount(streamToVolumeSource(stream)) == 0) {
checkAndSetVolume(stream,
- mVolumeCurves->getVolumeIndex(stream, device),
+ curves.getVolumeIndex(device),
outputDesc,
device,
delayMs);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 70ad6ac..06a1f3e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -49,7 +49,7 @@
#include <AudioPolicyMix.h>
#include <EffectDescriptor.h>
#include <SoundTriggerSession.h>
-#include <VolumeCurve.h>
+#include "TypeConverter.h"
namespace android {
@@ -310,12 +310,24 @@
{
return mAvailableInputDevices;
}
- virtual IVolumeCurvesCollection &getVolumeCurves() { return *mVolumeCurves; }
virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const
{
return mDefaultOutputDevice;
}
+ IVolumeCurves &getVolumeCurves(const audio_attributes_t &attr)
+ {
+ auto *curves = mEngine->getVolumeCurvesForAttributes(attr);
+ ALOG_ASSERT(curves != nullptr, "No curves for attributes %s", toString(attr).c_str());
+ return *curves;
+ }
+ IVolumeCurves &getVolumeCurves(audio_stream_type_t stream)
+ {
+ auto *curves = mEngine->getVolumeCurvesForStreamType(stream);
+ ALOG_ASSERT(curves != nullptr, "No curves for stream %s", toString(stream).c_str());
+ return *curves;
+ }
+
void addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc);
void removeOutput(audio_io_handle_t output);
void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
@@ -624,12 +636,12 @@
float mLastVoiceVolume; // last voice volume value sent to audio HAL
bool mA2dpSuspended; // true if A2DP output is suspended
- std::unique_ptr<IVolumeCurvesCollection> mVolumeCurves; // Volume Curves per use case and device category
EffectDescriptorCollection mEffects; // list of registered audio effects
sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
HwModuleCollection mHwModules; // contains only modules that have been loaded successfully
HwModuleCollection mHwModulesAll; // normally not needed, used during construction and for
// dumps
+
AudioPolicyConfig mConfig;
std::atomic<uint32_t> mAudioPortGeneration;