Fix issue 1795088       Improve audio routing code

Initial commit for review.
Integrated comments after patch set 1 review.
Fixed lockup in AudioFlinger::ThreadBase::exit()
Fixed lockup when playing tone with AudioPlocyService startTone()
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 83ff508..503cb31 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -39,21 +39,10 @@
 {
 public:
 
-    // input sources values must always be defined in the range
-    // [AudioRecord::DEFAULT_INPUT, AudioRecord::NUM_INPUT_SOURCES[
-    enum input_source {
-        DEFAULT_INPUT   =-1,
-        MIC_INPUT       = 0,
-        VOICE_UPLINK_INPUT = 1,
-        VOICE_DOWNLINK_INPUT = 2,
-        VOICE_CALL_INPUT = 3,
-        NUM_INPUT_SOURCES
-    };
-
     static const int DEFAULT_SAMPLE_RATE = 8000;
 
     /* Events used by AudioRecord callback function (callback_t).
-     * 
+     *
      * to keep in sync with frameworks/base/media/java/android/media/AudioRecord.java
      */
     enum event_type {
@@ -61,7 +50,7 @@
         EVENT_OVERRUN = 1,          // PCM buffer overrun occured.
         EVENT_MARKER = 2,           // Record head is at the specified marker position
                                     // (See setMarkerPosition()).
-        EVENT_NEW_POS = 3,          // Record head is at a new position 
+        EVENT_NEW_POS = 3,          // Record head is at a new position
                                     // (See setPositionUpdatePeriod()).
     };
 
@@ -123,11 +112,11 @@
      *
      * Parameters:
      *
-     * inputSource:        Select the audio input to record to (e.g. AudioRecord::MIC_INPUT).
+     * inputSource:        Select the audio input to record to (e.g. AUDIO_SOURCE_DEFAULT).
      * sampleRate:         Track sampling rate in Hz.
-     * format:             PCM sample format (e.g AudioSystem::PCM_16_BIT for signed
+     * format:             Audio format (e.g AudioSystem::PCM_16_BIT for signed
      *                     16 bits per sample).
-     * channelCount:       Number of PCM channels (e.g 2 for stereo).
+     * channels:           Channel mask: see AudioSystem::audio_channels.
      * frameCount:         Total size of track PCM buffer in frames. This defines the
      *                     latency of the track.
      * flags:              A bitmask of acoustic values from enum record_flags.  It enables
@@ -148,7 +137,7 @@
                         AudioRecord(int inputSource,
                                     uint32_t sampleRate = 0,
                                     int format          = 0,
-                                    int channelCount    = 0,
+                                    uint32_t channels = AudioSystem::CHANNEL_IN_MONO,
                                     int frameCount      = 0,
                                     uint32_t flags      = 0,
                                     callback_t cbf = 0,
@@ -166,14 +155,14 @@
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful intialization
      *  - INVALID_OPERATION: AudioRecord is already intitialized or record device is already in use
-     *  - BAD_VALUE: invalid parameter (channelCount, format, sampleRate...)
+     *  - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
      *  - NO_INIT: audio server or audio hardware not initialized
      *  - PERMISSION_DENIED: recording is not allowed for the requesting process
      * */
             status_t    set(int inputSource     = 0,
                             uint32_t sampleRate = 0,
                             int format          = 0,
-                            int channelCount    = 0,
+                            uint32_t channels = AudioSystem::CHANNEL_IN_MONO,
                             int frameCount      = 0,
                             uint32_t flags      = 0,
                             callback_t cbf = 0,
@@ -199,6 +188,7 @@
 
             int         format() const;
             int         channelCount() const;
+            int         channels() const;
             uint32_t    frameCount() const;
             int         frameSize() const;
             int         inputSource() const;
@@ -222,8 +212,8 @@
 
     /* Sets marker position. When record reaches the number of frames specified,
      * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
-     * with marker == 0 cancels marker notification callback. 
-     * If the AudioRecord has been opened with no callback function associated, 
+     * with marker == 0 cancels marker notification callback.
+     * If the AudioRecord has been opened with no callback function associated,
      * the operation will fail.
      *
      * Parameters:
@@ -238,10 +228,10 @@
             status_t    getMarkerPosition(uint32_t *marker);
 
 
-    /* Sets position update period. Every time the number of frames specified has been recorded, 
-     * a callback with event type EVENT_NEW_POS is called. 
-     * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification 
-     * callback. 
+    /* Sets position update period. Every time the number of frames specified has been recorded,
+     * a callback with event type EVENT_NEW_POS is called.
+     * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
+     * callback.
      * If the AudioRecord has been opened with no callback function associated,
      * the operation will fail.
      *
@@ -257,8 +247,8 @@
             status_t    getPositionUpdatePeriod(uint32_t *updatePeriod);
 
 
-    /* Gets record head position. The position is the  total number of frames 
-     * recorded since record start. 
+    /* Gets record head position. The position is the  total number of frames
+     * recorded since record start.
      *
      * Parameters:
      *
@@ -270,8 +260,16 @@
      */
             status_t    getPosition(uint32_t *position);
 
-            
-            
+    /* returns a handle on the audio input used by this AudioRecord.
+     *
+     * Parameters:
+     *  none.
+     *
+     * Returned value:
+     *  handle on audio hardware input
+     */
+            audio_io_handle_t    getInput() { return mInput; }
+
     /* obtains a buffer of "frameCount" frames. The buffer must be
      * filled entirely. If the track is stopped, obtainBuffer() returns
      * STOPPED instead of NO_ERROR as long as there are buffers availlable,
@@ -342,6 +340,7 @@
     bool                    mMarkerReached;
     uint32_t                mNewPosition;
     uint32_t                mUpdatePeriod;
+    audio_io_handle_t       mInput;
 };
 
 }; // namespace android
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 3a3a714..0ea04a4 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -24,36 +24,130 @@
 namespace android {
 
 typedef void (*audio_error_callback)(status_t err);
+typedef void * audio_io_handle_t;
+
+class IAudioPolicyService;
+class String8;
 
 class AudioSystem
 {
 public:
 
     enum stream_type {
-        DEFAULT         =-1,
-        VOICE_CALL      = 0,
-        SYSTEM          = 1,
-        RING            = 2,
-        MUSIC           = 3,
-        ALARM           = 4,
-        NOTIFICATION    = 5,
-        BLUETOOTH_SCO   = 6,
+        DEFAULT          =-1,
+        VOICE_CALL       = 0,
+        SYSTEM           = 1,
+        RING             = 2,
+        MUSIC            = 3,
+        ALARM            = 4,
+        NOTIFICATION     = 5,
+        BLUETOOTH_SCO    = 6,
         ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker
+        DTMF             = 8,
+        TTS              = 9,
         NUM_STREAM_TYPES
     };
 
-    enum audio_output_type {
-        AUDIO_OUTPUT_DEFAULT      =-1,
-        AUDIO_OUTPUT_HARDWARE     = 0,
-        AUDIO_OUTPUT_A2DP         = 1,
-        NUM_AUDIO_OUTPUT_TYPES
+    // Audio sub formats (see AudioSystem::audio_format).
+    enum pcm_sub_format {
+        PCM_SUB_16_BIT          = 0x1, // must be 1 for backward compatibility
+        PCM_SUB_8_BIT           = 0x2, // must be 2 for backward compatibility
     };
 
+    // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to specify
+    // bit rate, stereo mode, version...
+    enum mp3_sub_format {
+        //TODO
+    };
+
+    // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient or octet aligned,
+    // encoding mode for recording...
+    enum amr_sub_format {
+        //TODO
+    };
+
+    // AAC sub format field definition: specify profile or bitrate for recording...
+    enum aac_sub_format {
+        //TODO
+    };
+
+    // VORBIS sub format field definition: specify quality for recording...
+    enum vorbis_sub_format {
+        //TODO
+    };
+
+    // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24 bits).
+    // The main format indicates the main codec type. The sub format field indicates options and parameters
+    // for each format. The sub format is mainly used for record to indicate for instance the requested bitrate
+    // or profile. It can also be used for certain formats to give informations not present in the encoded
+    // audio stream (e.g. octet alignement for AMR).
     enum audio_format {
-        FORMAT_DEFAULT = 0,
-        PCM_16_BIT,
-        PCM_8_BIT,
-        INVALID_FORMAT
+        INVALID_FORMAT      = -1,
+        FORMAT_DEFAULT      = 0,
+        PCM                 = 0x00000000, // must be 0 for backward compatibility
+        MP3                 = 0x01000000,
+        AMR_NB              = 0x02000000,
+        AMR_WB              = 0x03000000,
+        AAC                 = 0x04000000,
+        HE_AAC_V1           = 0x05000000,
+        HE_AAC_V2           = 0x06000000,
+        VORBIS              = 0x07000000,
+        MAIN_FORMAT_MASK    = 0xFF000000,
+        SUB_FORMAT_MASK     = 0x00FFFFFF,
+        // Aliases
+        PCM_16_BIT          = (PCM|PCM_SUB_16_BIT),
+        PCM_8_BIT          = (PCM|PCM_SUB_8_BIT)
+    };
+
+
+    // Channel mask definitions must be kept in sync with JAVA values in /media/java/android/media/AudioFormat.java
+    enum audio_channels {
+        // output channels
+        CHANNEL_OUT_FRONT_LEFT = 0x1,
+        CHANNEL_OUT_FRONT_RIGHT = 0x2,
+        CHANNEL_OUT_FRONT_CENTER = 0x4,
+        CHANNEL_OUT_LOW_FREQUENCY = 0x8,
+        CHANNEL_OUT_BACK_LEFT = 0x10,
+        CHANNEL_OUT_BACK_RIGHT = 0x20,
+        CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40,
+        CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80,
+        CHANNEL_OUT_BACK_CENTER = 0x100,
+        CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT,
+        CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT),
+        CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+                CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
+        CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+                CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER),
+        CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+                CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
+        CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+                CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+                CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
+        CHANNEL_OUT_ALL = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+                CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+                CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | CHANNEL_OUT_BACK_CENTER),
+
+        // input channels
+        CHANNEL_IN_LEFT = 0x10000,
+        CHANNEL_IN_RIGHT = 0x20000,
+        CHANNEL_IN_FRONT = 0x40000,
+        CHANNEL_IN_BACK = 0x80000,
+        CHANNEL_IN_LEFT_PROCESSED = 0x100000,
+        CHANNEL_IN_RIGHT_PROCESSED = 0x200000,
+        CHANNEL_IN_FRONT_PROCESSED = 0x400000,
+        CHANNEL_IN_BACK_PROCESSED = 0x800000,
+        CHANNEL_IN_PRESSURE = 0x1000000,
+        CHANNEL_IN_X_AXIS = 0x2000000,
+        CHANNEL_IN_Y_AXIS = 0x4000000,
+        CHANNEL_IN_Z_AXIS = 0x8000000,
+        CHANNEL_IN_VOICE_UPLINK = 0x10000000,
+        CHANNEL_IN_VOICE_DNLINK = 0x20000000,
+        CHANNEL_IN_MONO = CHANNEL_IN_FRONT,
+        CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT),
+        CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK|
+                CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED | CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED|
+                CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS | CHANNEL_IN_Z_AXIS |
+                CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK)
     };
 
     enum audio_mode {
@@ -65,15 +159,6 @@
         NUM_MODES  // not a valid entry, denotes end-of-list
     };
 
-    enum audio_routes {
-        ROUTE_EARPIECE       = (1 << 0),
-        ROUTE_SPEAKER        = (1 << 1),
-        ROUTE_BLUETOOTH_SCO  = (1 << 2),
-        ROUTE_HEADSET        = (1 << 3),
-        ROUTE_BLUETOOTH_A2DP = (1 << 4),
-        ROUTE_ALL            = -1UL,
-    };
-
     enum audio_in_acoustics {
         AGC_ENABLE    = 0x0001,
         AGC_DISABLE   = 0,
@@ -87,36 +172,37 @@
      * only privileged processes can have access to them
      */
 
-    // routing helper functions
-    static status_t speakerphone(bool state);
-    static status_t isSpeakerphoneOn(bool* state);
-    static status_t bluetoothSco(bool state);
-    static status_t isBluetoothScoOn(bool* state);
+    // mute/unmute microphone
     static status_t muteMicrophone(bool state);
     static status_t isMicrophoneMuted(bool *state);
 
+    // set/get master volume
     static status_t setMasterVolume(float value);
-    static status_t setMasterMute(bool mute);
     static status_t getMasterVolume(float* volume);
+    // mute/unmute audio outputs
+    static status_t setMasterMute(bool mute);
     static status_t getMasterMute(bool* mute);
 
-    static status_t setStreamVolume(int stream, float value);
+    // set/get stream volume on specified output
+    static status_t setStreamVolume(int stream, float value, void *output);
+    static status_t getStreamVolume(int stream, float* volume, void *output);
+
+    // mute/unmute stream
     static status_t setStreamMute(int stream, bool mute);
-    static status_t getStreamVolume(int stream, float* volume);
     static status_t getStreamMute(int stream, bool* mute);
 
+    // set audio mode in audio hardware (see AudioSystem::audio_mode)
     static status_t setMode(int mode);
-    static status_t getMode(int* mode);
 
-    static status_t setRouting(int mode, uint32_t routes, uint32_t mask);
-    static status_t getRouting(int mode, uint32_t* routes);
-
+    // returns true if tracks are active on AudioSystem::MUSIC stream
     static status_t isMusicActive(bool *state);
 
-    // Temporary interface, do not use
-    // TODO: Replace with a more generic key:value get/set mechanism
-    static status_t setParameter(const char* key, const char* value);
-    
+    // set/get audio hardware parameters. The function accepts a list of parameters
+    // key value pairs in the form: key1=value1;key2=value2;...
+    // Some keys are reserved for standard parameters (See AudioParameter class).
+    static status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
+    static String8  getParameters(audio_io_handle_t ioHandle, const String8& keys);
+
     static void setErrorCallback(audio_error_callback cb);
 
     // helper function to obtain AudioFlinger service handle
@@ -130,47 +216,247 @@
     static status_t getOutputLatency(uint32_t* latency, int stream = DEFAULT);
 
     static bool routedToA2dpOutput(int streamType);
-    
-    static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, 
+
+    static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
         size_t* buffSize);
 
+
+    //
+    // AudioPolicyService interface
+    //
+
+    enum audio_devices {
+        // output devices
+        DEVICE_OUT_EARPIECE = 0x1,
+        DEVICE_OUT_SPEAKER = 0x2,
+        DEVICE_OUT_WIRED_HEADSET = 0x4,
+        DEVICE_OUT_WIRED_HEADPHONE = 0x8,
+        DEVICE_OUT_BLUETOOTH_SCO = 0x10,
+        DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
+        DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
+        DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
+        DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
+        DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
+        DEVICE_OUT_AUX_DIGITAL = 0x400,
+        DEVICE_OUT_FM_HEADPHONE = 0x800,
+        DEVICE_OUT_FM_SPEAKER = 0x1000,
+        DEVICE_OUT_TTY = 0x2000,
+        DEVICE_OUT_DEFAULT = 0x8000,
+        DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET |
+                DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
+                DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+                DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_FM_HEADPHONE |
+                DEVICE_OUT_FM_SPEAKER | DEVICE_OUT_TTY | DEVICE_OUT_DEFAULT),
+
+        // input devices
+        DEVICE_IN_COMMUNICATION = 0x10000,
+        DEVICE_IN_AMBIENT = 0x20000,
+        DEVICE_IN_BUILTIN_MIC = 0x40000,
+        DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000,
+        DEVICE_IN_WIRED_HEADSET = 0x100000,
+        DEVICE_IN_AUX_DIGITAL = 0x200000,
+        DEVICE_IN_VOICE_CALL = 0x400000,
+        DEVICE_IN_DEFAULT = 0x80000000,
+
+        DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
+                DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
+                DEVICE_IN_VOICE_CALL| DEVICE_IN_DEFAULT)
+    };
+
+    // device connection states used for setDeviceConnectionState()
+    enum device_connection_state {
+        DEVICE_STATE_UNAVAILABLE,
+        DEVICE_STATE_AVAILABLE,
+        NUM_DEVICE_STATES
+    };
+
+    // request to open a direct output with getOutput() (by opposition to sharing an output with other AudioTracks)
+    enum output_flags {
+        OUTPUT_FLAG_INDIRECT = 0x0,
+        OUTPUT_FLAG_DIRECT = 0x1
+    };
+
+    // device categories used for setForceUse()
+    enum forced_config {
+        FORCE_NONE,
+        FORCE_SPEAKER,
+        FORCE_HEADPHONES,
+        FORCE_BT_SCO,
+        FORCE_BT_A2DP,
+        FORCE_WIRED_ACCESSORY,
+        NUM_FORCE_CONFIG,
+        FORCE_DEFAULT = FORCE_NONE
+    };
+
+    // usages used for setForceUse()
+    enum force_use {
+        FOR_COMMUNICATION,
+        FOR_MEDIA,
+        FOR_RECORD,
+        NUM_FORCE_USE
+    };
+
+    // types of io configuration change events received with ioConfigChanged()
+    enum io_config_event {
+        OUTPUT_OPENED,
+        OUTPUT_CLOSED,
+        OUTPUT_CONFIG_CHANGED,
+        INPUT_OPENED,
+        INPUT_CLOSED,
+        INPUT_CONFIG_CHANGED,
+        STREAM_CONFIG_CHANGED,
+        NUM_CONFIG_EVENTS
+    };
+
+    // audio output descritor used to cache output configurations in client process to avoid frequent calls
+    // through IAudioFlinger
+    class OutputDescriptor {
+    public:
+        OutputDescriptor()
+        : samplingRate(0), format(0), channels(0), frameCount(0), latency(0)  {}
+
+        uint32_t samplingRate;
+        int32_t format;
+        int32_t channels;
+        size_t frameCount;
+        uint32_t latency;
+    };
+
+    //
+    // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
+    //
+    static status_t setDeviceConnectionState(audio_devices device, device_connection_state state, const char *device_address);
+    static device_connection_state getDeviceConnectionState(audio_devices device, const char *device_address);
+    static status_t setPhoneState(int state);
+    static status_t setRingerMode(uint32_t mode, uint32_t mask);
+    static status_t setForceUse(force_use usage, forced_config config);
+    static forced_config getForceUse(force_use usage);
+    static audio_io_handle_t getOutput(stream_type stream,
+                                        uint32_t samplingRate = 0,
+                                        uint32_t format = FORMAT_DEFAULT,
+                                        uint32_t channels = CHANNEL_OUT_STEREO,
+                                        output_flags flags = OUTPUT_FLAG_INDIRECT);
+    static status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
+    static status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
+    static void releaseOutput(audio_io_handle_t output);
+    static audio_io_handle_t getInput(int inputSource,
+                                    uint32_t samplingRate = 0,
+                                    uint32_t format = FORMAT_DEFAULT,
+                                    uint32_t channels = CHANNEL_IN_MONO,
+                                    audio_in_acoustics acoustics = (audio_in_acoustics)0);
+    static status_t startInput(audio_io_handle_t input);
+    static status_t stopInput(audio_io_handle_t input);
+    static void releaseInput(audio_io_handle_t input);
+    static status_t initStreamVolume(stream_type stream,
+                                      int indexMin,
+                                      int indexMax);
+    static status_t setStreamVolumeIndex(stream_type stream, int index);
+    static status_t getStreamVolumeIndex(stream_type stream, int *index);
+
+    static const sp<IAudioPolicyService>& get_audio_policy_service();
+
     // ----------------------------------------------------------------------------
 
+    static uint32_t popCount(uint32_t u);
+    static bool isOutputDevice(audio_devices device);
+    static bool isInputDevice(audio_devices device);
+    static bool isA2dpDevice(audio_devices device);
+    static bool isBluetoothScoDevice(audio_devices device);
+    static bool isLowVisibility(stream_type stream);
+    static bool isOutputChannel(uint32_t channel);
+    static bool isInputChannel(uint32_t channel);
+    static bool isValidFormat(uint32_t format);
+    static bool isLinearPCM(uint32_t format);
+
 private:
 
     class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient
     {
     public:
-        AudioFlingerClient() {      
+        AudioFlingerClient() {
         }
-        
+
         // DeathRecipient
         virtual void binderDied(const wp<IBinder>& who);
-        
+
         // IAudioFlingerClient
-        virtual void a2dpEnabledChanged(bool enabled);
-        
+
+        // indicate a change in the configuration of an output or input: keeps the cached
+        // values for output/input parameters upto date in client process
+        virtual void ioConfigChanged(int event, void *param1, void *param2);
     };
-    static int getOutput(int streamType);
+
+    class AudioPolicyServiceClient: public IBinder::DeathRecipient
+    {
+    public:
+        AudioPolicyServiceClient() {
+        }
+
+        // DeathRecipient
+        virtual void binderDied(const wp<IBinder>& who);
+    };
 
     static sp<AudioFlingerClient> gAudioFlingerClient;
-
+    static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
     friend class AudioFlingerClient;
+    friend class AudioPolicyServiceClient;
 
     static Mutex gLock;
     static sp<IAudioFlinger> gAudioFlinger;
     static audio_error_callback gAudioErrorCallback;
-    static int gOutSamplingRate[NUM_AUDIO_OUTPUT_TYPES];
-    static int gOutFrameCount[NUM_AUDIO_OUTPUT_TYPES];
-    static uint32_t gOutLatency[NUM_AUDIO_OUTPUT_TYPES];
-    static bool gA2dpEnabled;
-    
+
     static size_t gInBuffSize;
     // previous parameters for recording buffer size queries
     static uint32_t gPrevInSamplingRate;
     static int gPrevInFormat;
     static int gPrevInChannelCount;
 
+    static sp<IAudioPolicyService> gAudioPolicyService;
+
+    // mapping between stream types and outputs
+    static DefaultKeyedVector<int, audio_io_handle_t> gStreamOutputMap;
+    // list of output descritor containing cached parameters (sampling rate, framecount, channel count...)
+    static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs;
+};
+
+class AudioParameter {
+
+public:
+    AudioParameter() {}
+    AudioParameter(const String8& keyValuePairs);
+    virtual ~AudioParameter();
+
+    // reserved parameter keys for changeing standard parameters with setParameters() function.
+    // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
+    // configuration changes and act accordingly.
+    //  keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices
+    //  keySamplingRate: to change sampling rate routing, value is an int
+    //  keyFormat: to change audio format, value is an int in AudioSystem::audio_format
+    //  keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels
+    //  keyFrameCount: to change audio output frame count, value is an int
+    static const char *keyRouting;
+    static const char *keySamplingRate;
+    static const char *keyFormat;
+    static const char *keyChannels;
+    static const char *keyFrameCount;
+
+    String8 toString();
+
+    status_t add(const String8& key, const String8& value);
+    status_t addInt(const String8& key, const int value);
+    status_t addFloat(const String8& key, const float value);
+
+    status_t remove(const String8& key);
+
+    status_t get(const String8& key, String8& value);
+    status_t getInt(const String8& key, int& value);
+    status_t getFloat(const String8& key, float& value);
+
+    size_t size() { return mParameters.size(); }
+
+private:
+    String8 mKeyValuePairs;
+    KeyedVector <String8, String8> mParameters;
 };
 
 };  // namespace android
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 2e1fbda..981c2f6 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -117,9 +117,9 @@
      * streamType:         Select the type of audio stream this track is attached to
      *                     (e.g. AudioSystem::MUSIC).
      * sampleRate:         Track sampling rate in Hz.
