audio policy: add support for custom mixes

Add support for custom mixes in AudioPolicyManager.

Two methods are added to register or unregister a list of custom mixes
with their attributes and format.

getOutputForAttr() and getInputForAttr() first look for a match in
registered mixes before defaulting to normal output/input selection

Remote submix device connection disconnection now takes address into
account to identify the correspnoding custom mix.

Bug: 16009464.

Change-Id: I3f1c2a485a0fb71b1f984ed0adc9b68aa971e408
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 17348e9..4214131 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -23,6 +23,7 @@
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
+#include <media/AudioPolicy.h>
 #include "AudioPolicyInterface.h"
 
 
@@ -184,6 +185,9 @@
 
         virtual status_t releaseSoundTriggerSession(audio_session_t session);
 
+        virtual status_t registerPolicyMixes(Vector<AudioMix> mixes);
+        virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes);
+
 protected:
 
         enum routing_strategy {
@@ -392,6 +396,7 @@
             // For input, flags is interpreted as audio_input_flags_t.
             // TODO: merge audio_output_flags_t and audio_input_flags_t.
             bool isCompatibleProfile(audio_devices_t device,
+                                     String8 address,
                                      uint32_t samplingRate,
                                      uint32_t *updatedSamplingRate,
                                      audio_format_t format,
@@ -415,6 +420,13 @@
             status_t loadInput(cnode *root);
             status_t loadDevice(cnode *root);
 
+            status_t addOutputProfile(String8 name, const audio_config_t *config,
+                                      audio_devices_t device, String8 address);
+            status_t removeOutputProfile(String8 name);
+            status_t addInputProfile(String8 name, const audio_config_t *config,
+                                      audio_devices_t device, String8 address);
+            status_t removeInputProfile(String8 name);
+
             void dump(int fd);
 
             const char *const        mName; // base name of the audio HW module (primary, a2dp ...)
@@ -483,6 +495,7 @@
             uint32_t mLatency;                  //
             audio_output_flags_t mFlags;   //
             audio_devices_t mDevice;                   // current device this output is routed to
+            String8 mPolicyMixAddress;            // non empty or "0" when used by a dynamic policy
             audio_patch_handle_t mPatchHandle;
             uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
             nsecs_t mStopTime[AUDIO_STREAM_CNT];
@@ -515,7 +528,9 @@
             audio_source_t                mInputSource;    // input source selected by application
                                                            //(mediarecorder.h)
             const sp<IOProfile>           mProfile;        // I/O profile this output derives from
-            SortedVector<audio_session_t> mSessions;       // audio sessions attached to this input
+                                          // audio sessions attached to this input and the
+                                          // corresponding device address
+            DefaultKeyedVector<audio_session_t, String8> mSessions;
             bool                          mIsSoundTrigger; // used by a soundtrigger capture
 
             virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -594,7 +609,8 @@
                                   audio_patch_handle_t *patchHandle = NULL);
 
         // select input device corresponding to requested audio source
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource);
+        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource,
+                                                        String8 *address = NULL);
 
         // return io handle of active input or 0 if no input is active
         //    Only considers inputs from physical devices (e.g. main mic, headset mic) when
@@ -731,10 +747,11 @@
                                        audio_format_t format);
         // samplingRate parameter is an in/out and so may be modified
         sp<IOProfile> getInputProfile(audio_devices_t device,
-                                   uint32_t& samplingRate,
-                                   audio_format_t format,
-                                   audio_channel_mask_t channelMask,
-                                   audio_input_flags_t flags);
+                                      String8 address,
+                                      uint32_t& samplingRate,
+                                      audio_format_t format,
+                                      audio_channel_mask_t channelMask,
+                                      audio_input_flags_t flags);
         sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,
                                                        uint32_t samplingRate,
                                                        audio_format_t format,
@@ -832,6 +849,17 @@
         uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams
         bool mBeaconMuted;              // has STREAM_TTS been muted
 
+        // custom mix entry in mPolicyMixes
+        class AudioPolicyMix : public RefBase {
+        public:
+            AudioPolicyMix() {}
+
+            AudioMix    mMix;                   // Audio policy mix descriptor
+            sp<AudioOutputDescriptor> mOutput;  // Corresponding output stream
+        };
+        DefaultKeyedVector<String8, sp<AudioPolicyMix> > mPolicyMixes; // list of registered mixes
+
+
 #ifdef AUDIO_POLICY_TEST
         Mutex   mLock;
         Condition mWaitWorkCV;