/* //device/include/server/AudioFlinger/AudioFlinger.cpp
**
** Copyright 2007, 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.
*/


#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0

#include <math.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>

#include <utils/IServiceManager.h>
#include <utils/Log.h>
#include <utils/Parcel.h>
#include <utils/IPCThreadState.h>
#include <utils/String16.h>
#include <utils/threads.h>

#include <cutils/properties.h>

#include <media/AudioTrack.h>
#include <media/AudioRecord.h>

#include <private/media/AudioTrackShared.h>

#include <hardware_legacy/AudioHardwareInterface.h>

#include "AudioMixer.h"
#include "AudioFlinger.h"

#ifdef WITH_A2DP
#include "A2dpAudioInterface.h"
#endif

// ----------------------------------------------------------------------------
// the sim build doesn't have gettid

#ifndef HAVE_GETTID
# define gettid getpid
#endif

// ----------------------------------------------------------------------------

namespace android {

static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
static const char* kHardwareLockedString = "Hardware lock is taken\n";

//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
static const unsigned long kBufferRecoveryInUsecs = 2000;
static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
static const float MAX_GAIN = 4096.0f;

// retry counts for buffer fill timeout
// 50 * ~20msecs = 1 second
static const int8_t kMaxTrackRetries = 50;
static const int8_t kMaxTrackStartupRetries = 50;

static const int kStartSleepTime = 30000;
static const int kStopSleepTime = 30000;

static const int kDumpLockRetries = 50;
static const int kDumpLockSleep = 20000;

// Maximum number of pending buffers allocated by OutputTrack::write()
static const uint8_t kMaxOutputTrackBuffers = 5;


#define AUDIOFLINGER_SECURITY_ENABLED 1

// ----------------------------------------------------------------------------

static bool recordingAllowed() {
#ifndef HAVE_ANDROID_OS
    return true;
#endif
#if AUDIOFLINGER_SECURITY_ENABLED
    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
    bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
    if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
    return ok;
#else
    if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
        LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
    return true;
#endif
}

static bool settingsAllowed() {
#ifndef HAVE_ANDROID_OS
    return true;
#endif
#if AUDIOFLINGER_SECURITY_ENABLED
    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
    return ok;
#else
    if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
        LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
    return true;
#endif
}

// ----------------------------------------------------------------------------

AudioFlinger::AudioFlinger()
    : BnAudioFlinger(),
        mAudioHardware(0), mA2dpAudioInterface(0), mA2dpEnabled(false), mNotifyA2dpChange(false),
        mForcedSpeakerCount(0), mA2dpDisableCount(0), mA2dpSuppressed(false), mForcedRoute(0),
        mRouteRestoreTime(0), mMusicMuteSaved(false)
{
    mHardwareStatus = AUDIO_HW_IDLE;
    mAudioHardware = AudioHardwareInterface::create();
    mHardwareStatus = AUDIO_HW_INIT;
    if (mAudioHardware->initCheck() == NO_ERROR) {
        // open 16-bit output stream for s/w mixer
        mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
        status_t status;
        AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
        mHardwareStatus = AUDIO_HW_IDLE;
        if (hwOutput) {
            mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
        } else {
            LOGE("Failed to initialize hardware output stream, status: %d", status);
        }
        
#ifdef WITH_A2DP
        // Create A2DP interface
        mA2dpAudioInterface = new A2dpAudioInterface();
        AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
        if (a2dpOutput) {
            mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
            if (hwOutput) {  
                uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
                MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
                                                            hwOutput->sampleRate(),
                                                            AudioSystem::PCM_16_BIT,
                                                            hwOutput->channelCount(),
                                                            frameCount);
                mHardwareMixerThread->setOuputTrack(a2dpOutTrack);                
            }
        } else {
            LOGE("Failed to initialize A2DP output stream, status: %d", status);
        }
#endif
 
        // FIXME - this should come from settings
        setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
        setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
        setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
        setMode(AudioSystem::MODE_NORMAL);

        setMasterVolume(1.0f);
        setMasterMute(false);

        // Start record thread
        mAudioRecordThread = new AudioRecordThread(mAudioHardware, this);
        if (mAudioRecordThread != 0) {
            mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);            
        }
     } else {
        LOGE("Couldn't even initialize the stubbed audio hardware!");
    }
}

AudioFlinger::~AudioFlinger()
{
    if (mAudioRecordThread != 0) {
        mAudioRecordThread->exit();
        mAudioRecordThread.clear();        
    }
    mHardwareMixerThread.clear();
    delete mAudioHardware;
    // deleting mA2dpAudioInterface also deletes mA2dpOutput;
#ifdef WITH_A2DP
    mA2dpMixerThread.clear();
    delete mA2dpAudioInterface;
#endif
}


#ifdef WITH_A2DP
// setA2dpEnabled_l() must be called with AudioFlinger::mLock held
void AudioFlinger::setA2dpEnabled_l(bool enable)
{    
    SortedVector < sp<MixerThread::Track> > tracks;
    SortedVector < wp<MixerThread::Track> > activeTracks;
    
    LOGV_IF(enable, "set output to A2DP\n");
    LOGV_IF(!enable, "set output to hardware audio\n");

    // Transfer tracks playing on MUSIC stream from one mixer to the other
    if (enable) {
        mHardwareMixerThread->getTracks_l(tracks, activeTracks);
        mA2dpMixerThread->putTracks_l(tracks, activeTracks);
    } else {
        mA2dpMixerThread->getTracks_l(tracks, activeTracks);
        mHardwareMixerThread->putTracks_l(tracks, activeTracks);
    }
    mA2dpEnabled = enable;
    mNotifyA2dpChange = true;
    mWaitWorkCV.broadcast();
}

// checkA2dpEnabledChange_l() must be called with AudioFlinger::mLock held
void AudioFlinger::checkA2dpEnabledChange_l()
{
    if (mNotifyA2dpChange) {
        // Notify AudioSystem of the A2DP activation/deactivation
        size_t size = mNotificationClients.size();
        for (size_t i = 0; i < size; i++) {
            sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
            if (binder != NULL) {
                LOGV("Notifying output change to client %p", binder.get());
                sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
                client->a2dpEnabledChanged(mA2dpEnabled);
            }
        }
        mNotifyA2dpChange = false;
    }
}
#endif // WITH_A2DP

bool AudioFlinger::streamForcedToSpeaker(int streamType)
{
    // NOTE that streams listed here must not be routed to A2DP by default:
    // AudioSystem::routedToA2dpOutput(streamType) == false
    return (streamType == AudioSystem::RING ||
            streamType == AudioSystem::ALARM ||
            streamType == AudioSystem::NOTIFICATION ||
            streamType == AudioSystem::ENFORCED_AUDIBLE);
}

status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    result.append("Clients:\n");
    for (size_t i = 0; i < mClients.size(); ++i) {
        wp<Client> wClient = mClients.valueAt(i);
        if (wClient != 0) {
            sp<Client> client = wClient.promote();
            if (client != 0) {
                snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
                result.append(buffer);
            }
        }
    }
    write(fd, result.string(), result.size());
    return NO_ERROR;
}


status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    int hardwareStatus = mHardwareStatus;
    
    if (hardwareStatus == AUDIO_HW_IDLE && mHardwareMixerThread->mStandby) {
        hardwareStatus = AUDIO_HW_STANDBY;
    }
    snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
    result.append(buffer);
    write(fd, result.string(), result.size());
    return NO_ERROR;
}

status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    snprintf(buffer, SIZE, "Permission Denial: "
            "can't dump AudioFlinger from pid=%d, uid=%d\n",
            IPCThreadState::self()->getCallingPid(),
            IPCThreadState::self()->getCallingUid());
    result.append(buffer);
    write(fd, result.string(), result.size());
    return NO_ERROR;
}

static bool tryLock(Mutex& mutex)
{
    bool locked = false;
    for (int i = 0; i < kDumpLockRetries; ++i) {
        if (mutex.tryLock() == NO_ERROR) {
            locked = true;
            break;
        }
        usleep(kDumpLockSleep);
    }
    return locked;
}

