audio policy: move volume table to XML file

This patch allows to store in XML file volume tables.
The compatibility is maintained for legacy conf file.
Configurable Engine is only compatible with new XML conf.
This patch removes from configurable engine Structure / Settings the volume
table but keep the configurabllity of switching volume profiles from
one another according to criteria like phone state...
(ex: DTMF stream type is following Voice Profile in call)

Change-Id: I78c91bc3378b6c47202abe7b5c1c1e011ff62eed
Signed-off-by: François Gaffie <francois.gaffie@intel.com>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 074af50..7d585c0 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -115,18 +115,6 @@
     return (mApmObserver != NULL)? NO_ERROR : NO_INIT;
 }
 
-bool Engine::setVolumeProfileForStream(const audio_stream_type_t &streamType,
-                                       device_category deviceCategory,
-                                       const VolumeCurvePoints &points)
-{
-    Stream *stream = getFromCollection<audio_stream_type_t>(streamType);
-    if (stream == NULL) {
-        ALOGE("%s: stream %d not found", __FUNCTION__, streamType);
-        return false;
-    }
-    return stream->setVolumeProfile(deviceCategory, points) == NO_ERROR;
-}
-
 template <typename Key>
 Element<Key> *Engine::getFromCollection(const Key &key) const
 {
@@ -188,6 +176,18 @@
     return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(strategy);
 }
 
+bool Engine::PluginInterfaceImpl::setVolumeProfileForStream(const audio_stream_type_t &stream,
+                                                            const audio_stream_type_t &profile)
+{
+    if (mPolicyEngine->setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream,
+                                                                                   profile)) {
+        mPolicyEngine->mApmObserver->getVolumeCurves().switchVolumeCurve(profile, stream);
+        return true;
+    }
+    return false;
+}
+
+
 template <typename Property, typename Key>
 bool Engine::setPropertyForKey(const Property &property, const Key &key)
 {
@@ -199,32 +199,6 @@
     return element->template set<Property>(property) == NO_ERROR;
 }
 
-float Engine::volIndexToDb(device_category category,
-                           audio_stream_type_t streamType,
-                           int indexInUi)
-{
-    Stream *stream = getFromCollection<audio_stream_type_t>(streamType);
-    if (stream == NULL) {
-        ALOGE("%s: Element indexed by key=%d not found", __FUNCTION__, streamType);
-        return 1.0f;
-    }
-    return stream->volIndexToDb(category, indexInUi);
-}
-
-status_t Engine::initStreamVolume(audio_stream_type_t streamType,
-                                           int indexMin, int indexMax)
-{
-    Stream *stream = getFromCollection<audio_stream_type_t>(streamType);
-    if (stream == NULL) {
-        ALOGE("%s: Stream Type %d not found", __FUNCTION__, streamType);
-        return BAD_TYPE;
-    }
-    mApmObserver->getStreamDescriptors().setVolumeIndexMin(streamType, indexMin);
-    mApmObserver->getStreamDescriptors().setVolumeIndexMax(streamType, indexMax);
-
-    return stream->initVolume(indexMin, indexMax);
-}
-
 status_t Engine::setPhoneState(audio_mode_t mode)
 {
     return mPolicyParameterMgr->setPhoneState(mode);
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 8a15e5e..bc5e035 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -88,20 +88,6 @@
         {
             return mPolicyEngine->setDeviceConnectionState(devDesc, state);
         }
-        virtual status_t initStreamVolume(audio_stream_type_t stream,
-                                                   int indexMin, int indexMax)
-        {
-            return mPolicyEngine->initStreamVolume(stream, indexMin, indexMax);
-        }
-
-        virtual void initializeVolumeCurves(bool /*isSpeakerDrcEnabled*/) {}
-
-        virtual float volIndexToDb(device_category deviceCategory,
-                                   audio_stream_type_t stream,
-                                   int indexInUi)
-        {
-            return mPolicyEngine->volIndexToDb(deviceCategory, stream, indexInUi);
-        }
 
     private:
         Engine *mPolicyEngine;
@@ -141,11 +127,7 @@
                                                                                            stream);
         }
         virtual bool setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                               device_category deviceCategory,
