Clear up bit mask usage in audio policy.

This change includes:
1. Use DeviceTypeSet to represent a combination of audio device types.
2. Add helper functions for DeviceTypeSet
3. Stop using audio device type as a bit mask in DeviceVector

Test: atest AudioTrackTest AudioRecordTest AudioPlaybackCaptureTest
Test: atest AudioHostTest AudioServiceHostTest audiopolicy_tests
Test: audio smoke test
Change-Id: If80513b689848bcab6094f70a572f053856afa82
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index 9b9f12f..10f3e67 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -9,6 +9,7 @@
     vendor_available: true,
 
     srcs: [
+        "AudioContainers.cpp",
         "AudioGain.cpp",
         "AudioPort.cpp",
         "AudioProfile.cpp",
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
new file mode 100644
index 0000000..adc5d40
--- /dev/null
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <sstream>
+#include <string>
+
+#include <media/AudioContainers.h>
+
+namespace android {
+
+const DeviceTypeSet& getAudioDeviceOutAllSet() {
+    static const DeviceTypeSet audioDeviceOutAllSet = DeviceTypeSet(
+            std::begin(AUDIO_DEVICE_OUT_ALL_ARRAY),
+            std::end(AUDIO_DEVICE_OUT_ALL_ARRAY));
+    return audioDeviceOutAllSet;
+}
+
+const DeviceTypeSet& getAudioDeviceOutAllA2dpSet() {
+    static const DeviceTypeSet audioDeviceOutAllA2dpSet = DeviceTypeSet(
+            std::begin(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY),
+            std::end(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY));
+    return audioDeviceOutAllA2dpSet;
+}
+
+const DeviceTypeSet& getAudioDeviceOutAllScoSet() {
+    static const DeviceTypeSet audioDeviceOutAllScoSet = DeviceTypeSet(
+            std::begin(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY),
+            std::end(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY));
+    return audioDeviceOutAllScoSet;
+}
+
+const DeviceTypeSet& getAudioDeviceInAllSet() {
+    static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet(
+            std::begin(AUDIO_DEVICE_IN_ALL_ARRAY),
+            std::end(AUDIO_DEVICE_IN_ALL_ARRAY));
+    return audioDeviceInAllSet;
+}
+
+bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) {
+    bool ret = true;
+    for (auto it = deviceTypes.begin(); it != deviceTypes.end();) {
+        std::string deviceTypeStr;
+        ret = audio_is_output_device(*it) ?
+              OutputDeviceConverter::toString(*it, deviceTypeStr) :
+              InputDeviceConverter::toString(*it, deviceTypeStr);
+        if (!ret) {
+            break;
+        }
+        str.append(deviceTypeStr);
+        if (++it != deviceTypes.end()) {
+            str.append(" , ");
+        }
+    }
+    if (!ret) {
+        str = "Unknown values";
+    }
+    return ret;
+}
+
+std::string dumpDeviceTypes(const DeviceTypeSet &deviceTypes) {
+    std::string ret;
+    for (auto it = deviceTypes.begin(); it != deviceTypes.end();) {
+        std::stringstream ss;
+        ss << "0x" << std::hex << (*it);
+        ret.append(ss.str());
+        if (++it != deviceTypes.end()) {
+            ret.append(" , ");
+        }
+    }
+    return ret;
+}
+
+} // namespace android
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 3313224..8347c71 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -16,19 +16,37 @@
 
 #pragma once
 
+#include <algorithm>
+#include <iterator>
 #include <set>
 #include <vector>
 
+#include <media/TypeConverter.h>
 #include <system/audio.h>
 
 namespace android {
 
 using ChannelMaskSet = std::set<audio_channel_mask_t>;
+using DeviceTypeSet = std::set<audio_devices_t>;
 using FormatSet = std::set<audio_format_t>;
 using SampleRateSet = std::set<uint32_t>;
 
 using FormatVector = std::vector<audio_format_t>;
 
+const DeviceTypeSet& getAudioDeviceOutAllSet();
+const DeviceTypeSet& getAudioDeviceOutAllA2dpSet();
+const DeviceTypeSet& getAudioDeviceOutAllScoSet();
+const DeviceTypeSet& getAudioDeviceInAllSet();
+
+template<typename T>
+static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
+    std::vector<T> intersection;
+    std::set_intersection(a.begin(), a.end(),
+                          b.begin(), b.end(),
+                          std::back_inserter(intersection));
+    return intersection;
+}
+
 static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) {
     ChannelMaskSet inMaskSet;
     for (const auto &channel : channelMasks) {
@@ -49,4 +67,55 @@
     return outMaskSet;
 }
 
+static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes,
+                                      audio_devices_t deviceType) {
+    return deviceTypes.size() == 1 && *(deviceTypes.begin()) == deviceType;
+}
+
+typedef bool (*DeviceTypeUnaryPredicate)(audio_devices_t);
+static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes,
+                                      DeviceTypeUnaryPredicate p) {
+    return deviceTypes.size() == 1 && p(*(deviceTypes.begin()));
+}
+
+static inline void resetDeviceTypes(DeviceTypeSet& deviceTypes, audio_devices_t typeToAdd) {
+    deviceTypes.clear();
+    deviceTypes.insert(typeToAdd);
+}
+
+// FIXME: This is temporary helper function. Remove this when getting rid of all
+//  bit mask usages of audio device types.
+static inline audio_devices_t deviceTypesToBitMask(const DeviceTypeSet& deviceTypes) {
+    audio_devices_t types = AUDIO_DEVICE_NONE;
+    for (auto deviceType : deviceTypes) {
+        types |= deviceType;
+    }
+    return types;
+}
+
+// FIXME: This is temporary helper function. Remove this when getting rid of all
+//  bit mask usages of audio device types.
+static inline DeviceTypeSet deviceTypesFromBitMask(audio_devices_t types) {
+    DeviceTypeSet deviceTypes;
+    if ((types & AUDIO_DEVICE_BIT_IN) == 0) {
+        for (auto deviceType : AUDIO_DEVICE_OUT_ALL_ARRAY) {
+            if ((types & deviceType) == deviceType) {
+                deviceTypes.insert(deviceType);
+            }
+        }
+    } else {
+        for (auto deviceType : AUDIO_DEVICE_IN_ALL_ARRAY) {
+            if ((types & deviceType) == deviceType) {
+                deviceTypes.insert(deviceType);
+            }
+        }
+    }
+    return deviceTypes;
+}
+
+bool deviceTypesToString(const DeviceTypeSet& deviceTypes, std::string &str);
+
+std::string dumpDeviceTypes(const DeviceTypeSet& deviceTypes);
+
+
 } // namespace android
\ No newline at end of file