status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
{
    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
        dumpPermissionDenial(fd, args);
    } else {
        // get state of hardware lock
        bool hardwareLocked = tryLock(mHardwareLock);
        if (!hardwareLocked) {
            String8 result(kHardwareLockedString);
            write(fd, result.string(), result.size());
        } else {
            mHardwareLock.unlock();
        }

        bool locked = tryLock(mLock);

        // failed to lock - AudioFlinger is probably deadlocked
        if (!locked) {
            String8 result(kDeadlockedString);
            write(fd, result.string(), result.size());
        }

        dumpClients(fd, args);
        dumpInternals(fd, args);
        mHardwareMixerThread->dump(fd, args);
#ifdef WITH_A2DP
        mA2dpMixerThread->dump(fd, args);
#endif

        // dump record client
        if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);

        if (mAudioHardware) {
            mAudioHardware->dumpState(fd, args);
        }
        if (locked) mLock.unlock();
    }
    return NO_ERROR;
}

// IAudioFlinger interface


sp<IAudioTrack> AudioFlinger::createTrack(
        pid_t pid,
        int streamType,
        uint32_t sampleRate,
        int format,
        int channelCount,
        int frameCount,
        uint32_t flags,
        const sp<IMemory>& sharedBuffer,
        status_t *status)
{
    sp<MixerThread::Track> track;
    sp<TrackHandle> trackHandle;
    sp<Client> client;
    wp<Client> wclient;
    status_t lStatus;

    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
        LOGE("invalid stream type");
        lStatus = BAD_VALUE;
        goto Exit;
    }

    {
        Mutex::Autolock _l(mLock);

        wclient = mClients.valueFor(pid);

        if (wclient != NULL) {
            client = wclient.promote();
        } else {
            client = new Client(this, pid);
            mClients.add(pid, client);
        }
#ifdef WITH_A2DP
        if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
            track = mA2dpMixerThread->createTrack_l(client, streamType, sampleRate, format,
                    channelCount, frameCount, sharedBuffer, &lStatus);            
        } else 
#endif
        {
            track = mHardwareMixerThread->createTrack_l(client, streamType, sampleRate, format,
                    channelCount, frameCount, sharedBuffer, &lStatus);            
        }
    }
    if (lStatus == NO_ERROR) {
        trackHandle = new TrackHandle(track);
    } else {
        track.clear();
    }

Exit:
    if(status) {
        *status = lStatus;
    }
    return trackHandle;
}

uint32_t AudioFlinger::sampleRate(int output) const
{
#ifdef WITH_A2DP
     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
         return mA2dpMixerThread->sampleRate();
     }
#endif
     return mHardwareMixerThread->sampleRate();
}

int AudioFlinger::channelCount(int output) const
{
#ifdef WITH_A2DP
     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
         return mA2dpMixerThread->channelCount();
     }
#endif
     return mHardwareMixerThread->channelCount();
}

int AudioFlinger::format(int output) const
{
#ifdef WITH_A2DP
     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
         return mA2dpMixerThread->format();
     }
#endif
     return mHardwareMixerThread->format();
}

size_t AudioFlinger::frameCount(int output) const
{
#ifdef WITH_A2DP
     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
         return mA2dpMixerThread->frameCount();
     }
#endif
     return mHardwareMixerThread->frameCount();
}

uint32_t AudioFlinger::latency(int output) const
{
#ifdef WITH_A2DP
     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
         return mA2dpMixerThread->latency();
     }
#endif
     return mHardwareMixerThread->latency();
}

status_t AudioFlinger::setMasterVolume(float value)
{
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    // when hw supports master volume, don't scale in sw mixer
    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
        value = 1.0f;
    }
    mHardwareStatus = AUDIO_HW_IDLE;
    mHardwareMixerThread->setMasterVolume(value);
#ifdef WITH_A2DP
    mA2dpMixerThread->setMasterVolume(value);
#endif

    return NO_ERROR;
}

status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
{
    status_t err = NO_ERROR;

    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }
    if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
        LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
        return BAD_VALUE;
    }

#ifdef WITH_A2DP
    LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
    if (mode == AudioSystem::MODE_NORMAL && 
            (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
        AutoMutex lock(&mLock);

        bool enableA2dp = false;
        if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
            enableA2dp = true;
        }
        if (mA2dpDisableCount > 0) {
            mA2dpSuppressed = enableA2dp;
        } else {
            setA2dpEnabled_l(enableA2dp);
        }
        LOGV("setOutput done\n");
    }
    // setRouting() is always called at least for mode == AudioSystem::MODE_IN_CALL when 
    // SCO is enabled, whatever current mode is so we can safely handle A2DP disabling only
    // in this case to avoid doing it several times.
    if (mode == AudioSystem::MODE_IN_CALL &&
        (mask & AudioSystem::ROUTE_BLUETOOTH_SCO)) {
        AutoMutex lock(&mLock);
        handleRouteDisablesA2dp_l(routes);
    }
#endif

    // do nothing if only A2DP routing is affected
    mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
    if (mask) {
        AutoMutex lock(mHardwareLock);
        mHardwareStatus = AUDIO_HW_GET_ROUTING;
        uint32_t r;
        err = mAudioHardware->getRouting(mode, &r);
        if (err == NO_ERROR) {
            r = (r & ~mask) | (routes & mask);
            if (mode == AudioSystem::MODE_NORMAL || 
                (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
                mSavedRoute = r;
                r |= mForcedRoute;
                LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
            }
            mHardwareStatus = AUDIO_HW_SET_ROUTING;
            err = mAudioHardware->setRouting(mode, r);
        }
        mHardwareStatus = AUDIO_HW_IDLE;
    }
    return err;
}

uint32_t AudioFlinger::getRouting(int mode) const
{
    uint32_t routes = 0;
    if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
        if (mode == AudioSystem::MODE_NORMAL || 
            (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
            routes = mSavedRoute;                
        } else {
            mHardwareStatus = AUDIO_HW_GET_ROUTING;
            mAudioHardware->getRouting(mode, &routes);
            mHardwareStatus = AUDIO_HW_IDLE;
        }
    } else {
        LOGW("Illegal value: getRouting(%d)", mode);
    }
    return routes;
}

status_t AudioFlinger::setMode(int mode)
{
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }
    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
        LOGW("Illegal value: setMode(%d)", mode);
        return BAD_VALUE;
    }

    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_HW_SET_MODE;
    status_t ret = mAudioHardware->setMode(mode);
    mHardwareStatus = AUDIO_HW_IDLE;
    return ret;
}

int AudioFlinger::getMode() const
{
    int mode = AudioSystem::MODE_INVALID;
    mHardwareStatus = AUDIO_HW_SET_MODE;
    mAudioHardware->getMode(&mode);
    mHardwareStatus = AUDIO_HW_IDLE;
    return mode;
}

status_t AudioFlinger::setMicMute(bool state)
{
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
    status_t ret = mAudioHardware->setMicMute(state);
    mHardwareStatus = AUDIO_HW_IDLE;
    return ret;
}

bool AudioFlinger::getMicMute() const
{
    bool state = AudioSystem::MODE_INVALID;
    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
    mAudioHardware->getMicMute(&state);
    mHardwareStatus = AUDIO_HW_IDLE;
    return state;
}

status_t AudioFlinger::setMasterMute(bool muted)
{
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }
    mHardwareMixerThread->setMasterMute(muted);
#ifdef WITH_A2DP
    mA2dpMixerThread->setMasterMute(muted);
#endif
    return NO_ERROR;
}

float AudioFlinger::masterVolume() const
{
    return mHardwareMixerThread->masterVolume();
}

bool AudioFlinger::masterMute() const
{
    return mHardwareMixerThread->masterMute();
}

