auto import from //branches/cupcake/...@131421
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 38fa001..3b5932d 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -33,6 +33,7 @@
 #include <utils/MemoryDealer.h>
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
+#include <utils/Vector.h>
 
 #include <hardware_legacy/AudioHardwareInterface.h>
 
@@ -55,18 +56,13 @@
 
 static const nsecs_t kStandbyTimeInNsecs = seconds(3);
 
-class AudioFlinger : public BnAudioFlinger, protected Thread, public IBinder::DeathRecipient 
+class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient 
 {
 public:
     static void instantiate();
 
     virtual     status_t    dump(int fd, const Vector<String16>& args);
 
-    // Thread virtuals
-    virtual     bool        threadLoop();
-    virtual     status_t    readyToRun();
-    virtual     void        onFirstRef();
-
     // IAudioFlinger interface
     virtual sp<IAudioTrack> createTrack(
                                 pid_t pid,
@@ -79,11 +75,11 @@
                                 const sp<IMemory>& sharedBuffer,
                                 status_t *status);
 
-    virtual     uint32_t    sampleRate() const;
-    virtual     int         channelCount() const;
-    virtual     int         format() const;
-    virtual     size_t      frameCount() const;
-    virtual     size_t      latency() const;
+    virtual     uint32_t    sampleRate(int output) const;
+    virtual     int         channelCount(int output) const;
+    virtual     int         format(int output) const;
+    virtual     size_t      frameCount(int output) const;
+    virtual     uint32_t    latency(int output) const;
 
     virtual     status_t    setMasterVolume(float value);
     virtual     status_t    setMasterMute(bool muted);
@@ -108,6 +104,8 @@
 
     virtual     bool        isMusicActive() const;
 
+    virtual     bool        isA2dpEnabled() const;
+
     virtual     status_t    setParameter(const char* key, const char* value);
 
     virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
@@ -159,23 +157,26 @@
                             AudioFlinger();
     virtual                 ~AudioFlinger();
     
-    void                    setOutput(AudioStreamOut* output);
-    void                    doSetOutput(AudioStreamOut* output);
-    size_t                  getOutputFrameCount(AudioStreamOut* output);
+    void                    setOutput(int outputType);
+    void                    doSetOutput(int outputType);
 
 #ifdef WITH_A2DP
-    static bool             streamDisablesA2dp(int streamType);
-    inline bool             isA2dpEnabled() const {
-                                return (mRequestedOutput == mA2dpOutput ||
-                                        (mOutput && mOutput == mA2dpOutput));
-                            }
     void                    setA2dpEnabled(bool enable);
 #endif
+    static bool             streamForcedToSpeaker(int streamType);
+    
+    // Management of forced route to speaker for certain track types.
+    enum force_speaker_command {
+        ACTIVE_TRACK_ADDED = 0,
+        ACTIVE_TRACK_REMOVED,
+        CHECK_ROUTE_RESTORE_TIME,
+        FORCE_ROUTE_RESTORE
+    };
+    void                    handleForcedSpeakerRoute(int command);
 
     // Internal dump utilites.
     status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
     status_t dumpClients(int fd, const Vector<String16>& args);
-    status_t dumpTracks(int fd, const Vector<String16>& args);
     status_t dumpInternals(int fd, const Vector<String16>& args);
 
     // --- Client ---
@@ -194,168 +195,348 @@
     };
 
 
-    // --- Track ---
     class TrackHandle;
     class RecordHandle;
     class AudioRecordThread;
 
