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/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index a02f567..2a5cd49 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -31,6 +31,7 @@
 #include <IOProfile.h>
 #include <AudioIODescriptorInterface.h>
 #include <policy.h>
+#include <media/AudioContainers.h>
 #include <utils/String8.h>
 #include <utils/Log.h>
 
@@ -146,7 +147,7 @@
     switch (strategy) {
 
     case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
-        devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER);
+        devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
         break;
 
     case STRATEGY_SONIFICATION_RESPECTFUL:
@@ -161,7 +162,7 @@
                         toVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
                         SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
             // routing is same as media without the "remote" device
-            availableOutputDevices.remove(availableOutputDevices.getDevicesFromTypeMask(
+            availableOutputDevices.remove(availableOutputDevices.getDevicesFromType(
                     AUDIO_DEVICE_OUT_REMOTE_SUBMIX));
             devices = getDevicesForStrategyInt(STRATEGY_MEDIA,
                     availableOutputDevices,
@@ -171,7 +172,7 @@
             if (!media_active_locally) {
                 devices.replaceDevicesByType(
                         AUDIO_DEVICE_OUT_SPEAKER,
-                        availableOutputDevices.getDevicesFromTypeMask(
+                        availableOutputDevices.getDevicesFromType(
                                 AUDIO_DEVICE_OUT_SPEAKER_SAFE));
             }
         }
@@ -204,10 +205,10 @@
             // audio_policy_configuration.xml, hearing aid is not there, but it's
             // a primary device
             // FIXME: this is not the right way of solving this problem
-            DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypeMask(
+            DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypes(
                     primaryOutput->supportedDevices().types());
             availPrimaryOutputDevices.add(
-                    availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID));
+                    availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID));
 
             if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
                     String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
@@ -222,7 +223,7 @@
         switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
         case AUDIO_POLICY_FORCE_BT_SCO:
             if (!isInCall() || strategy != STRATEGY_DTMF) {
-                devices = availableOutputDevices.getDevicesFromTypeMask(
+                devices = availableOutputDevices.getDevicesFromType(
                         AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
                 if (!devices.isEmpty()) break;
             }
@@ -233,7 +234,7 @@
             FALLTHROUGH_INTENDED;
 
         default:    // FORCE_NONE
-            devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID);
+            devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
             if (!devices.isEmpty()) break;
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
             if (!isInCall() &&
@@ -255,7 +256,7 @@
                         AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET});
                 if (!devices.isEmpty()) break;
             }
-            devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_EARPIECE);
+            devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_EARPIECE);
             break;
 
         case AUDIO_POLICY_FORCE_SPEAKER:
@@ -264,7 +265,7 @@
             if (!isInCall() &&
                     (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                      outputs.isA2dpSupported()) {
-                devices = availableOutputDevices.getDevicesFromTypeMask(
+                devices = availableOutputDevices.getDevicesFromType(
                         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
                 if (!devices.isEmpty()) break;
             }
@@ -275,7 +276,7 @@
                         AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET});
                 if (!devices.isEmpty()) break;
             }
-            devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER);
+            devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
             break;
         }
     break;
@@ -299,12 +300,12 @@
 
         if ((strategy == STRATEGY_SONIFICATION) ||
                 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
-            devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER);
+            devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
         }
 
         // if SCO headset is connected and we are told to use it, play ringtone over
         // speaker and BT SCO
-        if (!availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_ALL_SCO).isEmpty()) {
+        if (!availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllScoSet()).isEmpty()) {
             DeviceVector devices2;
             devices2 = availableOutputDevices.getFirstDevicesFromTypes({
                     AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
@@ -325,7 +326,7 @@
                 if (strategy == STRATEGY_SONIFICATION) {
                     devices.replaceDevicesByType(
                             AUDIO_DEVICE_OUT_SPEAKER,
-                            availableOutputDevices.getDevicesFromTypeMask(
+                            availableOutputDevices.getDevicesFromType(
                                     AUDIO_DEVICE_OUT_SPEAKER_SAFE));
                 }
                 if (!devices2.isEmpty()) {
@@ -344,9 +345,9 @@
             for (size_t i = 0; i < outputs.size(); i++) {
                 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
                 if (desc->isActive() && !audio_is_linear_pcm(desc->getFormat())) {
-                    availableOutputDevices.remove(desc->devices().getDevicesFromTypeMask(
-                            AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF
-                            | AUDIO_DEVICE_OUT_HDMI_ARC));
+                    availableOutputDevices.remove(desc->devices().getDevicesFromTypes({
+                            AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_SPDIF,
+                            AUDIO_DEVICE_OUT_HDMI_ARC}));
                 }
             }
             if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
@@ -383,7 +384,7 @@
         // FIXME: Find a better solution to prevent routing to BT hearing aid(b/122931261).
         if ((devices2.isEmpty()) &&
                 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
-            devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID);
+            devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
         }
         if ((devices2.isEmpty()) &&
                 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
@@ -394,7 +395,7 @@
         }
         if ((devices2.isEmpty()) &&
             (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
-            devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER);
+            devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
         }
         if (devices2.isEmpty()) {
             devices2 = availableOutputDevices.getFirstDevicesFromTypes({
@@ -405,21 +406,21 @@
         }
         if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) {
             // no sonification on aux digital (e.g. HDMI)
-            devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_AUX_DIGITAL);
+            devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);
         }
         if ((devices2.isEmpty()) &&
                 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
-            devices2 = availableOutputDevices.getDevicesFromTypeMask(
+            devices2 = availableOutputDevices.getDevicesFromType(
                     AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);
         }
         if (devices2.isEmpty()) {
-            devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER);
+            devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
         }
         DeviceVector devices3;
         if (strategy == STRATEGY_MEDIA) {
             // ARC, SPDIF and AUX_LINE can co-exist with others.
-            devices3 = availableOutputDevices.getDevicesFromTypeMask(
-                    AUDIO_DEVICE_OUT_HDMI_ARC | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_AUX_LINE);
+            devices3 = availableOutputDevices.getDevicesFromTypes({
+                    AUDIO_DEVICE_OUT_HDMI_ARC, AUDIO_DEVICE_OUT_SPDIF, AUDIO_DEVICE_OUT_AUX_LINE});
         }
 
         devices2.add(devices3);
@@ -431,7 +432,7 @@
         if ((strategy == STRATEGY_MEDIA) &&
             (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
-            devices.remove(devices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER));
+            devices.remove(devices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
         }
 
         // for STRATEGY_SONIFICATION:
@@ -439,7 +440,7 @@
         if (strategy == STRATEGY_SONIFICATION) {
             devices.replaceDevicesByType(
                     AUDIO_DEVICE_OUT_SPEAKER,
-                    availableOutputDevices.getDevicesFromTypeMask(
+                    availableOutputDevices.getDevicesFromType(
                             AUDIO_DEVICE_OUT_SPEAKER_SAFE));
         }
         } break;