status_t AudioFlinger::setStreamVolume(int stream, float value)
{
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
        uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
        return BAD_VALUE;
    }

    status_t ret = NO_ERROR;
    
    if (stream == AudioSystem::VOICE_CALL ||
        stream == AudioSystem::BLUETOOTH_SCO) {
        float hwValue;
        if (stream == AudioSystem::VOICE_CALL) {
            hwValue = (float)AudioSystem::logToLinear(value)/100.0f;
            // offset value to reflect actual hardware volume that never reaches 0
            // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
            value = 0.01 + 0.99 * value;
        } else { // (type == AudioSystem::BLUETOOTH_SCO)
            hwValue = 1.0f;
        }

        AutoMutex lock(mHardwareLock);
        mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
        ret = mAudioHardware->setVoiceVolume(hwValue);
        mHardwareStatus = AUDIO_HW_IDLE;
        
    }
    
    mHardwareMixerThread->setStreamVolume(stream, value);
#ifdef WITH_A2DP
    mA2dpMixerThread->setStreamVolume(stream, value);
#endif

    mHardwareMixerThread->setStreamVolume(stream, value);
#ifdef WITH_A2DP
    mA2dpMixerThread->setStreamVolume(stream, value);
#endif

    return ret;
}

status_t AudioFlinger::setStreamMute(int stream, bool muted)
{
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
        uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
        return BAD_VALUE;
    }

#ifdef WITH_A2DP
    mA2dpMixerThread->setStreamMute(stream, muted);
#endif
    if (stream == AudioSystem::MUSIC) 
    {
        AutoMutex lock(&mHardwareLock);
        if (mForcedRoute != 0)
            mMusicMuteSaved = muted;
        else
            mHardwareMixerThread->setStreamMute(stream, muted);
    } else {
        mHardwareMixerThread->setStreamMute(stream, muted);
    }

    return NO_ERROR;
}

float AudioFlinger::streamVolume(int stream) const
{
    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
        return 0.0f;
    }
    
    float volume = mHardwareMixerThread->streamVolume(stream); 
    // remove correction applied by setStreamVolume()
    if (stream == AudioSystem::VOICE_CALL) {
        volume = (volume - 0.01) / 0.99 ;
    }
    
    return volume;
}

bool AudioFlinger::streamMute(int stream) const
{
    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
        return true;
    }
    
    if (stream == AudioSystem::MUSIC && mForcedRoute != 0) 
    {
        return mMusicMuteSaved;
    }
    return mHardwareMixerThread->streamMute(stream);
}

bool AudioFlinger::isMusicActive() const
{
 #ifdef WITH_A2DP
     if (isA2dpEnabled()) {
         return mA2dpMixerThread->isMusicActive();
     }
 #endif
    return mHardwareMixerThread->isMusicActive();
}

status_t AudioFlinger::setParameter(const char* key, const char* value)
{
    status_t result, result2;
    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_SET_PARAMETER;
    
    LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
    result = mAudioHardware->setParameter(key, value);
    if (mA2dpAudioInterface) {
        result2 = mA2dpAudioInterface->setParameter(key, value);
        if (result2)
            result = result2;
    }
    mHardwareStatus = AUDIO_HW_IDLE;
    return result;
}

size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
    return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
}

void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
{
    
    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
    Mutex::Autolock _l(mLock);

    sp<IBinder> binder = client->asBinder();
    if (mNotificationClients.indexOf(binder) < 0) {
        LOGV("Adding notification client %p", binder.get());
        binder->linkToDeath(this);
        mNotificationClients.add(binder);
        client->a2dpEnabledChanged(isA2dpEnabled());
    }
}

void AudioFlinger::binderDied(const wp<IBinder>& who) {
    
    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
    Mutex::Autolock _l(mLock);

    IBinder *binder = who.unsafe_get();

    if (binder != NULL) {
        int index = mNotificationClients.indexOf(binder);
        if (index >= 0) {
            LOGV("Removing notification client %p", binder);
            mNotificationClients.removeAt(index);
        }
    }
}

void AudioFlinger::removeClient(pid_t pid)
{
    LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
    Mutex::Autolock _l(mLock);
    mClients.removeItem(pid);
}

bool AudioFlinger::isA2dpEnabled() const
{
    return mA2dpEnabled;
}

void AudioFlinger::handleForcedSpeakerRoute(int command)
{
    switch(command) {
    case ACTIVE_TRACK_ADDED:
        {
            AutoMutex lock(mHardwareLock);
            if (mForcedSpeakerCount++ == 0) {
                mRouteRestoreTime = 0;
                mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
                if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
                    LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
                    mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
                    usleep(mHardwareMixerThread->latency()*1000);
                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
                    mHardwareStatus = AUDIO_HW_IDLE;
                    // delay track start so that audio hardware has time to siwtch routes
                    usleep(kStartSleepTime);
                }
                mForcedRoute = AudioSystem::ROUTE_SPEAKER;
            }
            LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
        }
        break;
    case ACTIVE_TRACK_REMOVED:
        {
            AutoMutex lock(mHardwareLock);
            if (mForcedSpeakerCount > 0){
                if (--mForcedSpeakerCount == 0) {
                    mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
                }
                LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
            } else {
                LOGE("mForcedSpeakerCount is already zero");
            }
        }
        break;
    case CHECK_ROUTE_RESTORE_TIME:
    case FORCE_ROUTE_RESTORE:
        if (mRouteRestoreTime) {
            AutoMutex lock(mHardwareLock);
            if (mRouteRestoreTime && 
               (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
                mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
                mForcedRoute = 0;
                if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
                    mHardwareStatus = AUDIO_HW_IDLE;
                    LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
                }
                mRouteRestoreTime = 0;
            }
        }
        break;
    }
}

#ifdef WITH_A2DP
// handleRouteDisablesA2dp_l() must be called with AudioFlinger::mLock held
void AudioFlinger::handleRouteDisablesA2dp_l(int routes)
{
   if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) {
        if (mA2dpDisableCount++ == 0) {
            if (mA2dpEnabled) {
                setA2dpEnabled_l(false);
                mA2dpSuppressed = true;
            }
        }
        LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
   } else {
        if (mA2dpDisableCount > 0) {
            if (--mA2dpDisableCount == 0) {
                if (mA2dpSuppressed) {
                    setA2dpEnabled_l(true);
                    mA2dpSuppressed = false;
                }
            }
            LOGV("mA2dpDisableCount decremented to %d", mA2dpDisableCount);
        } else {
            LOGE("mA2dpDisableCount is already zero");
        }
    }
}
#endif

// ----------------------------------------------------------------------------

AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
    :   Thread(false),
        mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType), 
        mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
        mInWrite(false)
{
    mSampleRate = output->sampleRate();
    mChannelCount = output->channelCount();

    // FIXME - Current mixer implementation only supports stereo output
    if (mChannelCount == 1) {
        LOGE("Invalid audio hardware channel count");
    }

    mFormat = output->format();
    mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
    mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());

    // FIXME - Current mixer implementation only supports stereo output: Always
    // Allocate a stereo buffer even if HW output is mono.
    mMixBuffer = new int16_t[mFrameCount * 2];
    memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
}

AudioFlinger::MixerThread::~MixerThread()
{
    delete [] mMixBuffer;
    delete mAudioMixer;
}

status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
{
    dumpInternals(fd, args);
    dumpTracks(fd, args);
    return NO_ERROR;
}

status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
    result.append(buffer);
    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
    for (size_t i = 0; i < mTracks.size(); ++i) {
        sp<Track> track = mTracks[i];
        if (track != 0) {
            track->dump(buffer, SIZE);
            result.append(buffer);
        }
    }

    snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
    result.append(buffer);
    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
        wp<Track> wTrack = mActiveTracks[i];
        if (wTrack != 0) {
            sp<Track> track = wTrack.promote();
            if (track != 0) {
                track->dump(buffer, SIZE);
                result.append(buffer);
            }
        }
    }
    write(fd, result.string(), result.size());
    return NO_ERROR;
}

status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
    result.append(buffer);
    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
    result.append(buffer);
    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
    result.append(buffer);
    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
    result.append(buffer);
    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
    result.append(buffer);
    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
    result.append(buffer);
    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
    result.append(buffer);
    write(fd, result.string(), result.size());
    return NO_ERROR;
}