-                                               const VolumeCurvePoints &points)
-        {
-            return mPolicyEngine->setVolumeProfileForStream(stream, deviceCategory, points);
-        }
+                                               const audio_stream_type_t &volumeProfile);
 
         virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy)
         {
@@ -181,9 +163,6 @@
     audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
     status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
                                       audio_policy_dev_state_t state);
-    float volIndexToDb(device_category category, audio_stream_type_t stream, int indexInUi);
-    status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
-
     StrategyCollection mStrategyCollection; /**< Strategies indexed by their enum id. */
     StreamCollection mStreamCollection; /**< Streams indexed by their enum id.  */
     UsageCollection mUsageCollection; /**< Usages indexed by their enum id. */
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.cpp b/services/audiopolicy/engineconfigurable/src/Stream.cpp
index 3bd5220..0ed364f 100755
--- a/services/audiopolicy/engineconfigurable/src/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Stream.cpp
@@ -62,91 +62,22 @@
     return mApplicableStrategy;
 }
 
-status_t Element<audio_stream_type_t>::setVolumeProfile(device_category category,
-                                                        const VolumeCurvePoints &points)
+template <>
+status_t Element<audio_stream_type_t>::set<audio_stream_type_t>(audio_stream_type_t volumeProfile)
 {
-    ALOGD("%s: adding volume profile for %s for device category %d, points nb =%zu", __FUNCTION__,
-          getName().c_str(), category, points.size());
-    mVolumeProfiles[category] = points;
-
-    for (size_t i = 0; i < points.size(); i++) {
-        ALOGV("%s: %s cat=%d curve index =%zu Index=%d dBAttenuation=%f",
-              __FUNCTION__, getName().c_str(), category, i, points[i].mIndex,
-             points[i].mDBAttenuation);
-    }
-    return NO_ERROR;
-}
-
-status_t Element<audio_stream_type_t>::initVolume(int indexMin, int indexMax)
-{
-    ALOGV("initStreamVolume() stream %s, min %d, max %d", getName().c_str(), indexMin, indexMax);
-    if (indexMin < 0 || indexMin >= indexMax) {
-        ALOGW("initStreamVolume() invalid index limits for stream %s, min %d, max %d",
-              getName().c_str(), indexMin, indexMax);
+    if (volumeProfile >= AUDIO_STREAM_CNT) {
         return BAD_VALUE;
     }
-    mIndexMin = indexMin;
-    mIndexMax = indexMax;
-
+    mVolumeProfile = volumeProfile;
+    ALOGD("%s: 0x%X for Stream %s", __FUNCTION__, mVolumeProfile, getName().c_str());
     return NO_ERROR;
 }
 
-float Element<audio_stream_type_t>::volIndexToDb(device_category deviceCategory, int indexInUi)
+template <>
+audio_stream_type_t Element<audio_stream_type_t>::get<audio_stream_type_t>() const
 {
-    VolumeProfileConstIterator it = mVolumeProfiles.find(deviceCategory);
-    if (it == mVolumeProfiles.end()) {
-        ALOGE("%s: device category %d not found for stream %s", __FUNCTION__, deviceCategory,
-              getName().c_str());
-        return 0.0f;
-    }
-    const VolumeCurvePoints curve = mVolumeProfiles[deviceCategory];
-    if (curve.size() != Volume::VOLCNT) {
-        ALOGE("%s: invalid profile for category %d and for stream %s", __FUNCTION__, deviceCategory,
-              getName().c_str());
-        return 0.0f;
-    }
-
-    // the volume index in the UI is relative to the min and max volume indices for this stream type
-    int nbSteps = 1 + curve[Volume::VOLMAX].mIndex -
-            curve[Volume::VOLMIN].mIndex;
-
-    if (mIndexMax - mIndexMin == 0) {
-        ALOGE("%s: Invalid volume indexes Min=Max=%d", __FUNCTION__, mIndexMin);
-        return 0.0f;
-    }
-    int volIdx = (nbSteps * (indexInUi - mIndexMin)) /
-            (mIndexMax - mIndexMin);
-
-    // find what part of the curve this index volume belongs to, or if it's out of bounds
-    int segment = 0;
-    if (volIdx < curve[Volume::VOLMIN].mIndex) {         // out of bounds
-        return VOLUME_MIN_DB;
-    } else if (volIdx < curve[Volume::VOLKNEE1].mIndex) {
-        segment = 0;
-    } else if (volIdx < curve[Volume::VOLKNEE2].mIndex) {
-        segment = 1;
-    } else if (volIdx <= curve[Volume::VOLMAX].mIndex) {
-        segment = 2;
-    } else {                                                               // out of bounds
-        return 0.0f;
-    }
-
-    // linear interpolation in the attenuation table in dB
-    float decibels = curve[segment].mDBAttenuation +
-            ((float)(volIdx - curve[segment].mIndex)) *
-                ( (curve[segment+1].mDBAttenuation -
-                        curve[segment].mDBAttenuation) /
-                    ((float)(curve[segment+1].mIndex -
-                            curve[segment].mIndex)) );
-
-    ALOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",
-            curve[segment].mIndex, volIdx,
-            curve[segment+1].mIndex,
-            curve[segment].mDBAttenuation,
-            decibels,
-            curve[segment+1].mDBAttenuation);
-
-    return decibels;
+    ALOGV("%s: 0x%X for Stream %s", __FUNCTION__, mVolumeProfile, getName().c_str());
+    return mVolumeProfile;
 }
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.h b/services/audiopolicy/engineconfigurable/src/Stream.h
index b103f89..6902003 100755
--- a/services/audiopolicy/engineconfigurable/src/Stream.h
+++ b/services/audiopolicy/engineconfigurable/src/Stream.h
@@ -18,7 +18,6 @@
 
 #include "Element.h"
 #include "EngineDefinition.h"
