Audio HAL: Add optional Destination to SinkMetadata

Currently this is used to indicate the output device
when the input stream is from an intermediate processing
module like MSD.

Bug: 120859615
Test: make
Change-Id: I60bac5c24a263ab0b8965e9dbf9514445e88c270
diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp
index 27c1ef5..3586b8e 100644
--- a/audio/5.0/Android.bp
+++ b/audio/5.0/Android.bp
@@ -20,6 +20,7 @@
         "android.hardware.audio.common@5.0",
         "android.hardware.audio.effect@5.0",
         "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
     ],
     types: [
         "AudioDrain",
@@ -28,18 +29,13 @@
         "AudioMicrophoneCoordinate",
         "AudioMicrophoneDirectionality",
         "AudioMicrophoneLocation",
-        "DeviceAddress",
         "MessageQueueFlagBits",
         "MicrophoneInfo",
         "MmapBufferFlag",
         "MmapBufferInfo",
         "MmapPosition",
         "ParameterValue",
-        "PlaybackTrackMetadata",
-        "RecordTrackMetadata",
         "Result",
-        "SinkMetadata",
-        "SourceMetadata",
         "TimeSpec",
     ],
     gen_java: false,
diff --git a/audio/5.0/IDevice.hal b/audio/5.0/IDevice.hal
index afb4fad..9e45ba5 100644
--- a/audio/5.0/IDevice.hal
+++ b/audio/5.0/IDevice.hal
@@ -133,7 +133,7 @@
      * @param config stream configuration.
      * @param flags additional flags.
      * @param sinkMetadata Description of the audio that is suggested by the client.
-     *                     May be used by implementations to configure hardware effects.
+     *                     May be used by implementations to configure processing effects.
      * @return retval operation completion status.
      * @return inStream in case of success, created input stream.
      * @return suggestedConfig in case of invalid parameters, suggested config.
diff --git a/audio/5.0/types.hal b/audio/5.0/types.hal
index 988f584..4932367 100644
--- a/audio/5.0/types.hal
+++ b/audio/5.0/types.hal
@@ -49,34 +49,11 @@
     uint64_t tvNSec;  // nanoseconds
 };
 
-/**
- * IEEE 802 MAC address.
- */
-typedef uint8_t[6] MacAddress;
-
 struct ParameterValue {
     string key;
     string value;
 };
 
-/**
- * Specifies a device in case when several devices of the same type
- * can be connected (e.g. BT A2DP, USB).
- */
-struct DeviceAddress {
-    AudioDevice device;  // discriminator
-    union Address {
-        MacAddress mac;     // used for BLUETOOTH_A2DP_*
-        uint8_t[4] ipv4;    // used for IP
-        struct Alsa {
-            int32_t card;
-            int32_t device;
-        } alsa;             // used for USB_*
-    } address;
-    string busAddress;      // used for BUS
-    string rSubmixAddress;  // used for REMOTE_SUBMIX
-};
-
 enum MmapBufferFlag : uint32_t {
     NONE    = 0x0,
     /**
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index 663f847..86d9354 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -9,6 +9,9 @@
     srcs: [
         "types.hal",
     ],
+    interfaces: [
+        "android.hidl.safe_union@1.0",
+    ],
     types: [
         "AudioChannelMask",
         "AudioConfig",
@@ -38,7 +41,12 @@
         "AudioSource",
         "AudioStreamType",
         "AudioUsage",
+        "DeviceAddress",
         "FixedChannelCount",
+        "PlaybackTrackMetadata",
+        "RecordTrackMetadata",
+        "SinkMetadata",
+        "SourceMetadata",
         "ThreadInfo",
         "Uuid",
     ],
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index e5919cb..dab7464 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -16,6 +16,8 @@
 
 package android.hardware.audio.common@5.0;
 
+import android.hidl.safe_union@1.0;
+
 /*
  *
  *  IDs and Handles
@@ -602,6 +604,29 @@
 };
 
 /**
+ * IEEE 802 MAC address.
+ */
+typedef uint8_t[6] MacAddress;
+
+/**
+ * Specifies a device address in case when several devices of the same type
+ * can be connected (e.g. BT A2DP, USB).
+ */
+struct DeviceAddress {
+    AudioDevice device;  // discriminator
+    union Address {
+        MacAddress mac;     // used for BLUETOOTH_A2DP_*
+        uint8_t[4] ipv4;    // used for IP
+        struct Alsa {
+            int32_t card;
+            int32_t device;
+        } alsa;             // used for USB_*
+    } address;
+    string busAddress;      // used for BUS
+    string rSubmixAddress;  // used for REMOTE_SUBMIX
+};
+
+/**
  * The audio output flags serve two purposes:
  *
  *  - when an AudioTrack is created they indicate a "wish" to be connected to an
@@ -748,9 +773,17 @@
      * Must not be negative.
      */
     float gain;
+    /**
+     * Indicates the destination of an input stream, can be left unspecified.
+     */
+    safe_union Destination {
+        Monostate unspecified;
+        DeviceAddress device;
+    };
+    Destination destination;
 };
 
-/** Metadatas of the source of a StreamIn. */
+/** Metadatas of the sink of a StreamIn. */
 struct SinkMetadata {
     vec<RecordTrackMetadata> tracks;
 };
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 9ab3ceb..022f75e 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -64,7 +64,7 @@
         config.sampleRateHz = 8000;
         config.format = AudioFormat::PCM_16_BIT;
         auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
-        const SinkMetadata initMetadata = {{{AudioSource::MIC, 1 /* gain */}}};
+        const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
         EventFlag* efGroup;
         for (auto microphone : microphones) {
             if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
@@ -200,7 +200,7 @@
     // Test all possible track configuration
     for (AudioSource source : range) {
         for (float volume : {0.0, 0.5, 1.0}) {
-            const SinkMetadata metadata = {{{source, volume}}};
+            const SinkMetadata metadata = {{{.source = source, .gain = volume}}};
             ASSERT_OK(stream->updateSinkMetadata(metadata))
                 << "source=" << toString(source) << ", volume=" << volume;
         }
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 238b3d8..ec8041c 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -769,7 +769,7 @@
 #if MAJOR_VERSION == 2
     const AudioSource initMetadata = AudioSource::DEFAULT;
 #elif MAJOR_VERSION >= 4
-    const SinkMetadata initMetadata = {{{AudioSource::DEFAULT, 1 /* gain */}}};
+    const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}};
 #endif
 };
 
diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp
index d60d94a..78b950e 100644
--- a/audio/effect/5.0/Android.bp
+++ b/audio/effect/5.0/Android.bp
@@ -26,6 +26,7 @@
     interfaces: [
         "android.hardware.audio.common@5.0",
         "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
     ],
     types: [
         "AudioBuffer",