// Thread virtuals
bool AudioFlinger::MixerThread::threadLoop()
{
    unsigned long sleepTime = kBufferRecoveryInUsecs;
    int16_t* curBuf = mMixBuffer;
    Vector< sp<Track> > tracksToRemove;
    size_t enabledTracks = 0;
    nsecs_t standbyTime = systemTime();   
    size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;

#ifdef WITH_A2DP
    bool outputTrackActive = false;
#endif

    do {
        enabledTracks = 0;
        { // scope for the AudioFlinger::mLock
        
            Mutex::Autolock _l(mAudioFlinger->mLock);

#ifdef WITH_A2DP
            if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
                if (outputTrackActive) {
                    mAudioFlinger->mLock.unlock();
                    mOutputTrack->stop();
                    mAudioFlinger->mLock.lock();
                    outputTrackActive = false;
                }
            }
            mAudioFlinger->checkA2dpEnabledChange_l();
#endif

            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;

            // put audio hardware into standby after short delay
            if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
                // wait until we have something to do...
                LOGV("Audio hardware entering standby, output %d\n", mOutputType);
                if (!mStandby) {
                    mOutput->standby();
                    mStandby = true;
                }
                
#ifdef WITH_A2DP
                if (outputTrackActive) {
                    mAudioFlinger->mLock.unlock();
                    mOutputTrack->stop();
                    mAudioFlinger->mLock.lock();
                    outputTrackActive = false;
                }
#endif
                if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
                    mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
                }                
                // we're about to wait, flush the binder command buffer
                IPCThreadState::self()->flushCommands();
                mAudioFlinger->mWaitWorkCV.wait(mAudioFlinger->mLock);
                LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
                
                if (mMasterMute == false) {
                    char value[PROPERTY_VALUE_MAX];
                    property_get("ro.audio.silent", value, "0");
                    if (atoi(value)) {
                        LOGD("Silence is golden");
                        setMasterMute(true);
                    }                    
                }
                
                standbyTime = systemTime() + kStandbyTimeInNsecs;
                continue;
            }

            // Forced route to speaker is handled by hardware mixer thread
            if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
                mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
            }

            // find out which tracks need to be processed
            size_t count = activeTracks.size();
            for (size_t i=0 ; i<count ; i++) {
                sp<Track> t = activeTracks[i].promote();
                if (t == 0) continue;

                Track* const track = t.get();
                audio_track_cblk_t* cblk = track->cblk();

                // The first time a track is added we wait
                // for all its buffers to be filled before processing it
                mAudioMixer->setActiveTrack(track->name());
                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
                        !track->isPaused())
                {
                    //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);

                    // compute volume for this track
                    int16_t left, right;
                    if (track->isMuted() || mMasterMute || track->isPausing()) {
                        left = right = 0;
                        if (track->isPausing()) {
                            LOGV("paused(%d)", track->name());
                            track->setPaused();
                        }
                    } else {
                        float typeVolume = mStreamTypes[track->type()].volume;
                        float v = mMasterVolume * typeVolume;
                        float v_clamped = v * cblk->volume[0];
                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
                        left = int16_t(v_clamped);
                        v_clamped = v * cblk->volume[1];
                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
                        right = int16_t(v_clamped);
                    }

                    // XXX: these things DON'T need to be done each time
                    mAudioMixer->setBufferProvider(track);
                    mAudioMixer->enable(AudioMixer::MIXING);

                    int param;
                    if ( track->mFillingUpStatus == Track::FS_FILLED) {
                        // no ramp for the first volume setting
                        track->mFillingUpStatus = Track::FS_ACTIVE;
                        if (track->mState == TrackBase::RESUMING) {
                            track->mState = TrackBase::ACTIVE;
                            param = AudioMixer::RAMP_VOLUME;
                        } else {
                            param = AudioMixer::VOLUME;
                        }
                    } else {
                        param = AudioMixer::RAMP_VOLUME;
                    }
                    mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
                    mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
                    mAudioMixer->setParameter(
                        AudioMixer::TRACK,
                        AudioMixer::FORMAT, track->format());
                    mAudioMixer->setParameter(
                        AudioMixer::TRACK,
                        AudioMixer::CHANNEL_COUNT, track->channelCount());
                    mAudioMixer->setParameter(
                        AudioMixer::RESAMPLE,
                        AudioMixer::SAMPLE_RATE,
                        int(cblk->sampleRate));

                    // reset retry count
                    track->mRetryCount = kMaxTrackRetries;
                    enabledTracks++;
                } else {
                    //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
                    if (track->isStopped()) {
                        track->reset();
                    }
                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
                        // We have consumed all the buffers of this track.
                        // Remove it from the list of active tracks.
                        LOGV("remove(%d) from active list", track->name());
                        tracksToRemove.add(track);
                    } else {
                        // No buffers for this track. Give it a few chances to
                        // fill a buffer, then remove it from active list.
                        if (--(track->mRetryCount) <= 0) {
                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
                            tracksToRemove.add(track);
                        }
                    }
                    // LOGV("disable(%d)", track->name());
                    mAudioMixer->disable(AudioMixer::MIXING);
                }
            }

            // remove all the tracks that need to be...
            count = tracksToRemove.size();
            if (UNLIKELY(count)) {
                for (size_t i=0 ; i<count ; i++) {
                    const sp<Track>& track = tracksToRemove[i];
                    removeActiveTrack_l(track);
                    if (track->isTerminated()) {
                        mTracks.remove(track);
                        deleteTrackName_l(track->mName);
                    }
                }
            }
       }
        
        if (LIKELY(enabledTracks)) {
            // mix buffers...
            mAudioMixer->process(curBuf);

#ifdef WITH_A2DP
            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
                if (!outputTrackActive) {
                    LOGV("starting output track in mixer for output %d", mOutputType);
                    mOutputTrack->start();
                    outputTrackActive = true;
                }
                mOutputTrack->write(curBuf, mFrameCount);
            }
#endif

            // output audio to hardware
            mLastWriteTime = systemTime();
            mInWrite = true;
            mOutput->write(curBuf, mixBufferSize);
            mNumWrites++;
            mInWrite = false;
            mStandby = false;
            nsecs_t temp = systemTime();
            standbyTime = temp + kStandbyTimeInNsecs;
            nsecs_t delta = temp - mLastWriteTime;
            if (delta > maxPeriod) {
                LOGW("write blocked for %llu msecs", ns2ms(delta));
                mNumDelayedWrites++;
            }
            sleepTime = kBufferRecoveryInUsecs;
        } else {         
#ifdef WITH_A2DP
            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
                if (outputTrackActive) {
                    mOutputTrack->write(curBuf, 0);
                    if (mOutputTrack->bufferQueueEmpty()) {
                        mOutputTrack->stop();
                        outputTrackActive = false;
                    } else {
                        standbyTime = systemTime() + kStandbyTimeInNsecs;
                    }
                }
            }
#endif
            // There was nothing to mix this round, which means all
            // active tracks were late. Sleep a little bit to give
            // them another chance. If we're too late, the audio
            // hardware will zero-fill for us.
            //LOGV("no buffers - usleep(%lu)", sleepTime);
            usleep(sleepTime);
            if (sleepTime < kMaxBufferRecoveryInUsecs) {
                sleepTime += kBufferRecoveryInUsecs;
            }
        }

        // finally let go of all our tracks, without the lock held
        // since we can't guarantee the destructors won't acquire that
        // same lock.
        tracksToRemove.clear();
    } while (true);

    return false;
}

status_t AudioFlinger::MixerThread::readyToRun()
{
    if (mSampleRate == 0) {
        LOGE("No working audio driver found.");
        return NO_INIT;
    }
    LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
    return NO_ERROR;
}

void AudioFlinger::MixerThread::onFirstRef()
{
    const size_t SIZE = 256;
    char buffer[SIZE];

    snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);

    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
}

