audio policy service: Add introspection API to retrieve AudioProductStrategies

This CL adds required introspection APIs to deal with product strategies:

-getter of the collection of product strategies
-helper function to return the strategy associated to a given attributes.
This API is mandatory to avoid duplicating the logic that compiles the strategy
for a given Audio Attributes structure.

Test: make

Change-Id: I0e107570a44227bb52a4f359954c93215d4f8bae
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 32898b1..5c33fb3 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -65,6 +65,8 @@
 
     StrategyVector getOrderedProductStrategies() const override;
 
+    status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const override;
+
     void dump(String8 *dst) const override;
 
 
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index 66ae86e..72505b2 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -49,6 +49,8 @@
 
     void addAttributes(const AudioAttributes &audioAttributes);
 
+    std::vector<android::AudioAttributes> listAudioAttributes() const;
+
     std::string getName() const { return mName; }
     AttributesVector getAudioAttributes() const;
     product_strategy_t getId() const { return mId; }
@@ -87,20 +89,6 @@
 
     void dump(String8 *dst, int spaces = 0) const;
 
-    /**
-     * @brief attributesMatches: checks if client attributes matches with a reference attributes
-     * "matching" means the usage shall match if reference attributes has a defined usage, AND
-     * content type shall match if reference attributes has a defined content type AND
-     * flags shall match if reference attributes has defined flags AND
-     * tags shall match if reference attributes has defined tags.
-     * Reference attributes "default" shall not be considered as a "true" case. This convention
-     * is used to identify the default strategy.
-     * @param refAttributes to be considered
-     * @param clientAttritubes to be considered
-     * @return true if matching, false otherwise
-     */
-    static bool attributesMatches(const audio_attributes_t refAttributes,
-                                  const audio_attributes_t clientAttritubes);
 private:
     std::string mName;
 
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 0f4d5a5..755f2a8 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -162,6 +162,17 @@
                 mProductStrategies.at(ps)->getAudioAttributes() : AttributesVector();
 }
 
+status_t EngineBase::listAudioProductStrategies(AudioProductStrategyVector &strategies) const
+{
+    for (const auto &iter : mProductStrategies) {
+        const auto &productStrategy = iter.second;
+        strategies.push_back(
+        {productStrategy->getName(), productStrategy->listAudioAttributes(),
+         productStrategy->getId()});
+    }
+    return NO_ERROR;
+}
+
 void EngineBase::dump(String8 *dst) const
 {
     mProductStrategies.dump(dst, 2);
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index a3edb39..71607d1 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -40,6 +40,15 @@
     mAttributesVector.push_back(audioAttributes);
 }
 
+std::vector<android::AudioAttributes> ProductStrategy::listAudioAttributes() const
+{
+    std::vector<android::AudioAttributes> androidAa;
+    for (const auto &attr : mAttributesVector) {
+        androidAa.push_back({attr.mGroupId, attr.mStream, attr.mAttributes});
+    }
+    return androidAa;
+}
+
 AttributesVector ProductStrategy::getAudioAttributes() const
 {
     AttributesVector attrVector;
@@ -52,42 +61,19 @@
     return { AUDIO_ATTRIBUTES_INITIALIZER };
 }
 
-// @todo: all flags required to match?
-//        all tags required to match?
-/* static */
-bool ProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
-                                        const audio_attributes_t clientAttritubes)
-{
-    if (refAttributes == defaultAttr) {
-        // The default product strategy is the strategy that holds default attributes by convention.
-        // All attributes that fail to match will follow the default strategy for routing.
-        // Choosing the default must be done as a fallback, the attributes match shall not
-        // selects the default.
-        return false;
-    }
-    return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
-            (clientAttritubes.usage == refAttributes.usage)) &&
-            ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
-             (clientAttritubes.content_type == refAttributes.content_type)) &&
-            ((refAttributes.flags == AUDIO_OUTPUT_FLAG_NONE) ||
-             (clientAttritubes.flags != AUDIO_OUTPUT_FLAG_NONE &&
-            (clientAttritubes.flags & refAttributes.flags) == clientAttritubes.flags)) &&
-            ((strlen(refAttributes.tags) == 0) ||
-             (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
-}
-
 bool ProductStrategy::matches(const audio_attributes_t attr) const
 {
     return std::find_if(begin(mAttributesVector), end(mAttributesVector),
                         [&attr](const auto &supportedAttr) {
-        return attributesMatches(supportedAttr.mAttributes, attr); }) != end(mAttributesVector);
+        return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr);
+    }) != end(mAttributesVector);
 }
 
 audio_stream_type_t ProductStrategy::getStreamTypeForAttributes(const audio_attributes_t &attr) const
 {
     const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
                                    [&attr](const auto &supportedAttr) {
-        return attributesMatches(supportedAttr.mAttributes, attr); });
+        return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr); });
     return iter != end(mAttributesVector) ? iter->mStream : AUDIO_STREAM_DEFAULT;
 }
 
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 9f5fb0c2..18ba2c8 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -18,7 +18,7 @@
 
 #include <AudioPolicyManagerObserver.h>
 #include <RoutingStrategy.h>
-#include <media/AudioCommonTypes.h>
+#include <media/AudioProductStrategy.h>
 #include <policy.h>
 #include <Volume.h>
 #include <HwModule.h>
@@ -270,6 +270,16 @@
      */
     virtual void updateDeviceSelectionCache() = 0;
 
+    /**
+     * @brief listAudioProductStrategies. Introspection API to retrieve a collection of
+     * AudioProductStrategyVector that allows to build AudioAttributes according to a
+     * product_strategy which is just an index. It has also a human readable name to help the
+     * Car/Oem/AudioManager identiying the use case.
+     * @param strategies collection.
+     * @return OK if the list has been retrieved, error code otherwise
+     */
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const = 0;
+
     virtual void dump(String8 *dst) const = 0;
 
 protected: