Merge "audio policy: allows dumping Audio Policy Mix"
diff --git a/include/media/TypeConverter.h b/include/media/TypeConverter.h
index ffe4c1f..e262eef 100644
--- a/include/media/TypeConverter.h
+++ b/include/media/TypeConverter.h
@@ -80,6 +80,16 @@
     typedef audio_mode_t Type;
     typedef Vector<Type> Collection;
 };
+struct UsageTraits
+{
+    typedef audio_usage_t Type;
+    typedef Vector<Type> Collection;
+};
+struct SourceTraits
+{
+    typedef audio_source_t Type;
+    typedef Vector<Type> Collection;
+};
 template <typename T>
 struct DefaultTraits
 {
@@ -215,6 +225,8 @@
 typedef TypeConverter<GainModeTraits> GainModeConverter;
 typedef TypeConverter<StreamTraits> StreamTypeConverter;
 typedef TypeConverter<AudioModeTraits> AudioModeConverter;
+typedef TypeConverter<UsageTraits> UsageTypeConverter;
+typedef TypeConverter<SourceTraits> SourceTypeConverter;
 
 bool deviceFromString(const std::string& literalDevice, audio_devices_t& device);
 
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index c2b2688..25c29f2 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -269,6 +269,48 @@
     TERMINATOR
 };
 
+template <>
+const UsageTypeConverter::Table UsageTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_UNKNOWN),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_MEDIA),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_VOICE_COMMUNICATION),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_ALARM),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_NOTIFICATION),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_NOTIFICATION_EVENT),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_ASSISTANCE_SONIFICATION),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_GAME),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_VIRTUAL_SOURCE),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_CNT),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_MAX),
+    TERMINATOR
+};
+
+template <>
+const SourceTypeConverter::Table SourceTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_DEFAULT),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_MIC),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_UPLINK),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_DOWNLINK),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_CALL),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_CAMCORDER),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_RECOGNITION),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_COMMUNICATION),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_REMOTE_SUBMIX),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_UNPROCESSED),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_CNT),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_MAX),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_FM_TUNER),
+    MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_HOTWORD),
+    TERMINATOR
+};
+
 template class TypeConverter<OutputDeviceTraits>;
 template class TypeConverter<InputDeviceTraits>;
 template class TypeConverter<OutputFlagTraits>;
@@ -280,6 +322,8 @@
 template class TypeConverter<GainModeTraits>;
 template class TypeConverter<StreamTraits>;
 template class TypeConverter<AudioModeTraits>;
+template class TypeConverter<UsageTraits>;
+template class TypeConverter<SourceTraits>;
 
 bool deviceFromString(const std::string& literalDevice, audio_devices_t& device) {
     return InputDeviceConverter::fromString(literalDevice, device) ||
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 97a9c94..0bacef7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -43,6 +43,8 @@
 
     void setMix(AudioMix &mix);
 
+    status_t dump(int fd, int spaces, int index) const;
+
 private:
     AudioMix    mMix;                   // Audio policy mix descriptor
     sp<SwAudioOutputDescriptor> mOutput;  // Corresponding output stream
@@ -77,6 +79,8 @@
                                                   AudioMix **policyMix);
 
     status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
+
+    status_t dump(int fd) const;
 };
 
 }; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
index 84e3a36..9e705aa 100644
--- a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
+++ b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
@@ -28,7 +28,25 @@
     typedef device_category Type;
     typedef Vector<Type> Collection;
 };
+struct MixTypeTraits
+{
+    typedef int32_t Type;
+    typedef Vector<Type> Collection;
+};
+struct RouteFlagTraits
+{
+    typedef uint32_t Type;
+    typedef Vector<Type> Collection;
+};
+struct RuleTraits
+{
+    typedef uint32_t Type;
+    typedef Vector<Type> Collection;
+};
 
 typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter;
+typedef TypeConverter<MixTypeTraits> MixTypeConverter;
+typedef TypeConverter<RouteFlagTraits> RouteFlagTypeConverter;
+typedef TypeConverter<RuleTraits> RuleTypeConverter;
 
 }; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 02833a9..08930f1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include "AudioPolicyMix.h"
+#include "TypeConverter.h"
 #include "HwModule.h"
 #include "AudioPort.h"
 #include "IOProfile.h"
@@ -51,6 +52,66 @@
     return &mMix;
 }
 