// MixerThread::createTrack_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::MixerThread::Track>  AudioFlinger::MixerThread::createTrack_l(
        const sp<AudioFlinger::Client>& client,
        int streamType,
        uint32_t sampleRate,
        int format,
        int channelCount,
        int frameCount,
        const sp<IMemory>& sharedBuffer,
        status_t *status)
{
    sp<Track> track;
    status_t lStatus;
    
    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
    if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
        LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
        lStatus = BAD_VALUE;
        goto Exit;
    }


    if (mSampleRate == 0) {
        LOGE("Audio driver not initialized.");
        lStatus = NO_INIT;
        goto Exit;
    }

    track = new Track(this, client, streamType, sampleRate, format,
            channelCount, frameCount, sharedBuffer);
    if (track->getCblk() == NULL) {
        lStatus = NO_MEMORY;
        goto Exit;
    }
    mTracks.add(track);
    lStatus = NO_ERROR;

Exit:
    if(status) {
        *status = lStatus;
    }
    return track;
}

// getTracks_l() must be called with AudioFlinger::mLock held
void AudioFlinger::MixerThread::getTracks_l(
        SortedVector < sp<Track> >& tracks,
        SortedVector < wp<Track> >& activeTracks)
{
    size_t size = mTracks.size();
    LOGV ("MixerThread::getTracks_l() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType,  mTracks.size(), mActiveTracks.size());
    for (size_t i = 0; i < size; i++) {
        sp<Track> t = mTracks[i];
        if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
            tracks.add(t);
            int j = mActiveTracks.indexOf(t);
            if (j >= 0) {
                t = mActiveTracks[j].promote();
                if (t != NULL) {
                    activeTracks.add(t);                                    
                }                            
            }
        }
    }

    size = activeTracks.size();
    for (size_t i = 0; i < size; i++) {
        removeActiveTrack_l(activeTracks[i]);
    }
    
    size = tracks.size();
    for (size_t i = 0; i < size; i++) {
        sp<Track> t = tracks[i];
        mTracks.remove(t);
        deleteTrackName_l(t->name());
    }
}

// putTracks_l() must be called with AudioFlinger::mLock held
void AudioFlinger::MixerThread::putTracks_l(
        SortedVector < sp<Track> >& tracks,
        SortedVector < wp<Track> >& activeTracks)
{

    LOGV ("MixerThread::putTracks_l() for output %d, tracks.size %d, activeTracks.size %d", mOutputType,  tracks.size(), activeTracks.size());

    size_t size = tracks.size();
    for (size_t i = 0; i < size ; i++) {
        sp<Track> t = tracks[i];
        int name = getTrackName_l();

        if (name < 0) return;
        
        t->mName = name;
        t->mMixerThread = this;
        mTracks.add(t);

        int j = activeTracks.indexOf(t);
        if (j >= 0) {
            addActiveTrack_l(t);
        }            
    }
}

uint32_t AudioFlinger::MixerThread::sampleRate() const
{
    return mSampleRate;
}

int AudioFlinger::MixerThread::channelCount() const
{
    return mChannelCount;
}

int AudioFlinger::MixerThread::format() const
{
    return mFormat;
}

size_t AudioFlinger::MixerThread::frameCount() const
{
    return mFrameCount;
}

uint32_t AudioFlinger::MixerThread::latency() const
{
    if (mOutput) {
        return mOutput->latency();
    }
    else {
        return 0;
    }
}

status_t AudioFlinger::MixerThread::setMasterVolume(float value)
{
    mMasterVolume = value;
    return NO_ERROR;
}

status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
{
    mMasterMute = muted;
    return NO_ERROR;
}

float AudioFlinger::MixerThread::masterVolume() const
{
    return mMasterVolume;
}

bool AudioFlinger::MixerThread::masterMute() const
{
    return mMasterMute;
}

status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
{
    mStreamTypes[stream].volume = value;
    return NO_ERROR;
}

status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
{
    mStreamTypes[stream].mute = muted;
    return NO_ERROR;
}

float AudioFlinger::MixerThread::streamVolume(int stream) const
{
    return mStreamTypes[stream].volume;
}

bool AudioFlinger::MixerThread::streamMute(int stream) const
{
    return mStreamTypes[stream].mute;
}

bool AudioFlinger::MixerThread::isMusicActive() const
{
    size_t count = mActiveTracks.size();
    for (size_t i = 0 ; i < count ; ++i) {
        sp<Track> t = mActiveTracks[i].promote();
        if (t == 0) continue;
        Track* const track = t.get();
        if (t->mStreamType == AudioSystem::MUSIC)
            return true;
    }
    return false;
}

// addTrack_l() must be called with AudioFlinger::mLock held
status_t AudioFlinger::MixerThread::addTrack_l(const sp<Track>& track)
{
    status_t status = ALREADY_EXISTS;

    // here the track could be either new, or restarted
    // in both cases "unstop" the track
    if (track->isPaused()) {
        track->mState = TrackBase::RESUMING;
        LOGV("PAUSED => RESUMING (%d)", track->name());
    } else {
        track->mState = TrackBase::ACTIVE;
        LOGV("? => ACTIVE (%d)", track->name());
    }
    // set retry count for buffer fill
    track->mRetryCount = kMaxTrackStartupRetries;
    if (mActiveTracks.indexOf(track) < 0) {
        // the track is newly added, make sure it fills up all its
        // buffers before playing. This is to ensure the client will
        // effectively get the latency it requested.
        track->mFillingUpStatus = Track::FS_FILLING;
        track->mResetDone = false;
        addActiveTrack_l(track);
        status = NO_ERROR;
    }
    
    LOGV("mWaitWorkCV.broadcast");
    mAudioFlinger->mWaitWorkCV.broadcast();

    return status;
}

// destroyTrack_l() must be called with AudioFlinger::mLock held
void AudioFlinger::MixerThread::destroyTrack_l(const sp<Track>& track)
{
    track->mState = TrackBase::TERMINATED;
    if (mActiveTracks.indexOf(track) < 0) {
        LOGV("remove track (%d) and delete from mixer", track->name());
        mTracks.remove(track);
        deleteTrackName_l(track->name());
    }
}

// addActiveTrack_l() must be called with AudioFlinger::mLock held
void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
{
    mActiveTracks.add(t);

    // Force routing to speaker for certain stream types
    // The forced routing to speaker is managed by hardware mixer
    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
        sp<Track> track = t.promote();
        if (track == NULL) return;
   
        if (streamForcedToSpeaker(track->type())) {
            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
        }        
    }
}

// removeActiveTrack_l() must be called with AudioFlinger::mLock held
void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
{
    mActiveTracks.remove(t);

    // Force routing to speaker for certain stream types
    // The forced routing to speaker is managed by hardware mixer
    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
        sp<Track> track = t.promote();
        if (track == NULL) return;

        if (streamForcedToSpeaker(track->type())) {
            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
        }
    }
}

// getTrackName_l() must be called with AudioFlinger::mLock held
int AudioFlinger::MixerThread::getTrackName_l()
{
    return mAudioMixer->getTrackName();
}

// deleteTrackName_l() must be called with AudioFlinger::mLock held
void AudioFlinger::MixerThread::deleteTrackName_l(int name)
{
    mAudioMixer->deleteTrackName(name);
}

size_t AudioFlinger::MixerThread::getOutputFrameCount() 
{
    return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
}

// ----------------------------------------------------------------------------

