audio policy: implement routing control

Add implementation of audio routing control via AudioSystem APIs.

The following APIs are implemented:
- listAudioPorts(): return a list of devices and output/input mixers ports
that can be used as sources or sinks for audio patches.
- createAudioPatch()/releaseAudioPatch(): create/release a connection patch between
two audio ports (e.g. to connect input from an HDMI device to a speaker output device).
Only one client application can own a patch from a given source.
When an audio port (device or mix) is part of an application created patch, its routing cannot
not be changed by a policy decision.
- listAudioPatches(): return a list of existing patches.

Each audio port addition/removal and each audio patch creation/release increments a generation count.
This generation count is used to ensure consistency betwen calls to
listAudioPorts() and listAudioPatches().

Bug: 14815883.

Change-Id: I022b638c2f5f0bb41543c7cfca7488fb45cfdd80
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 905a3c8..99d9feb 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -140,6 +140,23 @@
 
         virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
 
+        virtual status_t listAudioPorts(audio_port_role_t role,
+                                        audio_port_type_t type,
+                                        unsigned int *num_ports,
+                                        struct audio_port *ports,
+                                        unsigned int *generation);
+        virtual status_t getAudioPort(struct audio_port *port);
+        virtual status_t createAudioPatch(const struct audio_patch *patch,
+                                           audio_patch_handle_t *handle,
+                                           uid_t uid);
+        virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
+                                              uid_t uid);
+        virtual status_t listAudioPatches(unsigned int *num_patches,
+                                          struct audio_patch *patches,
+                                          unsigned int *generation);
+        virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+        virtual void clearAudioPatches(uid_t uid);
+
 protected:
 
         enum routing_strategy {
@@ -213,6 +230,18 @@
             HwModule *mModule;                     // audio HW module exposing this I/O stream
         };
 
+        class AudioPatch: public RefBase
+        {
+        public:
+            AudioPatch(audio_patch_handle_t handle,
+                       const struct audio_patch *patch, uid_t uid) :
+                           mHandle(handle), mPatch(*patch), mUid(uid), mAfPatchHandle(0) {}
+
+            audio_patch_handle_t mHandle;
+            struct audio_patch mPatch;
+            uid_t mUid;
+            audio_patch_handle_t mAfPatchHandle;
+        };
 
         class DeviceDescriptor: public AudioPort
         {
@@ -236,7 +265,8 @@
             virtual ~DeviceDescriptor() {}
 
             bool equals(const sp<DeviceDescriptor>& other) const;
-            void toAudioPortConfig(struct audio_port_config *config) const;
+            void toAudioPortConfig(struct audio_port_config *dstConfig,
+                                   const struct audio_port_config *srcConfig = NULL) const;
             virtual void toAudioPort(struct audio_port *port) const;
 
             status_t dump(int fd, int spaces) const;
@@ -262,6 +292,7 @@
             void loadDevicesFromType(audio_devices_t types);
             sp<DeviceDescriptor> getDevice(audio_devices_t type, String8 address) const;
             DeviceVector getDevicesFromType(audio_devices_t types) const;
+            sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
 
         private:
             void refreshTypes();
@@ -335,7 +366,8 @@
                              uint32_t inPastMs = 0,
                              nsecs_t sysTime = 0) const;
 
-            void toAudioPortConfig(struct audio_port_config *config) const;
+            void toAudioPortConfig(struct audio_port_config *dstConfig,
+                                   const struct audio_port_config *srcConfig = NULL) const;
             void toAudioPort(struct audio_port *port) const;
 
             audio_port_handle_t mId;
@@ -379,7 +411,8 @@
             audio_source_t mInputSource;                // input source selected by application (mediarecorder.h)
             const sp<IOProfile> mProfile;                  // I/O profile this output derives from
 
-            void toAudioPortConfig(struct audio_port_config *config) const;
+            void toAudioPortConfig(struct audio_port_config *dstConfig,
+                                   const struct audio_port_config *srcConfig = NULL) const;
             void toAudioPort(struct audio_port *port) const;
         };
 
@@ -439,13 +472,17 @@
         uint32_t setOutputDevice(audio_io_handle_t output,
                              audio_devices_t device,
                              bool force = false,
-                             int delayMs = 0);
+                             int delayMs = 0,
+                             audio_patch_handle_t *patchHandle = NULL);
         status_t resetOutputDevice(audio_io_handle_t output,
-                                   int delayMs = 0);
+                                   int delayMs = 0,
+                                   audio_patch_handle_t *patchHandle = NULL);
         status_t setInputDevice(audio_io_handle_t input,
                                 audio_devices_t device,
-                                bool force = false);
-        status_t resetInputDevice(audio_io_handle_t input);
+                                bool force = false,
+                                audio_patch_handle_t *patchHandle = NULL);
+        status_t resetInputDevice(audio_io_handle_t input,
+                                  audio_patch_handle_t *patchHandle = NULL);
 
         // select input device corresponding to requested audio source
         virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource);
@@ -589,6 +626,13 @@
 
         bool isNonOffloadableEffectEnabled();
 
+        status_t addAudioPatch(audio_patch_handle_t handle,
+                               const sp<AudioPatch>& patch);
+        status_t removeAudioPatch(audio_patch_handle_t handle);
+
+        AudioOutputDescriptor *getOutputFromId(audio_port_handle_t id) const;
+        AudioInputDescriptor *getInputFromId(audio_port_handle_t id) const;
+        HwModule *getModuleForDevice(audio_devices_t device) const;
         //
         // Audio policy configuration file parsing (audio_policy.conf)
         //
@@ -610,6 +654,7 @@
         void defaultAudioPolicyConfig(void);
 
 
+        uid_t mUidCached;
         AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
         audio_io_handle_t mPrimaryOutput;              // primary output handle
         // list of descriptors for outputs currently opened
@@ -644,6 +689,9 @@
 
         Vector <HwModule *> mHwModules;
         volatile int32_t mNextUniqueId;
+        volatile int32_t mAudioPortGeneration;
+
+        DefaultKeyedVector<audio_patch_handle_t, sp<AudioPatch> > mAudioPatches;
 
 #ifdef AUDIO_POLICY_TEST
         Mutex   mLock;
@@ -668,6 +716,8 @@
         void handleNotificationRoutingForStream(audio_stream_type_t stream);
         static bool isVirtualInputDevice(audio_devices_t device);
         uint32_t nextUniqueId();
+        uint32_t nextAudioPortGeneration();
+        uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
         // converts device address to string sent to audio HAL via setParameters
         static String8 addressToParameter(audio_devices_t device, const String8 address);
 };