Use DeviceIdVector for outputs in Audio Policy

Use DeviceIdVector for output in Audio Policy.

Bug: 367816690
Test: atest audiopolicy_tests
Test: adb shell /data/fuzz/arm64/audiopolicy_fuzzer/audiopolicy_fuzzer
Flag: android.media.audio.routed_device_ids
Change-Id: If2144348ff69e75fd4e6c339848d7d161ef5611d
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 1ffa176..babc80e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -369,7 +369,7 @@
                                             const AttributionSourceState& attributionSource,
                                             const AudioConfig& configAidl,
                                             int32_t flagsAidl,
-                                            int32_t selectedDeviceIdAidl,
+                                            const std::vector<int32_t>& selectedDeviceIdsAidl,
                                             media::GetOutputForAttrResponse* _aidl_return)
 {
     audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
@@ -381,8 +381,9 @@
             aidl2legacy_AudioConfig_audio_config_t(configAidl, false /*isInput*/));
     audio_output_flags_t flags = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_int32_t_audio_output_flags_t_mask(flagsAidl));
-    audio_port_handle_t selectedDeviceId = VALUE_OR_RETURN_BINDER_STATUS(
-            aidl2legacy_int32_t_audio_port_handle_t(selectedDeviceIdAidl));
+    DeviceIdVector selectedDeviceIds = VALUE_OR_RETURN_BINDER_STATUS(
+            convertContainer<DeviceIdVector>(selectedDeviceIdsAidl,
+                                             aidl2legacy_int32_t_audio_port_handle_t));
 
     audio_io_handle_t output;
     audio_port_handle_t portId;
@@ -435,7 +436,7 @@
                                                             &stream,
                                                             attributionSource,
                                                             &config,
-                                                            &flags, &selectedDeviceId, &portId,
+                                                            &flags, &selectedDeviceIds, &portId,
                                                             &secondaryOutputs,
                                                             &outputType,
                                                             &isSpatialized,
@@ -487,15 +488,16 @@
 
         sp<AudioPlaybackClient> client =
                 new AudioPlaybackClient(attr, output, attributionSource, session,
-                    portId, selectedDeviceId, stream, isSpatialized, config.channel_mask);
+                    portId, selectedDeviceIds, stream, isSpatialized, config.channel_mask);
         mAudioPlaybackClients.add(portId, client);
 
         _aidl_return->output = VALUE_OR_RETURN_BINDER_STATUS(
                 legacy2aidl_audio_io_handle_t_int32_t(output));
         _aidl_return->stream = VALUE_OR_RETURN_BINDER_STATUS(
                 legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
-        _aidl_return->selectedDeviceId = VALUE_OR_RETURN_BINDER_STATUS(
-                legacy2aidl_audio_port_handle_t_int32_t(selectedDeviceId));
+        _aidl_return->selectedDeviceIds = VALUE_OR_RETURN_BINDER_STATUS(
+                convertContainer<std::vector<int32_t>>(selectedDeviceIds,
+                                                       legacy2aidl_audio_port_handle_t_int32_t));
         _aidl_return->portId = VALUE_OR_RETURN_BINDER_STATUS(
                 legacy2aidl_audio_port_handle_t_int32_t(portId));
         _aidl_return->secondaryOutputs = VALUE_OR_RETURN_BINDER_STATUS(
@@ -853,8 +855,9 @@
             return binderStatusFromStatusT(status);
         }
 
+        DeviceIdVector selectedDeviceIds = { selectedDeviceId };
         sp<AudioRecordClient> client = new AudioRecordClient(attr, input, session, portId,
-                                                             selectedDeviceId, attributionSource,
+                                                             selectedDeviceIds, attributionSource,
                                                              virtualDeviceId,
                                                              canCaptureOutput, canCaptureHotword,
                                                              mOutputCommandThread);
@@ -888,6 +891,17 @@
     return {};
 }
 
+std::string AudioPolicyService::getDeviceTypeStrForPortIds(DeviceIdVector portIds) {
+    std::string output = {};
+    for (auto it = portIds.begin(); it != portIds.end(); ++it) {
+        if (it != portIds.begin()) {
+            output += ", ";
+        }
+        output += getDeviceTypeStrForPortId(*it);
+    }
+    return output;
+}
+
 Status AudioPolicyService::startInput(int32_t portIdAidl)
 {
     audio_port_handle_t portId = VALUE_OR_RETURN_BINDER_STATUS(
@@ -978,6 +992,8 @@
                 "android.media.audiopolicy.active.session";
         static constexpr char kAudioPolicyActiveDevice[] =
                 "android.media.audiopolicy.active.device";
+        static constexpr char kAudioPolicyActiveDevices[] =
+                "android.media.audiopolicy.active.devices";
 
         mediametrics::Item *item = mediametrics::Item::create(kAudioPolicy);
         if (item != NULL) {
@@ -995,8 +1011,8 @@
                 item->setCString(kAudioPolicyRqstPkg,
                     std::to_string(client->attributionSource.uid).c_str());
             }
-            item->setCString(
-                    kAudioPolicyRqstDevice, getDeviceTypeStrForPortId(client->deviceId).c_str());
+            item->setCString(kAudioPolicyRqstDevice,
+                    getDeviceTypeStrForPortId(getFirstDeviceId(client->deviceIds)).c_str());
 
             int count = mAudioRecordClients.size();
             for (int i = 0; i < count ; i++) {
@@ -1018,7 +1034,9 @@
                             other->attributionSource.uid).c_str());
                     }
                     item->setCString(kAudioPolicyActiveDevice,
-                                     getDeviceTypeStrForPortId(other->deviceId).c_str());
+                            getDeviceTypeStrForPortId(getFirstDeviceId(other->deviceIds)).c_str());
+                    item->setCString(kAudioPolicyActiveDevices,
+                            getDeviceTypeStrForPortIds(other->deviceIds).c_str());
                 }
             }
             item->selfrecord();