// TrackBase constructor must be called with AudioFlinger::mLock held
AudioFlinger::MixerThread::TrackBase::TrackBase(
            const sp<MixerThread>& mixerThread,
            const sp<Client>& client,
            int streamType,
            uint32_t sampleRate,
            int format,
            int channelCount,
            int frameCount,
            uint32_t flags,
            const sp<IMemory>& sharedBuffer)
    :   RefBase(),
        mMixerThread(mixerThread),
        mClient(client),
        mStreamType(streamType),
        mFrameCount(0),
        mState(IDLE),
        mClientTid(-1),
        mFormat(format),
        mFlags(flags & ~SYSTEM_FLAGS_MASK)
{
    mName = mixerThread->getTrackName_l();
    LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
    if (mName < 0) {
        LOGE("no more track names availlable");
        return;
    }

    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());

    // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
   size_t size = sizeof(audio_track_cblk_t);
   size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
   if (sharedBuffer == 0) {
       size += bufferSize;
   }

   if (client != NULL) {
        mCblkMemory = client->heap()->allocate(size);
        if (mCblkMemory != 0) {
            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
            if (mCblk) { // construct the shared structure in-place.
                new(mCblk) audio_track_cblk_t();
                // clear all buffers
                mCblk->frameCount = frameCount;
                mCblk->sampleRate = (uint16_t)sampleRate;
                mCblk->channels = (uint16_t)channelCount;
                if (sharedBuffer == 0) {
                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
                    // Force underrun condition to avoid false underrun callback until first data is
                    // written to buffer
                    mCblk->flowControlFlag = 1;
                } else {
                    mBuffer = sharedBuffer->pointer();
                }
                mBufferEnd = (uint8_t *)mBuffer + bufferSize;
            }
        } else {
            LOGE("not enough memory for AudioTrack size=%u", size);
            client->heap()->dump("AudioTrack");
            return;
        }
   } else {
       mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
       if (mCblk) { // construct the shared structure in-place.
           new(mCblk) audio_track_cblk_t();
           // clear all buffers
           mCblk->frameCount = frameCount;
           mCblk->sampleRate = (uint16_t)sampleRate;
           mCblk->channels = (uint16_t)channelCount;
           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
           // Force underrun condition to avoid false underrun callback until first data is
           // written to buffer
           mCblk->flowControlFlag = 1;
           mBufferEnd = (uint8_t *)mBuffer + bufferSize;
       }
   }
}

AudioFlinger::MixerThread::TrackBase::~TrackBase()
{
    if (mCblk) {
        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.        
    }
    mCblkMemory.clear();            // and free the shared memory
    mClient.clear();
}

void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
    buffer->raw = 0;
    mFrameCount = buffer->frameCount;
    step();
    buffer->frameCount = 0;
}

bool AudioFlinger::MixerThread::TrackBase::step() {
    bool result;
    audio_track_cblk_t* cblk = this->cblk();

    result = cblk->stepServer(mFrameCount);
    if (!result) {
        LOGV("stepServer failed acquiring cblk mutex");
        mFlags |= STEPSERVER_FAILED;
    }
    return result;
}

void AudioFlinger::MixerThread::TrackBase::reset() {
    audio_track_cblk_t* cblk = this->cblk();

    cblk->user = 0;
    cblk->server = 0;
    cblk->userBase = 0;
    cblk->serverBase = 0;
    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
    LOGV("TrackBase::reset");
}

sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
{
    return mCblkMemory;
}

int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
    return (int)mCblk->sampleRate;
}

int AudioFlinger::MixerThread::TrackBase::channelCount() const {
    return mCblk->channels;
}

void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
    audio_track_cblk_t* cblk = this->cblk();
    int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
    int16_t *bufferEnd = bufferStart + frames * cblk->channels;

    // Check validity of returned pointer in case the track control block would have been corrupted.
    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd || 
        (cblk->channels == 2 && ((unsigned long)bufferStart & 3))) {
        LOGE("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
                server %d, serverBase %d, user %d, userBase %d, channels %d",
                bufferStart, bufferEnd, mBuffer, mBufferEnd,
                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channels);
        return 0;
    }

    return bufferStart;
}

// ----------------------------------------------------------------------------

// Track constructor must be called with AudioFlinger::mLock held
AudioFlinger::MixerThread::Track::Track(
            const sp<MixerThread>& mixerThread,
            const sp<Client>& client,
            int streamType,
            uint32_t sampleRate,
            int format,
            int channelCount,
            int frameCount,
            const sp<IMemory>& sharedBuffer)
    :   TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
{
    mVolume[0] = 1.0f;
    mVolume[1] = 1.0f;
    mMute = false;
    mSharedBuffer = sharedBuffer;
}

AudioFlinger::MixerThread::Track::~Track()
{
    wp<Track> weak(this); // never create a strong ref from the dtor
    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
    mState = TERMINATED;
}

void AudioFlinger::MixerThread::Track::destroy()
{
    // NOTE: destroyTrack_l() can remove a strong reference to this Track 
    // by removing it from mTracks vector, so there is a risk that this Tracks's
    // desctructor is called. As the destructor needs to lock AudioFlinger::mLock,
    // we must acquire a strong reference on this Track before locking AudioFlinger::mLock
    // here so that the destructor is called only when exiting this function.
    // On the other hand, as long as Track::destroy() is only called by 
    // TrackHandle destructor, the TrackHandle still holds a strong ref on 
    // this Track with its member mTrack.
    sp<Track> keep(this);
    { // scope for AudioFlinger::mLock
        Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
        mMixerThread->destroyTrack_l(this);
    }
}

void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
{
    snprintf(buffer, size, "  %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
            mName - AudioMixer::TRACK0,
            (mClient == NULL) ? getpid() : mClient->pid(),
            mStreamType,
            mFormat,
            mCblk->channels,
            mFrameCount,
            mState,
            mMute,
            mFillingUpStatus,
            mCblk->sampleRate,
            mCblk->volume[0],
            mCblk->volume[1],
            mCblk->server,
            mCblk->user);
}

status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
{
     audio_track_cblk_t* cblk = this->cblk();
     uint32_t framesReady;
     uint32_t framesReq = buffer->frameCount;

     // Check if last stepServer failed, try to step now
     if (mFlags & TrackBase::STEPSERVER_FAILED) {
         if (!step())  goto getNextBuffer_exit;
         LOGV("stepServer recovered");
         mFlags &= ~TrackBase::STEPSERVER_FAILED;
     }

     framesReady = cblk->framesReady();

     if (LIKELY(framesReady)) {
        uint32_t s = cblk->server;
        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;

        bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
        if (framesReq > framesReady) {
            framesReq = framesReady;
        }
        if (s + framesReq > bufferEnd) {
            framesReq = bufferEnd - s;
        }

         buffer->raw = getBuffer(s, framesReq);
         if (buffer->raw == 0) goto getNextBuffer_exit;

         buffer->frameCount = framesReq;
        return NO_ERROR;
     }

getNextBuffer_exit:
     buffer->raw = 0;
     buffer->frameCount = 0;
     return NOT_ENOUGH_DATA;
}

bool AudioFlinger::MixerThread::Track::isReady() const {
    if (mFillingUpStatus != FS_FILLING) return true;

    if (mCblk->framesReady() >= mCblk->frameCount ||
        mCblk->forceReady) {
        mFillingUpStatus = FS_FILLED;
        mCblk->forceReady = 0;
        LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
        return true;
    }
    return false;
}

status_t AudioFlinger::MixerThread::Track::start()
{
    LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
    mMixerThread->addTrack_l(this);
    return NO_ERROR;
}

void AudioFlinger::MixerThread::Track::stop()
{
    LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
    if (mState > STOPPED) {
        mState = STOPPED;
        // If the track is not active (PAUSED and buffers full), flush buffers
        if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
            reset();
        }
        LOGV("(> STOPPED) => STOPPED (%d)", mName);
    }
}

void AudioFlinger::MixerThread::Track::pause()
{
    LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
    if (mState == ACTIVE || mState == RESUMING) {
        mState = PAUSING;
        LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
    }
}

void AudioFlinger::MixerThread::Track::flush()
{
    LOGV("flush(%d)", mName);
    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
    if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
        return;
    }
    // No point remaining in PAUSED state after a flush => go to
    // STOPPED state
    mState = STOPPED;

    mCblk->lock.lock();
    // NOTE: reset() will reset cblk->user and cblk->server with
    // the risk that at the same time, the AudioMixer is trying to read
    // data. In this case, getNextBuffer() would return a NULL pointer
    // as audio buffer => the AudioMixer code MUST always test that pointer
    // returned by getNextBuffer() is not NULL!
    reset();
    mCblk->lock.unlock();
}

void AudioFlinger::MixerThread::Track::reset()
{
    // Do not reset twice to avoid discarding data written just after a flush and before
    // the audioflinger thread detects the track is stopped.
    if (!mResetDone) {
        TrackBase::reset();
        // Force underrun condition to avoid false underrun callback until first data is
        // written to buffer
        mCblk->flowControlFlag = 1;
        mCblk->forceReady = 0;
        mFillingUpStatus = FS_FILLING;        
        mResetDone = true;
    }
}