-#include <Volume.h>
 #include <RoutingStrategy.h>
 #include <map>
 
@@ -32,17 +31,10 @@
 template <>
 class Element<audio_stream_type_t>
 {
-private:
-    typedef std::map<device_category, VolumeCurvePoints> VolumeProfiles;
-    typedef VolumeProfiles::iterator VolumeProfileIterator;
-    typedef VolumeProfiles::const_iterator VolumeProfileConstIterator;
-
 public:
     Element(const std::string &name)
         : mName(name),
-          mApplicableStrategy(STRATEGY_MEDIA),
-          mIndexMin(0),
-          mIndexMax(1)
+          mApplicableStrategy(STRATEGY_MEDIA)
     {}
     ~Element() {}
 
@@ -79,12 +71,6 @@
     template <typename Property>
     status_t set(Property property);
 
-    status_t setVolumeProfile(device_category category, const VolumeCurvePoints &points);
-
-    float volIndexToDb(device_category deviceCategory, int indexInUi);
-
-    status_t initVolume(int indexMin, int indexMax);
-
 private:
     /* Copy facilities are put private to disable copy. */
     Element(const Element &object);
@@ -95,16 +81,7 @@
 
     routing_strategy mApplicableStrategy; /**< Applicable strategy for this stream. */
 
-    /**
-     * Collection of volume profiles indexed by the stream type.
-     * Volume is the only reason why the stream profile was not removed from policy when introducing
-     * attributes.
-     */
-    VolumeProfiles mVolumeProfiles;
-
-    int mIndexMin;
-
-    int mIndexMax;
+    audio_stream_type_t mVolumeProfile; /**< Volume Profile followed by this stream. */
 };
 
 typedef Element<audio_stream_type_t> Stream;