-     * format:             PCM sample format (e.g AudioSystem::PCM_16_BIT for signed
+     * format:             Audio format (e.g AudioSystem::PCM_16_BIT for signed
      *                     16 bits per sample).
-     * channelCount:       Number of PCM channels (e.g 2 for stereo).
+     * channels:           Channel mask: see AudioSystem::audio_channels.
      * frameCount:         Total size of track PCM buffer in frames. This defines the
      *                     latency of the track.
      * flags:              Reserved for future use.
@@ -133,7 +133,7 @@
                         AudioTrack( int streamType,
                                     uint32_t sampleRate  = 0,
                                     int format           = 0,
-                                    int channelCount     = 0,
+                                    int channels         = 0,
                                     int frameCount       = 0,
                                     uint32_t flags       = 0,
                                     callback_t cbf       = 0,
@@ -152,7 +152,7 @@
                         AudioTrack( int streamType,
                                     uint32_t sampleRate = 0,
                                     int format          = 0,
-                                    int channelCount    = 0,
+                                    int channels        = 0,
                                     const sp<IMemory>& sharedBuffer = 0,
                                     uint32_t flags      = 0,
                                     callback_t cbf      = 0,
@@ -169,13 +169,13 @@
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful intialization
      *  - INVALID_OPERATION: AudioTrack is already intitialized
-     *  - BAD_VALUE: invalid parameter (channelCount, format, sampleRate...)
+     *  - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
      *  - NO_INIT: audio server or audio hardware not initialized
      * */
             status_t    set(int streamType      =-1,
                             uint32_t sampleRate = 0,
                             int format          = 0,
-                            int channelCount    = 0,
+                            int channels        = 0,
                             int frameCount      = 0,
                             uint32_t flags      = 0,
                             callback_t cbf      = 0,
@@ -330,6 +330,16 @@
      */
             status_t    reload();
 
+    /* returns a handle on the audio output used by this AudioTrack.
+     *
+     * Parameters:
+     *  none.
+     *
+     * Returned value:
+     *  handle on audio hardware output
+     */
+            audio_io_handle_t    getOutput();
+
     /* obtains a buffer of "frameCount" frames. The buffer must be
      * filled entirely. If the track is stopped, obtainBuffer() returns
      * STOPPED instead of NO_ERROR as long as there are buffers availlable,
@@ -387,7 +397,6 @@
     sp<AudioTrackThread>    mAudioTrackThread;
 
     float                   mVolume[2];
-    uint32_t                mSampleRate;
     uint32_t                mFrameCount;
 
     audio_track_cblk_t*     mCblk;
@@ -395,6 +404,7 @@
     uint8_t                 mFormat;
     uint8_t                 mChannelCount;
     uint8_t                 mMuted;
+    uint32_t                mChannels;
     status_t                mStatus;
     uint32_t                mLatency;
 
@@ -410,6 +420,7 @@
     bool                    mMarkerReached;
     uint32_t                mNewPosition;
     uint32_t                mUpdatePeriod;
+    uint32_t                mFlags;
 };
 
 
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index bac3d29..26e6972 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -27,7 +27,7 @@
 #include <media/IAudioTrack.h>
 #include <media/IAudioRecord.h>
 #include <media/IAudioFlingerClient.h>
-
+#include <utils/String8.h>
 
 namespace android {
 
@@ -50,11 +50,12 @@
                                 int frameCount,
                                 uint32_t flags,
                                 const sp<IMemory>& sharedBuffer,
+                                void *output,
                                 status_t *status) = 0;
 
     virtual sp<IAudioRecord> openRecord(
                                 pid_t pid,
-                                int inputSource,
+                                void *input,
                                 uint32_t sampleRate,
                                 int format,
                                 int channelCount,
@@ -65,11 +66,11 @@
     /* query the audio hardware state. This state never changes,
      * and therefore can be cached.
      */
-    virtual     uint32_t    sampleRate(int output) const = 0;
-    virtual     int         channelCount(int output) const = 0;
-    virtual     int         format(int output) const = 0;
-    virtual     size_t      frameCount(int output) const = 0;
-    virtual     uint32_t    latency(int output) const = 0;
+    virtual     uint32_t    sampleRate(void *output) const = 0;
+    virtual     int         channelCount(void *output) const = 0;
+    virtual     int         format(void *output) const = 0;
+    virtual     size_t      frameCount(void *output) const = 0;
+    virtual     uint32_t    latency(void *output) const = 0;
 
     /* set/get the audio hardware state. This will probably be used by
      * the preference panel, mostly.
@@ -83,19 +84,14 @@
     /* set/get stream type state. This will probably be used by
      * the preference panel, mostly.
      */
-    virtual     status_t    setStreamVolume(int stream, float value) = 0;
+    virtual     status_t    setStreamVolume(int stream, float value, void *output) = 0;
     virtual     status_t    setStreamMute(int stream, bool muted) = 0;
 
-    virtual     float       streamVolume(int stream) const = 0;
+    virtual     float       streamVolume(int stream, void *output) const = 0;
     virtual     bool        streamMute(int stream) const = 0;
 
-    // set/get audio routing
-    virtual     status_t    setRouting(int mode, uint32_t routes, uint32_t mask) = 0;
-    virtual     uint32_t    getRouting(int mode) const = 0;
-
-    // set/get audio mode
+    // set audio mode
     virtual     status_t    setMode(int mode) = 0;
-    virtual     int         getMode() const = 0;
 
     // mic mute/state
     virtual     status_t    setMicMute(bool state) = 0;
@@ -104,22 +100,34 @@
     // is a music stream active?
     virtual     bool        isMusicActive() const = 0;
 
-    // pass a generic configuration parameter to libaudio
-    // Temporary interface, do not use
-    // TODO: Replace with a more generic key:value get/set mechanism
-    virtual     status_t  setParameter(const char* key, const char* value) = 0;
+    virtual     status_t    setParameters(void *ioHandle, const String8& keyValuePairs) = 0;
+    virtual     String8     getParameters(void *ioHandle, const String8& keys) = 0;
     
     // register a current process for audio output change notifications
     virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
     
     // retrieve the audio recording buffer size
     virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
-    
-    // force AudioFlinger thread out of standby
-    virtual     void        wakeUp() = 0;
 
-    // is A2DP output enabled
-    virtual     bool        isA2dpEnabled() const = 0;
+    virtual void *openOutput(uint32_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    uint32_t *pFormat,
+                                    uint32_t *pChannels,
+                                    uint32_t *pLatencyMs,
+                                    uint32_t flags) = 0;
+    virtual void *openDuplicateOutput(void *output1, void *output2) = 0;
+    virtual status_t closeOutput(void *output) = 0;
+    virtual status_t suspendOutput(void *output) = 0;
+    virtual status_t restoreOutput(void *output) = 0;
+
+    virtual void *openInput(uint32_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    uint32_t *pFormat,
+                                    uint32_t *pChannels,
+                                    uint32_t acoustics) = 0;
+    virtual status_t closeInput(void *input) = 0;
+
+    virtual status_t setStreamOutput(uint32_t stream, void *output) = 0;
 };
 
 
diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h
index 383ec0c..78142ce 100644
--- a/include/media/IAudioFlingerClient.h
+++ b/include/media/IAudioFlingerClient.h
@@ -20,7 +20,7 @@
 
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
-
+#include <utils/KeyedVector.h>
 
 namespace android {
 
@@ -31,8 +31,8 @@
 public:
     DECLARE_META_INTERFACE(AudioFlingerClient);
 
-    // Notifies a change of audio output from/to hardware to/from A2DP.
-    virtual void a2dpEnabledChanged(bool enabled) = 0;
+    // Notifies a change of audio input/output configuration.
+    virtual void ioConfigChanged(int event, void *param1, void *param2) = 0;
 
 };
 
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
new file mode 100644
index 0000000..4804bbd
--- /dev/null
+++ b/include/media/IAudioPolicyService.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IAUDIOPOLICYSERVICE_H
+#define ANDROID_IAUDIOPOLICYSERVICE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <media/AudioSystem.h>
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioPolicyService : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(AudioPolicyService);
+
+    //
+    // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
+    //
+    virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
+                                              AudioSystem::device_connection_state state,
+                                              const char *device_address) = 0;
+    virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device,
+                                                                          const char *device_address) = 0;
+    virtual status_t setPhoneState(int state) = 0;
+    virtual status_t setRingerMode(uint32_t mode, uint32_t mask) = 0;
+    virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) = 0;
+    virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) = 0;
+    virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
+                                        uint32_t samplingRate = 0,
+                                        uint32_t format = AudioSystem::FORMAT_DEFAULT,
+                                        uint32_t channels = 0,
+                                        AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT) = 0;
+    virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream) = 0;
+    virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream) = 0;
+    virtual void releaseOutput(audio_io_handle_t output) = 0;
+    virtual audio_io_handle_t getInput(int inputSource,
+                                    uint32_t samplingRate = 0,
+                                    uint32_t format = AudioSystem::FORMAT_DEFAULT,
+                                    uint32_t channels = 0,
+                                    AudioSystem::audio_in_acoustics acoustics = (AudioSystem::audio_in_acoustics)0) = 0;
+    virtual status_t startInput(audio_io_handle_t input) = 0;
+    virtual status_t stopInput(audio_io_handle_t input) = 0;
+    virtual void releaseInput(audio_io_handle_t input) = 0;
+    virtual status_t initStreamVolume(AudioSystem::stream_type stream,
+                                      int indexMin,
+                                      int indexMax) = 0;
+    virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index) = 0;
+    virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnAudioPolicyService : public BnInterface<IAudioPolicyService>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOPOLICYSERVICE_H
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 496a739..8e2db20 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -55,17 +55,18 @@
                     uint32_t    volumeLR;
                 };
                 uint32_t    sampleRate;