void AudioFlinger::MixerThread::Track::mute(bool muted)
{
    mMute = muted;
}

void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
{
    mVolume[0] = left;
    mVolume[1] = right;
}

// ----------------------------------------------------------------------------

// RecordTrack constructor must be called with AudioFlinger::mLock held
AudioFlinger::MixerThread::RecordTrack::RecordTrack(
            const sp<MixerThread>& mixerThread,
            const sp<Client>& client,
            int streamType,
            uint32_t sampleRate,
            int format,
            int channelCount,
            int frameCount,
            uint32_t flags)
    :   TrackBase(mixerThread, client, streamType, sampleRate, format,
                  channelCount, frameCount, flags, 0),
        mOverflow(false)
{
}

AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
{
    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
    mMixerThread->deleteTrackName_l(mName);
}

status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
{
    audio_track_cblk_t* cblk = this->cblk();
    uint32_t framesAvail;
    uint32_t framesReq = buffer->frameCount;

     // Check if last stepServer failed, try to step now
    if (mFlags & TrackBase::STEPSERVER_FAILED) {
        if (!step()) goto getNextBuffer_exit;
        LOGV("stepServer recovered");
        mFlags &= ~TrackBase::STEPSERVER_FAILED;
    }

    framesAvail = cblk->framesAvailable_l();

    if (LIKELY(framesAvail)) {
        uint32_t s = cblk->server;
        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;

        if (framesReq > framesAvail) {
            framesReq = framesAvail;
        }
        if (s + framesReq > bufferEnd) {
            framesReq = bufferEnd - s;
        }

        buffer->raw = getBuffer(s, framesReq);
        if (buffer->raw == 0) goto getNextBuffer_exit;

        buffer->frameCount = framesReq;
        return NO_ERROR;
    }

getNextBuffer_exit:
    buffer->raw = 0;
    buffer->frameCount = 0;
    return NOT_ENOUGH_DATA;
}

status_t AudioFlinger::MixerThread::RecordTrack::start()
{
    return mMixerThread->mAudioFlinger->startRecord(this);
}

void AudioFlinger::MixerThread::RecordTrack::stop()
{
    mMixerThread->mAudioFlinger->stopRecord(this);
    TrackBase::reset();
    // Force overerrun condition to avoid false overrun callback until first data is
    // read from buffer
    mCblk->flowControlFlag = 1;
}


// ----------------------------------------------------------------------------

AudioFlinger::MixerThread::OutputTrack::OutputTrack(
            const sp<MixerThread>& mixerThread,
            uint32_t sampleRate,
            int format,
            int channelCount,
            int frameCount)
    :   Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
    mOutputMixerThread(mixerThread)
{
                
    mCblk->out = 1;
    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
    mOutBuffer.frameCount = 0;
    mCblk->bufferTimeoutMs = 10;
    
    LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p", 
            mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
    
}

AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
{
    stop();
}

status_t AudioFlinger::MixerThread::OutputTrack::start()
{
    status_t status = Track::start();
    
    mRetryCount = 127;
    return status;
}

void AudioFlinger::MixerThread::OutputTrack::stop()
{
    Track::stop();
    clearBufferQueue();
    mOutBuffer.frameCount = 0;
}

void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
{
    Buffer *pInBuffer;
    Buffer inBuffer;
    uint32_t channels = mCblk->channels;
        
    inBuffer.frameCount = frames;
    inBuffer.i16 = data;
    
    if (mCblk->user == 0) {
        if (mOutputMixerThread->isMusicActive()) {
            mCblk->forceReady = 1;
            LOGV("OutputTrack::start() force ready");
        } else if (mCblk->frameCount > frames){
            if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
                uint32_t startFrames = (mCblk->frameCount - frames);
                LOGV("OutputTrack::start() write %d frames", startFrames);
                pInBuffer = new Buffer;
                pInBuffer->mBuffer = new int16_t[startFrames * channels];
                pInBuffer->frameCount = startFrames;
                pInBuffer->i16 = pInBuffer->mBuffer;
                memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
                mBufferQueue.add(pInBuffer);                
            } else {
                LOGW ("OutputTrack::write() no more buffers");
            }
        }        
    }

    while (1) { 
        // First write pending buffers, then new data
        if (mBufferQueue.size()) {
            pInBuffer = mBufferQueue.itemAt(0);
        } else {
            pInBuffer = &inBuffer;
        }
 
        if (pInBuffer->frameCount == 0) {
            break;
        }
        
        if (mOutBuffer.frameCount == 0) {
            mOutBuffer.frameCount = pInBuffer->frameCount;
            if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
                break;
            }
        }
            
        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
        mCblk->stepUser(outFrames);
        pInBuffer->frameCount -= outFrames;
        pInBuffer->i16 += outFrames * channels;
        mOutBuffer.frameCount -= outFrames;
        mOutBuffer.i16 += outFrames * channels;            
        
        if (pInBuffer->frameCount == 0) {
            if (mBufferQueue.size()) {
                mBufferQueue.removeAt(0);
                delete [] pInBuffer->mBuffer;
                delete pInBuffer;
            } else {
                break;
            }
        }
    }
 
    // If we could not write all frames, allocate a buffer and queue it for next time.
    if (inBuffer.frameCount) {
        if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
            pInBuffer = new Buffer;
            pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
            pInBuffer->frameCount = inBuffer.frameCount;
            pInBuffer->i16 = pInBuffer->mBuffer;
            memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
            mBufferQueue.add(pInBuffer);
        } else {
            LOGW("OutputTrack::write() no more buffers");
        }
    }
    
    // Calling write() with a 0 length buffer, means that no more data will be written:
    // If no more buffers are pending, fill output track buffer to make sure it is started 
    // by output mixer.
    if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
        frames = mCblk->frameCount - mCblk->user;
        pInBuffer = new Buffer;
        pInBuffer->mBuffer = new int16_t[frames * channels];
        pInBuffer->frameCount = frames;
        pInBuffer->i16 = pInBuffer->mBuffer;
        memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
        mBufferQueue.add(pInBuffer);
    }

}

status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
{
    int active;
    int timeout = 0;
    status_t result;
    audio_track_cblk_t* cblk = mCblk;
    uint32_t framesReq = buffer->frameCount;

    LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
    buffer->frameCount  = 0;
    
    uint32_t framesAvail = cblk->framesAvailable();

    if (framesAvail == 0) {
        return AudioTrack::NO_MORE_BUFFERS;
    }

    if (framesReq > framesAvail) {
        framesReq = framesAvail;
    }

    uint32_t u = cblk->user;
    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;

    if (u + framesReq > bufferEnd) {
        framesReq = bufferEnd - u;
    }

    buffer->frameCount  = framesReq;
    buffer->raw         = (void *)cblk->buffer(u);
    return NO_ERROR;
}


void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
{
    size_t size = mBufferQueue.size();
    Buffer *pBuffer;
    
    for (size_t i = 0; i < size; i++) {
        pBuffer = mBufferQueue.itemAt(i);
        delete [] pBuffer->mBuffer;
        delete pBuffer;
    }
    mBufferQueue.clear();
}

// ----------------------------------------------------------------------------

AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
    :   RefBase(),
        mAudioFlinger(audioFlinger),
        mMemoryDealer(new MemoryDealer(1024*1024)),
        mPid(pid)
{
    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
}

AudioFlinger::Client::~Client()
{
    mAudioFlinger->removeClient(mPid);
}

const sp<MemoryDealer>& AudioFlinger::Client::heap() const
{
    return mMemoryDealer;
}

// ----------------------------------------------------------------------------

AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
    : BnAudioTrack(),
      mTrack(track)
{
}

AudioFlinger::TrackHandle::~TrackHandle() {
    // just stop the track on deletion, associated resources
    // will be freed from the main thread once all pending buffers have
    // been played. Unless it's not in the active track list, in which
    // case we free everything now...
    mTrack->destroy();
}