+status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "%*sAudio Policy Mix %d:\n", spaces, "", index+1);
+    result.append(buffer);
+    std::string mixTypeLiteral;
+    if (!MixTypeConverter::toString(mMix.mMixType, mixTypeLiteral)) {
+        ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMix.mMixType);
+        return BAD_VALUE;
+    }
+    snprintf(buffer, SIZE, "%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
+    result.append(buffer);
+    std::string routeFlagLiteral;
+    RouteFlagTypeConverter::maskToString(mMix.mRouteFlags, routeFlagLiteral);
+    snprintf(buffer, SIZE, "%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
+    result.append(buffer);
+    std::string deviceLiteral;
+    deviceToString(mMix.mDeviceType, deviceLiteral);
+    snprintf(buffer, SIZE, "%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
+    result.append(buffer);
+
+    int indexCriterion = 0;
+    for (const auto &criterion : mMix.mCriteria) {
+        snprintf(buffer, SIZE, "%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
+        result.append(buffer);
+        std::string usageLiteral;
+        if (!UsageTypeConverter::toString(criterion.mValue.mUsage, usageLiteral)) {
+            ALOGE("%s: failed to convert usage %d", __FUNCTION__, criterion.mValue.mUsage);
+            return BAD_VALUE;
+        }
+        snprintf(buffer, SIZE, "%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
+        result.append(buffer);
+        if (mMix.mMixType == MIX_TYPE_RECORDERS) {
+            std::string sourceLiteral;
+            if (!SourceTypeConverter::toString(criterion.mValue.mSource, sourceLiteral)) {
+                ALOGE("%s: failed to convert source %d", __FUNCTION__, criterion.mValue.mSource);
+                return BAD_VALUE;
+            }
+            snprintf(buffer, SIZE, "%*s- Source:%s\n", spaces + 4, "", sourceLiteral.c_str());
+            result.append(buffer);
+        }
+        snprintf(buffer, SIZE, "%*s- Uid:%d\n", spaces + 4, "", criterion.mValue.mUid);
+        result.append(buffer);
+        std::string ruleLiteral;
+        if (!RuleTypeConverter::toString(criterion.mRule, ruleLiteral)) {
+            ALOGE("%s: failed to convert source %d", __FUNCTION__,criterion.mRule);
+            return BAD_VALUE;
+        }
+        snprintf(buffer, SIZE, "%*s- Rule:%s\n", spaces + 4, "", ruleLiteral.c_str());
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
 status_t AudioPolicyMixCollection::registerMix(const String8& address, AudioMix mix,
                                                sp<SwAudioOutputDescriptor> desc)
 {
@@ -288,4 +349,14 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyMixCollection::dump(int fd) const
+{
+    std::string log("\nAudio Policy Mix:\n");
+    write(fd, log.c_str(), log.size());
+    for (size_t i = 0; i < size(); i++) {
+        valueAt(i)->dump(fd, 2, i);
+    }
+    return NO_ERROR;
+}
+
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
index 4839683..0362037 100644
--- a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <media/AudioPolicy.h>
+
 #include "TypeConverter.h"
 
 namespace android {
@@ -30,6 +32,37 @@
     TERMINATOR
 };
 
+template <>
+const MixTypeConverter::Table MixTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(MIX_TYPE_INVALID),
+    MAKE_STRING_FROM_ENUM(MIX_TYPE_PLAYERS),
+    MAKE_STRING_FROM_ENUM(MIX_TYPE_RECORDERS),
+    TERMINATOR
+};
+
+template <>
+const RouteFlagTypeConverter::Table RouteFlagTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_RENDER),
+    MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_LOOP_BACK),
+    MAKE_STRING_FROM_ENUM(MIX_ROUTE_FLAG_ALL),
+    TERMINATOR
+};
+
+template <>
+const RuleTypeConverter::Table RuleTypeConverter::mTable[] = {
+    MAKE_STRING_FROM_ENUM(RULE_EXCLUSION_MASK),
+    MAKE_STRING_FROM_ENUM(RULE_MATCH_ATTRIBUTE_USAGE),
+    MAKE_STRING_FROM_ENUM(RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET),
+    MAKE_STRING_FROM_ENUM(RULE_MATCH_UID),
+    MAKE_STRING_FROM_ENUM(RULE_EXCLUDE_ATTRIBUTE_USAGE),
+    MAKE_STRING_FROM_ENUM(RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET),
+    MAKE_STRING_FROM_ENUM(RULE_EXCLUDE_UID),
+    TERMINATOR
+};
+
 template class TypeConverter<DeviceCategoryTraits>;
+template class TypeConverter<MixTypeTraits>;
+template class TypeConverter<RouteFlagTraits>;
+template class TypeConverter<RuleTraits>;
 
 }; // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 923d4f6..e71bb01 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2419,6 +2419,7 @@
     mVolumeCurves->dump(fd);
     mEffects.dump(fd);
     mAudioPatches.dump(fd);
+    mPolicyMixes.dump(fd);
 
     return NO_ERROR;
 }