Explicit routing in AudioRecord

Change-Id: I9cc5d54883a3e5c75d553fabb619fc8e49f4f9e5
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 521f6c4..b965411 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -131,6 +131,7 @@
                                          audio_format_t format,
                                          audio_channel_mask_t channelMask,
                                          audio_input_flags_t flags,
+                                         audio_port_handle_t selectedDeviceId,
                                          input_type_t *inputType);
 
         // indicates to the audio policy manager that the input starts being used.
@@ -233,45 +234,84 @@
         routing_strategy getStrategy(audio_stream_type_t stream) const;
 
 protected:
-        class SessionRoute : public RefBase
-        {
+        class SessionRoute : public RefBase {
         public:
-            friend class SessionRouteMap;
+            // For Input (Source) routes, use STREAM_TYPE_NA ("NA" = "not applicable)for the
+            // streamType argument
+            static const audio_stream_type_t STREAM_TYPE_NA = AUDIO_STREAM_DEFAULT;
+
+            // For Output (Sink) routes, use SOURCE_TYPE_NA ("NA" = "not applicable") for the
+            // source argument
+
+            static const audio_source_t SOURCE_TYPE_NA = AUDIO_SOURCE_DEFAULT;
+
             SessionRoute(audio_session_t session,
                          audio_stream_type_t streamType,
+                         audio_source_t source,
                          sp<DeviceDescriptor> deviceDescriptor)
-                : mSession(session),
-                  mStreamType(streamType),
-                  mDeviceDescriptor(deviceDescriptor),
-                  mRefCount(0),
-                  mActivityCount(0),
-                  mChanged(false) {}
-
-            void log(const char* prefix);
+               : mSession(session),
+                 mDeviceDescriptor(deviceDescriptor),
+                 mRefCount(0),
+                 mActivityCount(0),
+                 mChanged(false),
+                 mStreamType(streamType),
+                 mSource(source) {}
 
             audio_session_t         mSession;
-            audio_stream_type_t     mStreamType;
 
             sp<DeviceDescriptor>    mDeviceDescriptor;
 
+            void log(const char* prefix);
+
             // "reference" counting
             int                     mRefCount;      // +/- on references
             int                     mActivityCount; // +/- on start/stop
             bool                    mChanged;
+
+            // for outputs
+            const audio_stream_type_t     mStreamType;
+
+            // for inputs
+            const audio_source_t          mSource;
         };
 
-        class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>>
-        {
-         public:
+        class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>> {
+        public:
+            // These constants identify the SessionRoutMap as holding EITHER input routes,
+            // or output routes.  An error will occur if an attempt is made to add a SessionRoute
+            // object with mStreamType == STREAM_TYPE_NA (i.e. an input SessionRoute) to a
+            // SessionRoutMap that is marked for output (i.e. mMapType == SESSION_ROUTE_MAP_OUTPUT)
+            // and similarly  for output SessionRoutes and Input SessionRouteMaps.
+            typedef enum {
+              MAPTYPE_INPUT = 0,
+              MAPTYPE_OUTPUT = 1
+            } session_route_map_type_t;
+
+            SessionRouteMap(session_route_map_type_t mapType) :
+                mMapType(mapType) {
+            }
+
             bool hasRoute(audio_session_t session);
-            void addRoute(audio_session_t session, audio_stream_type_t streamType,
-                          sp<DeviceDescriptor> deviceDescriptor);
             void removeRoute(audio_session_t session);
 
             int incRouteActivity(audio_session_t session);
             int decRouteActivity(audio_session_t session);
             bool hasRouteChanged(audio_session_t session); // also clears the changed flag
             void log(const char* caption);
+
+            // Specify an Output(Sink) route by passing SessionRoute::SOURCE_TYPE_NA in the
+            // source argument.
+            // Specify an Input(Source) rout by passing SessionRoute::AUDIO_STREAM_DEFAULT
+            // in the streamType argument.
+            void addRoute(audio_session_t session,
+                          audio_stream_type_t streamType,
+                          audio_source_t source,
+                          sp<DeviceDescriptor> deviceDescriptor);
+
+        private:
+            // Used to mark a SessionRoute as for either inputs (mMapType == kSessionRouteMap_Input)
+            // or outputs (mMapType == kSessionRouteMap_Output)
+            const session_route_map_type_t mMapType;
         };
 
         // From AudioPolicyManagerObserver
@@ -535,8 +575,8 @@
         DeviceVector  mAvailableOutputDevices; // all available output devices
         DeviceVector  mAvailableInputDevices;  // all available input devices
 
-        SessionRouteMap mOutputRoutes;
-        SessionRouteMap mInputRoutes;
+        SessionRouteMap mOutputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_OUTPUT);
+        SessionRouteMap mInputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_INPUT);
 
         StreamDescriptorCollection mStreams; // stream descriptors for volume control
         bool    mLimitRingtoneVolume;        // limit ringtone volume to music volume if headset connected