Refactor opening output interface between AF and AP.

Refactor interface between audio flinger and audio policy. Use device
descriptor instead of audio device type and address. DeviceDescriptor
can contain more information that may be useful when opening an output
stream.
In audio policy, if multiple audio devices are passed in when opening
an output stream, one device is extracted using the same strategy as
when selecting a device for volume application. When starting source,
audio policy manager will call audio flinger to create audio patch. In
that case, multiple devices will still be patched to the output stream.

Test: atest AudioTrackTest AudioPlaybackCaptureTest
Test: atest audiopolicy_tests, audio smoke test
Change-Id: I46dc2da621614f8716c6c73cf807fe7d2d672cda
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index c516d20..2752ba6 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -1,7 +1,15 @@
 cc_library_headers {
     name: "libaudioclient_headers",
     vendor_available: true,
-    export_include_dirs: ["include"],
+    header_libs: [
+        "libaudiofoundation_headers",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    export_header_lib_headers: [
+        "libaudiofoundation_headers",
+    ],
 }
 
 cc_library_shared {
@@ -63,6 +71,7 @@
         "TrackPlayerBase.cpp",
     ],
     shared_libs: [
+        "libaudiofoundation",
         "libaudioutils",
         "libaudiopolicy",
         "libaudiomanager",
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 46cfb68..6e9a7cf 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -392,20 +392,18 @@
     virtual status_t openOutput(audio_module_handle_t module,
                                 audio_io_handle_t *output,
                                 audio_config_t *config,
-                                audio_devices_t *devices,
-                                const String8& address,
+                                const sp<DeviceDescriptorBase>& device,
                                 uint32_t *latencyMs,
                                 audio_output_flags_t flags)
     {
-        if (output == NULL || config == NULL || devices == NULL || latencyMs == NULL) {
+        if (output == nullptr || config == nullptr || device == nullptr || latencyMs == nullptr) {
             return BAD_VALUE;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(module);
         data.write(config, sizeof(audio_config_t));
-        data.writeInt32(*devices);
-        data.writeString8(address);
+        data.writeParcelable(*device);
         data.writeInt32((int32_t) flags);
         status_t status = remote()->transact(OPEN_OUTPUT, data, &reply);
         if (status != NO_ERROR) {
@@ -420,7 +418,6 @@
         *output = (audio_io_handle_t)reply.readInt32();
         ALOGV("openOutput() returned output, %d", *output);
         reply.read(config, sizeof(audio_config_t));
-        *devices = (audio_devices_t)reply.readInt32();
         *latencyMs = reply.readInt32();
         return NO_ERROR;
     }
@@ -1198,19 +1195,21 @@
             if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
                 ALOGE("b/23905951");
             }
-            audio_devices_t devices = (audio_devices_t)data.readInt32();
-            String8 address(data.readString8());
+            sp<DeviceDescriptorBase> device = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
+            status_t status = NO_ERROR;
+            if ((status = data.readParcelable(device.get())) != NO_ERROR) {
+                reply->writeInt32((int32_t)status);
+                return NO_ERROR;
+            }
             audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
             uint32_t latencyMs = 0;
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = openOutput(module, &output, &config,
-                                         &devices, address, &latencyMs, flags);
+            status = openOutput(module, &output, &config, device, &latencyMs, flags);
             ALOGV("OPEN_OUTPUT output, %d", output);
             reply->writeInt32((int32_t)status);
             if (status == NO_ERROR) {
                 reply->writeInt32((int32_t)output);
                 reply->write(&config, sizeof(audio_config_t));
-                reply->writeInt32(devices);
                 reply->writeInt32(latencyMs);
             }
             return NO_ERROR;
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index b580a88..0a65857 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -27,6 +27,7 @@
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 #include <media/AudioClient.h>
+#include <media/DeviceDescriptorBase.h>
 #include <media/IAudioTrack.h>
 #include <media/IAudioFlingerClient.h>
 #include <system/audio.h>
@@ -416,8 +417,7 @@
     virtual status_t openOutput(audio_module_handle_t module,
                                 audio_io_handle_t *output,
                                 audio_config_t *config,
-                                audio_devices_t *devices,
-                                const String8& address,
+                                const sp<DeviceDescriptorBase>& device,
                                 uint32_t *latencyMs,
                                 audio_output_flags_t flags) = 0;
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index 1df0d16..edc06d2 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -15,6 +15,7 @@
 cc_library {
     name: "libaudiofoundation",
     vendor_available: true,
+    double_loadable: true,
 
     srcs: [
         "AudioContainers.cpp",
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 8347c71..05e68fa 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <algorithm>
+#include <functional>
 #include <iterator>
 #include <set>
 #include <vector>
@@ -78,6 +79,11 @@
     return deviceTypes.size() == 1 && p(*(deviceTypes.begin()));
 }
 
+static inline bool areAllOfSameDeviceType(const DeviceTypeSet& deviceTypes,
+                                          std::function<bool(audio_devices_t)> p) {
+    return std::all_of(deviceTypes.begin(), deviceTypes.end(), p);
+}
+
 static inline void resetDeviceTypes(DeviceTypeSet& deviceTypes, audio_devices_t typeToAdd) {
     deviceTypes.clear();
     deviceTypes.insert(typeToAdd);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index b07f21d..3d3a5eb 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -229,14 +229,14 @@
 
 status_t DeviceHalHidl::openOutputStream(
         audio_io_handle_t handle,
-        audio_devices_t devices,
+        audio_devices_t deviceType,
         audio_output_flags_t flags,
         struct audio_config *config,
         const char *address,
         sp<StreamOutHalInterface> *outStream) {
     if (mDevice == 0) return NO_INIT;
     DeviceAddress hidlDevice;
-    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
+    status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
     if (status != OK) return status;
     AudioConfig hidlConfig;
     HidlUtils::audioConfigFromHal(*config, &hidlConfig);
diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp
index ee68252..dfbb6b2 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.cpp
+++ b/media/libaudiohal/impl/DeviceHalLocal.cpp
@@ -104,7 +104,7 @@
 
 status_t DeviceHalLocal::openOutputStream(
         audio_io_handle_t handle,
-        audio_devices_t devices,
+        audio_devices_t deviceType,
         audio_output_flags_t flags,
         struct audio_config *config,
         const char *address,
@@ -112,11 +112,11 @@
     audio_stream_out_t *halStream;
     ALOGV("open_output_stream handle: %d devices: %x flags: %#x"
             "srate: %d format %#x channels %x address %s",
-            handle, devices, flags,
+            handle, deviceType, flags,
             config->sample_rate, config->format, config->channel_mask,
             address);
     int openResut = mDev->open_output_stream(
-            mDev, handle, devices, flags, config, &halStream, address);
+            mDev, handle, deviceType, flags, config, &halStream, address);
     if (openResut == OK) {
         *outStream = new StreamOutHalLocal(halStream, this);
     }
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index e565237..2200a7f 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -69,7 +69,7 @@
     // by releasing all references to the returned object.
     virtual status_t openOutputStream(
             audio_io_handle_t handle,
-            audio_devices_t devices,
+            audio_devices_t deviceType,
             audio_output_flags_t flags,
             struct audio_config *config,
             const char *address,