status_t AudioFlinger::TrackHandle::start() {
    return mTrack->start();
}

void AudioFlinger::TrackHandle::stop() {
    mTrack->stop();
}

void AudioFlinger::TrackHandle::flush() {
    mTrack->flush();
}

void AudioFlinger::TrackHandle::mute(bool e) {
    mTrack->mute(e);
}

void AudioFlinger::TrackHandle::pause() {
    mTrack->pause();
}

void AudioFlinger::TrackHandle::setVolume(float left, float right) {
    mTrack->setVolume(left, right);
}

sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
    return mTrack->getCblk();
}

status_t AudioFlinger::TrackHandle::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    return BnAudioTrack::onTransact(code, data, reply, flags);
}

// ----------------------------------------------------------------------------

sp<IAudioRecord> AudioFlinger::openRecord(
        pid_t pid,
        int streamType,
        uint32_t sampleRate,
        int format,
        int channelCount,
        int frameCount,
        uint32_t flags,
        status_t *status)
{
    sp<MixerThread::RecordTrack> recordTrack;
    sp<RecordHandle> recordHandle;
    sp<Client> client;
    wp<Client> wclient;
    AudioStreamIn* input = 0;
    int inFrameCount;
    size_t inputBufferSize;
    status_t lStatus;

    // check calling permissions
    if (!recordingAllowed()) {
        lStatus = PERMISSION_DENIED;
        goto Exit;
    }

    if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
        LOGE("invalid stream type");
        lStatus = BAD_VALUE;
        goto Exit;
    }

    if (sampleRate > MAX_SAMPLE_RATE) {
        LOGE("Sample rate out of range");
        lStatus = BAD_VALUE;
        goto Exit;
    }

    if (mAudioRecordThread == 0) {
        LOGE("Audio record thread not started");
        lStatus = NO_INIT;
        goto Exit;
    }


    // Check that audio input stream accepts requested audio parameters 
    inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
    if (inputBufferSize == 0) {
        lStatus = BAD_VALUE;
        LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d",  sampleRate, format, channelCount);
        goto Exit;
    }

    // add client to list
    { // scope for mLock
        Mutex::Autolock _l(mLock);
        wclient = mClients.valueFor(pid);
        if (wclient != NULL) {
            client = wclient.promote();
        } else {
            client = new Client(this, pid);
            mClients.add(pid, client);
        }

        // frameCount must be a multiple of input buffer size
        inFrameCount = inputBufferSize/channelCount/sizeof(short);
        frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
    
        // create new record track. The record track uses one track in mHardwareMixerThread by convention.
        recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
                                                   format, channelCount, frameCount, flags);
    }
    if (recordTrack->getCblk() == NULL) {
        recordTrack.clear();
        lStatus = NO_MEMORY;
        goto Exit;
    }

    // return to handle to client
    recordHandle = new RecordHandle(recordTrack);
    lStatus = NO_ERROR;

Exit:
    if (status) {
        *status = lStatus;
    }
    return recordHandle;
}

status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
    if (mAudioRecordThread != 0) {
        return mAudioRecordThread->start(recordTrack);        
    }
    return NO_INIT;
}

void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
    if (mAudioRecordThread != 0) {
        mAudioRecordThread->stop(recordTrack);
    }
}

// ----------------------------------------------------------------------------

AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
    : BnAudioRecord(),
    mRecordTrack(recordTrack)
{
}

AudioFlinger::RecordHandle::~RecordHandle() {
    stop();
}

status_t AudioFlinger::RecordHandle::start() {
    LOGV("RecordHandle::start()");
    return mRecordTrack->start();
}

void AudioFlinger::RecordHandle::stop() {
    LOGV("RecordHandle::stop()");
    mRecordTrack->stop();
}

sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
    return mRecordTrack->getCblk();
}

status_t AudioFlinger::RecordHandle::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    return BnAudioRecord::onTransact(code, data, reply, flags);
}

// ----------------------------------------------------------------------------

AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware,
            const sp<AudioFlinger>& audioFlinger) :
    mAudioHardware(audioHardware),
    mAudioFlinger(audioFlinger),
    mActive(false)
{
}

AudioFlinger::AudioRecordThread::~AudioRecordThread()
{
}

bool AudioFlinger::AudioRecordThread::threadLoop()
{
    LOGV("AudioRecordThread: start record loop");
    AudioBufferProvider::Buffer buffer;
    int inBufferSize = 0;
    int inFrameCount = 0;
    AudioStreamIn* input = 0;

    mActive = 0;
    
    // start recording
    while (!exitPending()) {
        if (!mActive) {
            mLock.lock();
            if (!mActive && !exitPending()) {
                LOGV("AudioRecordThread: loop stopping");
                if (input) {
                    delete input;
                    input = 0;
                }
                mRecordTrack.clear();
                mStopped.signal();

                mWaitWorkCV.wait(mLock);
               
                LOGV("AudioRecordThread: loop starting");
                if (mRecordTrack != 0) {
                    input = mAudioHardware->openInputStream(mRecordTrack->format(), 
                                    mRecordTrack->channelCount(), 
                                    mRecordTrack->sampleRate(), 
                                    &mStartStatus,
                                    (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
                    if (input != 0) {
                        inBufferSize = input->bufferSize();
                        inFrameCount = inBufferSize/input->frameSize();                        
                    }
                } else {
                    mStartStatus = NO_INIT;
                }
                if (mStartStatus !=NO_ERROR) {
                    LOGW("record start failed, status %d", mStartStatus);
                    mActive = false;
                    mRecordTrack.clear();                    
                }
                mWaitWorkCV.signal();
            }
            mLock.unlock();
        } else if (mRecordTrack != 0) {

            buffer.frameCount = inFrameCount;
            if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR &&
                       (int)buffer.frameCount == inFrameCount)) {
                LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
                ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
                if (bytesRead < 0) {
                    LOGE("Error reading audio input");
                    sleep(1);
                }
                mRecordTrack->releaseBuffer(&buffer);
                mRecordTrack->overflow();
            }

            // client isn't retrieving buffers fast enough
            else {
                if (!mRecordTrack->setOverflow())
                    LOGW("AudioRecordThread: buffer overflow");
                // Release the processor for a while before asking for a new buffer.
                // This will give the application more chance to read from the buffer and
                // clear the overflow.
                usleep(5000);
            }
        }
    }


    if (input) {
        delete input;
    }
    mRecordTrack.clear();
    
    return false;
}

status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
{
    LOGV("AudioRecordThread::start");
    AutoMutex lock(&mLock);
    mActive = true;
    // If starting the active track, just reset mActive in case a stop
    // was pending and exit
    if (recordTrack == mRecordTrack.get()) return NO_ERROR;

    if (mRecordTrack != 0) return -EBUSY;

    mRecordTrack = recordTrack;

    // signal thread to start
    LOGV("Signal record thread");
    mWaitWorkCV.signal();
    mWaitWorkCV.wait(mLock);
    LOGV("Record started, status %d", mStartStatus);
    return mStartStatus;
}

void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
    LOGV("AudioRecordThread::stop");
    AutoMutex lock(&mLock);
    if (mActive && (recordTrack == mRecordTrack.get())) {
        mActive = false;
        mStopped.wait(mLock);
    }
}

void AudioFlinger::AudioRecordThread::exit()
{
    LOGV("AudioRecordThread::exit");
    {
        AutoMutex lock(&mLock);
        requestExit();
        mWaitWorkCV.signal();
    }
    requestExitAndWait();
}

status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    pid_t pid = 0;

    if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
        snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
        result.append(buffer);
    } else {
        result.append("No record client\n");
    }
    write(fd, result.string(), result.size());
    return NO_ERROR;
}

status_t AudioFlinger::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    return BnAudioFlinger::onTransact(code, data, reply, flags);
}

// ----------------------------------------------------------------------------
void AudioFlinger::instantiate() {
    defaultServiceManager()->addService(
            String16("media.audio_flinger"), new AudioFlinger());
}

}; // namespace android