-    // base for record and playback
-    class TrackBase : public AudioBufferProvider, public RefBase {
-
+    
+    // --- MixerThread ---
+    class MixerThread : public Thread {
     public:
-        enum track_state {
-            IDLE,
-            TERMINATED,
-            STOPPED,
-            RESUMING,
-            ACTIVE,
-            PAUSING,
-            PAUSED
+        
+        // --- Track ---
+
+        // base for record and playback
+        class TrackBase : public AudioBufferProvider, public RefBase {
+
+        public:
+            enum track_state {
+                IDLE,
+                TERMINATED,
+                STOPPED,
+                RESUMING,
+                ACTIVE,
+                PAUSING,
+                PAUSED
+            };
+
+            enum track_flags {
+                STEPSERVER_FAILED = 0x01   //  StepServer could not acquire cblk->lock mutex
+            };
+
+                                TrackBase(  const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~TrackBase();
+
+            virtual status_t    start() = 0;
+            virtual void        stop() = 0;
+                    sp<IMemory> getCblk() const;
+
+        protected:
+            friend class MixerThread;
+            friend class RecordHandle;
+            friend class AudioRecordThread;
+
+                                TrackBase(const TrackBase&);
+                                TrackBase& operator = (const TrackBase&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+            virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
+            audio_track_cblk_t* cblk() const {
+                return mCblk;
+            }
+
+            int type() const {
+                return mStreamType;
+            }
+
+            int format() const {
+                return mFormat;
+            }
+
+            int channelCount() const ;
+
+            int sampleRate() const;
+
+            void* getBuffer(uint32_t offset, uint32_t frames) const;
+
+            int name() const {
+                return mName;
+            }
+
+            bool isStopped() const {
+                return mState == STOPPED;
+            }
+
+            bool isTerminated() const {
+                return mState == TERMINATED;
+            }
+
+            bool step();
+            void reset();
+
+            sp<MixerThread>     mMixerThread;
+            sp<Client>          mClient;
+            sp<IMemory>         mCblkMemory;
+            audio_track_cblk_t* mCblk;
+            int                 mStreamType;
+            void*               mBuffer;
+            void*               mBufferEnd;
+            uint32_t            mFrameCount;
+            int                 mName;
+            // we don't really need a lock for these
+            int                 mState;
+            int                 mClientTid;
+            uint8_t             mFormat;
+            uint8_t             mFlags;
         };
 
-        enum track_flags {
-            STEPSERVER_FAILED = 0x01   //  StepServer could not acquire cblk->lock mutex
+        // playback track
+        class Track : public TrackBase {
+        public:
+                                Track(  const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~Track();
+
+                    void        dump(char* buffer, size_t size);
+            virtual status_t    start();
+            virtual void        stop();
+                    void        pause();
+
+                    void        flush();
+                    void        destroy();
+                    void        mute(bool);
+                    void        setVolume(float left, float right);
+
+        protected:
+            friend class MixerThread;
+            friend class AudioFlinger;
+            friend class AudioFlinger::TrackHandle;
+
+                                Track(const Track&);
+                                Track& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool isMuted() const {
+                return (mMute || mMixerThread->mStreamTypes[mStreamType].mute);
+            }
+
+            bool isPausing() const {
+                return mState == PAUSING;
+            }
+
+            bool isPaused() const {
+                return mState == PAUSED;
+            }
+
+            bool isReady() const;
+
+            void setPaused() { mState = PAUSED; }
+            void reset();
+
+            // we don't really need a lock for these
+            float               mVolume[2];
+            volatile bool       mMute;
+            // FILLED state is used for suppressing volume ramp at begin of playing
+            enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
+            mutable uint8_t     mFillingUpStatus;
+            int8_t              mRetryCount;
+            sp<IMemory>         mSharedBuffer;
+            bool                mResetDone;
+        };  // end of Track
+
+        // record track
+        class RecordTrack : public TrackBase {
+        public:
+                                RecordTrack(  const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount);
+                                ~RecordTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+
+                    bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
+                    bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+
+        private:
+            friend class AudioFlinger;
+            friend class AudioFlinger::RecordHandle;
+            friend class AudioFlinger::AudioRecordThread;
+            friend class MixerThread;
+
+                                RecordTrack(const Track&);
+                                RecordTrack& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool                mOverflow;
         };
 
-                            TrackBase(  const sp<AudioFlinger>& audioFlinger,
-                                    const sp<Client>& client,
+        // playback track
+        class OutputTrack : public Track {
+        public:
+            
+            class Buffer: public AudioBufferProvider::Buffer {
+            public:
+                int16_t *mBuffer;
+            };
+            
+                                OutputTrack(  const sp<MixerThread>& mixerThread,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount);
+                                ~OutputTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+                    void        write(int16_t* data, uint32_t frames);
+                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
+
+        private:
+
+            status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer);
+            void                clearBufferQueue();
+            
+            sp<MixerThread>             mOutputMixerThread;
+            Vector < Buffer* >          mBufferQueue;
+            AudioBufferProvider::Buffer mOutBuffer;
+            uint32_t                    mFramesWritten;
+            
+         };  // end of OutputTrack
+
+        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType);
+        virtual             ~MixerThread();
+
+        virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+        virtual     status_t    readyToRun();
+        virtual     void        onFirstRef();
+
+        virtual     uint32_t    sampleRate() const;
+        virtual     int         channelCount() const;
+        virtual     int         format() const;
+        virtual     size_t      frameCount() const;
+        virtual     uint32_t    latency() const;
+
+        virtual     status_t    setMasterVolume(float value);
+        virtual     status_t    setMasterMute(bool muted);
+
+        virtual     float       masterVolume() const;
+        virtual     bool        masterMute() const;
+
+        virtual     status_t    setStreamVolume(int stream, float value);
+        virtual     status_t    setStreamMute(int stream, bool muted);
+
+        virtual     float       streamVolume(int stream) const;
+        virtual     bool        streamMute(int stream) const;
+
+                    bool        isMusicActive() const;
+        
+                    
+        sp<Track> createTrack(
+                                    const sp<AudioFlinger::Client>& client,
                                     int streamType,
                                     uint32_t sampleRate,
                                     int format,
                                     int channelCount,
                                     int frameCount,
-                                    const sp<IMemory>& sharedBuffer);
-                            ~TrackBase();
+                                    const sp<IMemory>& sharedBuffer,
+                                    status_t *status);
 
-        virtual status_t    start() = 0;
-        virtual void        stop() = 0;
-                sp<IMemory> getCblk() const;
-
-    protected:
-        friend class AudioFlinger;
-        friend class RecordHandle;
-        friend class AudioRecordThread;
-
-                            TrackBase(const TrackBase&);
-                            TrackBase& operator = (const TrackBase&);
-
-        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
-        virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
-        audio_track_cblk_t* cblk() const {
-            return mCblk;
-        }
-
-        int type() const {
-            return mStreamType;
-        }
-
-        int format() const {
-            return mFormat;
-        }
-
-        int channelCount() const ;
-
-        int sampleRate() const;
-
-        void* getBuffer(uint32_t offset, uint32_t frames) const;
-
-        int name() const {
-            return mName;
-        }
-
-        bool isStopped() const {
-            return mState == STOPPED;
-        }
-
-        bool isTerminated() const {
-            return mState == TERMINATED;
-        }
-
-        bool step();
-        void reset();
-
-        sp<AudioFlinger>    mAudioFlinger;
-        sp<Client>          mClient;
-        sp<IMemory>         mCblkMemory;
-        audio_track_cblk_t* mCblk;
-        int                 mStreamType;
-        void*               mBuffer;
-        void*               mBufferEnd;
-        uint32_t            mFrameCount;
-        int                 mName;
-        // we don't really need a lock for these
-        int                 mState;
-        int                 mClientTid;
-        uint8_t             mFormat;
-        uint8_t             mFlags;
-    };
-
-    // playback track
-    class Track : public TrackBase {
-    public:
-                            Track(  const sp<AudioFlinger>& audioFlinger,
-                                    const sp<Client>& client,
-                                    int streamType,
-                                    uint32_t sampleRate,
-                                    int format,
-                                    int channelCount,
-                                    int frameCount,
-                                    const sp<IMemory>& sharedBuffer);
-                            ~Track();
-
-                void        dump(char* buffer, size_t size);
-        virtual status_t    start();
-        virtual void        stop();
-                void        pause();
-
-                void        flush();
-                void        destroy();
-                void        mute(bool);
-                void        setVolume(float left, float right);
+                    void        wakeUp() { mWaitWorkCV.broadcast(); }
+                    
+                    void        getTracks(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        putTracks(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        setOuputTrack(OutputTrack *track) { mOutputTrack = track; }
+                    
+        struct  stream_type_t {
+            stream_type_t()
+                :   volume(1.0f),
+                    mute(false)
+            {
+            }
+            float       volume;
+            bool        mute;
+        };
 
     private:
+
+
         friend class AudioFlinger;
-        friend class TrackHandle;
+        friend class Track;
+        friend class TrackBase;
+        friend class RecordTrack;
+        
+        MixerThread(const Client&);
+        MixerThread& operator = (const MixerThread&);
+  
+        status_t    addTrack(const sp<Track>& track);
+        void        removeTrack(wp<Track> track, int name);
+        void        remove_track_l(wp<Track> track, int name);
+        void        destroyTrack(const sp<Track>& track);
+        int         getTrackName();
+        void        deleteTrackName(int name);
+        void        addActiveTrack(const wp<Track>& t);
+        void        removeActiveTrack(const wp<Track>& t);
+        size_t      getOutputFrameCount();
 
-                            Track(const Track&);
-                            Track& operator = (const Track&);
+        status_t    dumpInternals(int fd, const Vector<String16>& args);
+        status_t    dumpTracks(int fd, const Vector<String16>& args);
+        
+        sp<AudioFlinger>                mAudioFlinger;       
+        mutable     Mutex               mLock;
+        mutable     Condition           mWaitWorkCV;
+        SortedVector< wp<Track> >       mActiveTracks;
+        SortedVector< sp<Track> >       mTracks;
+        stream_type_t                   mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
+        AudioMixer*                     mAudioMixer;
+        AudioStreamOut*                 mOutput;
+        int                             mOutputType;
+        uint32_t                        mSampleRate;
+        size_t                          mFrameCount;
+        int                             mChannelCount;
+        int                             mFormat;
+        int16_t*                        mMixBuffer;
+        float                           mMasterVolume;
+        bool                            mMasterMute;
+        nsecs_t                         mLastWriteTime;
+        int                             mNumWrites;
+        int                             mNumDelayedWrites;
+        bool                            mStandby;
+        bool                            mInWrite;
+        sp <OutputTrack>                mOutputTrack;
+    };
 
-        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
-        bool isMuted() const {
-            return (mMute || mAudioFlinger->mStreamTypes[mStreamType].mute);
-        }
-
-        bool isPausing() const {
-            return mState == PAUSING;
-        }
-
-        bool isPaused() const {
-            return mState == PAUSED;
-        }
-
-        bool isReady() const;
-
-        void setPaused() { mState = PAUSED; }
-        void reset();
-
-        // we don't really need a lock for these
-        float               mVolume[2];
-        volatile bool       mMute;
-        // FILLED state is used for suppressing volume ramp at begin of playing
-        enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
-        mutable uint8_t     mFillingUpStatus;
-        int8_t              mRetryCount;
-        sp<IMemory>         mSharedBuffer;
-        bool                mResetDone;
-    };  // end of Track
-
+    
     friend class AudioBuffer;
 
     class TrackHandle : public android::BnAudioTrack {
     public:
-                            TrackHandle(const sp<Track>& track);
+                            TrackHandle(const sp<MixerThread::Track>& track);
         virtual             ~TrackHandle();
         virtual status_t    start();
         virtual void        stop();
@@ -367,72 +548,20 @@
         virtual status_t onTransact(
             uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
     private:
-        sp<Track> mTrack;
-    };
-
-    struct  stream_type_t {
-        stream_type_t()
-            :   volume(1.0f),
-                mute(false)
-        {
-        }
-        float       volume;
-        bool        mute;
+        sp<MixerThread::Track> mTrack;
     };
 
     friend class Client;
-    friend class Track;
+    friend class MixerThread::Track;
 
 
                 void        removeClient(pid_t pid);
 
-                status_t    addTrack(const sp<Track>& track);
-                void        removeTrack(wp<Track> track, int name);
-                void        remove_track_l(wp<Track> track, int name);
-                void        destroyTrack(const sp<Track>& track);
-                void        addActiveTrack(const wp<Track>& track);
-                void        removeActiveTrack(const wp<Track>& track);
-                int         getTrackName();
-                void        deleteTrackName(int name);
 
-                AudioMixer* audioMixer() {
-                    return mAudioMixer;
-                }
-
-    // record track
-    class RecordTrack : public TrackBase {
-    public:
-                            RecordTrack(  const sp<AudioFlinger>& audioFlinger,
-                                    const sp<Client>& client,
-                                    int streamType,
-                                    uint32_t sampleRate,
-                                    int format,
-                                    int channelCount,
-                                    int frameCount);
-                            ~RecordTrack();
-
-        virtual status_t    start();
-        virtual void        stop();
-
-                bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
-                bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
-
-    private:
-        friend class AudioFlinger;
-        friend class RecordHandle;
-        friend class AudioRecordThread;
-
-                            RecordTrack(const Track&);
-                            RecordTrack& operator = (const Track&);
-
-        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
-        bool                mOverflow;
-    };
 
     class RecordHandle : public android::BnAudioRecord {
     public:
-        RecordHandle(const sp<RecordTrack>& recordTrack);
+        RecordHandle(const sp<MixerThread::RecordTrack>& recordTrack);
         virtual             ~RecordHandle();
         virtual status_t    start();
         virtual void        stop();
@@ -440,7 +569,7 @@
         virtual status_t onTransact(
             uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
     private:
-        sp<RecordTrack> mRecordTrack;
+        sp<MixerThread::RecordTrack> mRecordTrack;
     };
 
     // record thread
@@ -453,14 +582,14 @@
         virtual status_t    readyToRun() { return NO_ERROR; }
         virtual void        onFirstRef() {}
 
-                status_t    start(RecordTrack* recordTrack);
-                void        stop(RecordTrack* recordTrack);
+                status_t    start(MixerThread::RecordTrack* recordTrack);
+                void        stop(MixerThread::RecordTrack* recordTrack);
                 void        exit();
 
     private:
                 AudioRecordThread();
                 AudioHardwareInterface              *mAudioHardware;
-                sp<RecordTrack>                     mRecordTrack;
+                sp<MixerThread::RecordTrack>        mRecordTrack;
                 Mutex                               mLock;
                 Condition                           mWaitWorkCV;
                 volatile bool                       mActive;
@@ -468,48 +597,31 @@
     };
 
     friend class AudioRecordThread;
+    friend class MixerThread;
 
-                status_t    startRecord(RecordTrack* recordTrack);
-                void        stopRecord(RecordTrack* recordTrack);
-
-                void notifyOutputChange_l();
+                status_t    startRecord(MixerThread::RecordTrack* recordTrack);
+                void        stopRecord(MixerThread::RecordTrack* recordTrack);
+                
+                void        handleOutputSwitch();
 
     mutable     Mutex                                       mHardwareLock;
     mutable     Mutex                                       mLock;
-    mutable     Condition                                   mWaitWorkCV;
                 DefaultKeyedVector< pid_t, wp<Client> >     mClients;
-                SortedVector< wp<Track> >                   mActiveTracks;
-                SortedVector< sp<Track> >                   mTracks;
-                float                               mMasterVolume;
-                uint32_t                            mMasterRouting;
-                bool                                mMasterMute;
-                stream_type_t                       mStreamTypes[AudioTrack::NUM_STREAM_TYPES];
 
-                AudioMixer*                         mHardwareAudioMixer;
-                AudioMixer*                         mA2dpAudioMixer;
-                AudioMixer*                         mAudioMixer;
+                sp<MixerThread>                     mA2dpMixerThread;
+                sp<MixerThread>                     mHardwareMixerThread;
                 AudioHardwareInterface*             mAudioHardware;
                 AudioHardwareInterface*             mA2dpAudioInterface;
-                AudioStreamOut*                     mHardwareOutput;
-                AudioStreamOut*                     mA2dpOutput;
-                AudioStreamOut*                     mOutput;
-                AudioStreamOut*                     mRequestedOutput;
                 sp<AudioRecordThread>               mAudioRecordThread;
-                uint32_t                            mSampleRate;
-                size_t                              mFrameCount;
-                int                                 mChannelCount;
-                int                                 mFormat;
-                int16_t*                            mMixBuffer;
+                bool                                mA2dpEnabled;
+                bool                                mA2dpEnabledReq;
     mutable     int                                 mHardwareStatus;
-                nsecs_t                             mLastWriteTime;
-                int                                 mNumWrites;
-                int                                 mNumDelayedWrites;
-                bool                                mStandby;
-                bool                                mInWrite;
-                int                                 mA2dpDisableCount;
-                bool                                mA2dpSuppressed;
-                bool                                mMusicMuteSaved;
                 SortedVector< wp<IBinder> >         mNotificationClients;
+                int                                 mForcedSpeakerCount;
+                uint32_t                            mSavedRoute;
+                uint32_t                            mForcedRoute;
+                nsecs_t                             mRouteRestoreTime;
+                bool                                mMusicMuteSaved;
 };
 
 // ----------------------------------------------------------------------------