Update AudioChannelLayout to address some issues

Changes made:

 - haptic channels moved to the MSB part of the integer;

 - "voice up/down link" channel moved into their own
   union variant.

Bug: 188932434
Bug: 193562113
Bug: 193563345
Test: atest audio_aidl_conversion_tests
Change-Id: Idedab7142fe05ecfcbcc57c8a359a9d541395c96
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index 298e596..bb67b53 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -475,10 +475,7 @@
         DEFINE_INPUT_LAYOUT(2POINT1POINT2),
         DEFINE_INPUT_LAYOUT(3POINT0POINT2),
         DEFINE_INPUT_LAYOUT(3POINT1POINT2),
-        DEFINE_INPUT_LAYOUT(5POINT1),
-        DEFINE_INPUT_LAYOUT(VOICE_UPLINK_MONO),
-        DEFINE_INPUT_LAYOUT(VOICE_DNLINK_MONO),
-        DEFINE_INPUT_LAYOUT(VOICE_CALL_MONO)
+        DEFINE_INPUT_LAYOUT(5POINT1)
 #undef DEFINE_INPUT_LAYOUT
     };
     return pairs;
@@ -527,6 +524,22 @@
     return pairs;
 }
 
+const detail::AudioChannelPairs& getVoiceAudioChannelPairs() {
+    static const detail::AudioChannelPairs pairs = {
+#define DEFINE_VOICE_LAYOUT(n)                                                               \
+            {                                                                                \
+                AUDIO_CHANNEL_IN_VOICE_##n,                                                  \
+                media::AudioChannelLayout::make<media::AudioChannelLayout::Tag::voiceMask>(  \
+                        media::AudioChannelLayout::VOICE_##n)                                \
+            }
+        DEFINE_VOICE_LAYOUT(UPLINK_MONO),
+        DEFINE_VOICE_LAYOUT(DNLINK_MONO),
+        DEFINE_VOICE_LAYOUT(CALL_MONO)
+#undef DEFINE_VOICE_LAYOUT
+    };
+    return pairs;
+}
+
 media::AudioDeviceDescription make_AudioDeviceDescription(media::AudioDeviceType type,
         const std::string& connection = "") {
     media::AudioDeviceDescription result;
@@ -1080,6 +1093,17 @@
 }
 
 template<typename S, typename T>
+std::unordered_map<S, T> make_DirectMap(
+        const std::vector<std::pair<S, T>>& v1, const std::vector<std::pair<S, T>>& v2) {
+    std::unordered_map<S, T> result(v1.begin(), v1.end());
+    LOG_ALWAYS_FATAL_IF(result.size() != v1.size(), "Duplicate key elements detected in v1");
+    result.insert(v2.begin(), v2.end());
+    LOG_ALWAYS_FATAL_IF(result.size() != v1.size() + v2.size(),
+            "Duplicate key elements detected in v1+v2");
+    return result;
+}
+
+template<typename S, typename T>
 std::unordered_map<T, S> make_ReverseMap(const std::vector<std::pair<S, T>>& v) {
     std::unordered_map<T, S> result;
     std::transform(v.begin(), v.end(), std::inserter(result, result.begin()),
@@ -1099,6 +1123,7 @@
     static const ReverseMap mIdx = make_ReverseMap(getIndexAudioChannelPairs());
     static const ReverseMap mIn = make_ReverseMap(getInAudioChannelPairs());
     static const ReverseMap mOut = make_ReverseMap(getOutAudioChannelPairs());
+    static const ReverseMap mVoice = make_ReverseMap(getVoiceAudioChannelPairs());
 
     auto convert = [](const media::AudioChannelLayout& aidl, const ReverseMap& m,
             const char* func, const char* type) -> ConversionResult<audio_channel_mask_t> {
@@ -1120,6 +1145,8 @@
             return convert(aidl, mIdx, __func__, "index");
         case Tag::layoutMask:
             return convert(aidl, isOutput ? mOut : mIn, __func__, isOutput ? "output" : "input");
+        case Tag::voiceMask:
+            return convert(aidl, mVoice, __func__, "voice");
     }
     ALOGE("%s: unexpected tag value %d", __func__, aidl.getTag());
     return unexpected(BAD_VALUE);
@@ -1130,7 +1157,8 @@
     using DirectMap = std::unordered_map<audio_channel_mask_t, media::AudioChannelLayout>;
     using Tag = media::AudioChannelLayout::Tag;
     static const DirectMap mIdx = make_DirectMap(getIndexAudioChannelPairs());
-    static const DirectMap mIn = make_DirectMap(getInAudioChannelPairs());
+    static const DirectMap mInAndVoice = make_DirectMap(
+            getInAudioChannelPairs(), getVoiceAudioChannelPairs());
     static const DirectMap mOut = make_DirectMap(getOutAudioChannelPairs());
 
     auto convert = [](const audio_channel_mask_t legacy, const DirectMap& m,
@@ -1154,7 +1182,8 @@
     if (repr == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
         return convert(legacy, mIdx, __func__, "index");
     } else if (repr == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
-        return convert(legacy, isOutput ? mOut : mIn, __func__, isOutput ? "output" : "input");
+        return convert(legacy, isOutput ? mOut : mInAndVoice, __func__,
+                isOutput ? "output" : "input / voice");
     }
 
     ALOGE("%s: unknown representation %d in audio_channel_mask_t value 0x%x",