+                // NOTE: audio_track_cblk_t::frameSize is not equal to AudioTrack::frameSize() for
+                // 8 bit PCM data: in this case,  mCblk->frameSize is based on a sample size of
+                // 16 bit because data is converted to 16 bit before being stored in buffer
+                uint32_t    frameSize;
                 uint8_t     channels;
                 uint8_t     flowControlFlag; // underrun (out) or overrrun (in) indication
                 uint8_t     out;        // out equals 1 for AudioTrack and 0 for AudioRecord
-                uint8_t     forceReady; 
+                uint8_t     forceReady;
                 uint16_t    bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
                 uint16_t    waitTimeMs;      // Cumulated wait time
-                // Padding ensuring that data buffer starts on a cache line boundary (32 bytes). 
-                // See AudioFlinger::TrackBase constructor
-                int32_t     Padding[1];
-                // Cache line boundary
-                
+                // Cache line boundary (32 bytes)
+
                             audio_track_cblk_t();
                 uint32_t    stepUser(uint32_t frameCount);
                 bool        stepServer(uint32_t frameCount);
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index ed084ca..28b0d2f 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -43,7 +43,7 @@
 // @param [inout] void *&       - The userdata pointer set in the original
 //                                 synth call
 // @param [in]    uint32_t      - Track sampling rate in Hz
-// @param [in]    audio_format  - The AudioSystem::audio_format enum
+// @param [in]    uint32_t      - The audio format
 // @param [in]    int           - The number of channels
 // @param [inout] int8_t *&     - A buffer of audio data only valid during the
 //                                execution of the callback
@@ -54,7 +54,7 @@
 //         TTS_CALLBACK_CONTINUE to indicate the synthesis must continue if
 //            there is more data to produce.
 typedef tts_callback_status (synthDoneCB_t)(void *&, uint32_t,
-        AudioSystem::audio_format, int, int8_t *&, size_t&, tts_synth_status);
+        uint32_t, int, int8_t *&, size_t&, tts_synth_status);
 
 class TtsEngine;
 extern "C" TtsEngine* getTtsEngine();