/*
** Copyright 2010, 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.
*/

#include <math.h>

//#define LOG_NDEBUG 0
#define LOG_TAG "AudioHardware"

#include <utils/Log.h>
#include <utils/String8.h>

#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <dlfcn.h>
#include <fcntl.h>

#include "AudioHardware.h"
#include <audio_effects/effect_aec.h>

extern "C" {
#include <tinyalsa/asoundlib.h>
}


namespace android_audio_legacy {

const uint32_t AudioHardware::inputConfigTable[][AudioHardware::INPUT_CONFIG_CNT] = {
        {8000, 4},
        {11025, 4},
        {16000, 2},
        {22050, 2},
        {32000, 1},
        {44100, 1}
};

//  trace driver operations for dump
//
#define DRIVER_TRACE

enum {
    DRV_NONE,
    DRV_PCM_OPEN,
    DRV_PCM_CLOSE,
    DRV_PCM_WRITE,
    DRV_PCM_READ,
    DRV_MIXER_OPEN,
    DRV_MIXER_CLOSE,
    DRV_MIXER_GET,
    DRV_MIXER_SEL
};

#ifdef DRIVER_TRACE
#define TRACE_DRIVER_IN(op) mDriverOp = op;
#define TRACE_DRIVER_OUT mDriverOp = DRV_NONE;
#else
#define TRACE_DRIVER_IN(op)
#define TRACE_DRIVER_OUT
#endif

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

const char *AudioHardware::inputPathNameDefault = "Default";
const char *AudioHardware::inputPathNameCamcorder = "Camcorder";
const char *AudioHardware::inputPathNameVoiceRecognition = "Voice Recognition";

AudioHardware::AudioHardware() :
    mInit(false),
    mMicMute(false),
    mPcm(NULL),
    mMixer(NULL),
    mPcmOpenCnt(0),
    mMixerOpenCnt(0),
    mInCallAudioMode(false),
    mVoiceVol(1.0f),
    mInputSource(AUDIO_SOURCE_DEFAULT),
    mBluetoothNrec(true),
    mTTYMode(TTY_MODE_OFF),
    mSecRilLibHandle(NULL),
    mRilClient(0),
    mActivatedCP(false),
    mEchoReference(NULL),
    mDriverOp(DRV_NONE)
{
    loadRILD();
    mInit = true;
}

AudioHardware::~AudioHardware()
{
    for (size_t index = 0; index < mInputs.size(); index++) {
        closeInputStream(mInputs[index].get());
    }
    mInputs.clear();
    closeOutputStream((AudioStreamOut*)mOutput.get());

    if (mMixer) {
        TRACE_DRIVER_IN(DRV_MIXER_CLOSE)
        mixer_close(mMixer);
        TRACE_DRIVER_OUT
    }
    if (mPcm) {
        TRACE_DRIVER_IN(DRV_PCM_CLOSE)
        pcm_close(mPcm);
        TRACE_DRIVER_OUT
    }

    if (mSecRilLibHandle) {
        if (disconnectRILD(mRilClient) != RIL_CLIENT_ERR_SUCCESS)
            ALOGE("Disconnect_RILD() error");

        if (closeClientRILD(mRilClient) != RIL_CLIENT_ERR_SUCCESS)
            ALOGE("CloseClient_RILD() error");

        mRilClient = 0;

        dlclose(mSecRilLibHandle);
        mSecRilLibHandle = NULL;
    }

    mInit = false;
}

status_t AudioHardware::initCheck()
{
    return mInit ? NO_ERROR : NO_INIT;
}

void AudioHardware::loadRILD(void)
{
    mSecRilLibHandle = dlopen("libsecril-client.so", RTLD_NOW);

    if (mSecRilLibHandle) {
        ALOGV("libsecril-client.so is loaded");

        openClientRILD   = (HRilClient (*)(void))
                              dlsym(mSecRilLibHandle, "OpenClient_RILD");
        disconnectRILD   = (int (*)(HRilClient))
                              dlsym(mSecRilLibHandle, "Disconnect_RILD");
        closeClientRILD  = (int (*)(HRilClient))
                              dlsym(mSecRilLibHandle, "CloseClient_RILD");
        isConnectedRILD  = (int (*)(HRilClient))
                              dlsym(mSecRilLibHandle, "isConnected_RILD");
        connectRILD      = (int (*)(HRilClient))
                              dlsym(mSecRilLibHandle, "Connect_RILD");
        setCallVolume    = (int (*)(HRilClient, SoundType, int))
                              dlsym(mSecRilLibHandle, "SetCallVolume");
        setCallAudioPath = (int (*)(HRilClient, AudioPath))
                              dlsym(mSecRilLibHandle, "SetCallAudioPath");
        setCallClockSync = (int (*)(HRilClient, SoundClockCondition))
                              dlsym(mSecRilLibHandle, "SetCallClockSync");

        if (!openClientRILD  || !disconnectRILD   || !closeClientRILD ||
            !isConnectedRILD || !connectRILD      ||
            !setCallVolume   || !setCallAudioPath || !setCallClockSync) {
            ALOGE("Can't load all functions from libsecril-client.so");

            dlclose(mSecRilLibHandle);
            mSecRilLibHandle = NULL;
        } else {
            mRilClient = openClientRILD();
            if (!mRilClient) {
                ALOGE("OpenClient_RILD() error");

                dlclose(mSecRilLibHandle);
                mSecRilLibHandle = NULL;
            }
        }
    } else {
        ALOGE("Can't load libsecril-client.so");
    }
}

status_t AudioHardware::connectRILDIfRequired(void)
{
    if (!mSecRilLibHandle) {
        ALOGE("connectIfRequired() lib is not loaded");
        return INVALID_OPERATION;
    }

    if (isConnectedRILD(mRilClient)) {
        return OK;
    }

    if (connectRILD(mRilClient) != RIL_CLIENT_ERR_SUCCESS) {
        ALOGE("Connect_RILD() error");
        return INVALID_OPERATION;
    }

    return OK;
}

AudioStreamOut* AudioHardware::openOutputStream(
    uint32_t devices, int *format, uint32_t *channels,
    uint32_t *sampleRate, status_t *status)
{
    sp <AudioStreamOutALSA> out;
    status_t rc;

    { // scope for the lock
        Mutex::Autolock lock(mLock);

        // only one output stream allowed
        if (mOutput != 0) {
            if (status) {
                *status = INVALID_OPERATION;
            }
            return NULL;
        }

        out = new AudioStreamOutALSA();

        rc = out->set(this, devices, format, channels, sampleRate);
        if (rc == NO_ERROR) {
            mOutput = out;
        }
    }

    if (rc != NO_ERROR) {
        if (out != 0) {
            out.clear();
        }
    }
    if (status) {
        *status = rc;
    }

    return out.get();
}

void AudioHardware::closeOutputStream(AudioStreamOut* out) {
    sp <AudioStreamOutALSA> spOut;
    sp<AudioStreamInALSA> spIn;
    {
        Mutex::Autolock lock(mLock);
        if (mOutput == 0 || mOutput.get() != out) {
            ALOGW("Attempt to close invalid output stream");
            return;
        }
        spOut = mOutput;
        mOutput.clear();
        if (mEchoReference != NULL) {
            spIn = getActiveInput_l();
        }
    }
    if (spIn != 0) {
        // this will safely release the echo reference by calling releaseEchoReference()
        // after placing the active input in standby
        spIn->standby();
    }

    spOut.clear();
}

AudioStreamIn* AudioHardware::openInputStream(
    uint32_t devices, int *format, uint32_t *channels,
    uint32_t *sampleRate, status_t *status,
    AudioSystem::audio_in_acoustics acoustic_flags)
{
    // check for valid input source
    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
        if (status) {
            *status = BAD_VALUE;
        }
        return NULL;
    }

    status_t rc = NO_ERROR;
    sp <AudioStreamInALSA> in;

    { // scope for the lock
        Mutex::Autolock lock(mLock);

        in = new AudioStreamInALSA();
        rc = in->set(this, devices, format, channels, sampleRate, acoustic_flags);
        if (rc == NO_ERROR) {
            mInputs.add(in);
        }
    }

    if (rc != NO_ERROR) {
        if (in != 0) {
            in.clear();
        }
    }
    if (status) {
        *status = rc;
    }

    ALOGV("AudioHardware::openInputStream()%p", in.get());
    return in.get();
}

void AudioHardware::closeInputStream(AudioStreamIn* in) {

    sp<AudioStreamInALSA> spIn;
    {
        Mutex::Autolock lock(mLock);

        ssize_t index = mInputs.indexOf((AudioStreamInALSA *)in);
        if (index < 0) {
            ALOGW("Attempt to close invalid input stream");
            return;
        }
        spIn = mInputs[index];
        mInputs.removeAt(index);
    }
    ALOGV("AudioHardware::closeInputStream()%p", in);
    spIn.clear();
}


status_t AudioHardware::setMode(int mode)
{
    sp<AudioStreamOutALSA> spOut;
    sp<AudioStreamInALSA> spIn;
    status_t status;

    // Mutex acquisition order is always out -> in -> hw
    AutoMutex lock(mLock);

    spOut = mOutput;
    while (spOut != 0) {
        if (!spOut->checkStandby()) {
            int cnt = spOut->prepareLock();
            mLock.unlock();
            spOut->lock();
            mLock.lock();
            // make sure that another thread did not change output state while the
            // mutex is released
            if ((spOut == mOutput) && (cnt == spOut->standbyCnt())) {
                break;
            }
            spOut->unlock();
            spOut = mOutput;
        } else {
            spOut.clear();
        }
    }
    // spOut is not 0 here only if the output is active

    spIn = getActiveInput_l();
    while (spIn != 0) {
        int cnt = spIn->prepareLock();
        mLock.unlock();
        spIn->lock();
        mLock.lock();
        // make sure that another thread did not change input state while the
        // mutex is released
        if ((spIn == getActiveInput_l()) && (cnt == spIn->standbyCnt())) {
            break;
        }
        spIn->unlock();
        spIn = getActiveInput_l();
    }
    // spIn is not 0 here only if the input is active

    int prevMode = mMode;
    status = AudioHardwareBase::setMode(mode);
    ALOGV("setMode() : new %d, old %d", mMode, prevMode);
    if (status == NO_ERROR) {
        bool modeNeedsCPActive = mMode == AudioSystem::MODE_IN_CALL ||
                                    mMode == AudioSystem::MODE_RINGTONE;
        // activate call clock in radio when entering in call or ringtone mode
        if (modeNeedsCPActive)
        {
            if ((!mActivatedCP) && (mSecRilLibHandle) && (connectRILDIfRequired() == OK)) {
                setCallClockSync(mRilClient, SOUND_CLOCK_START);
                mActivatedCP = true;
            }
        }

        if (mMode == AudioSystem::MODE_IN_CALL && !mInCallAudioMode) {
            if (spOut != 0) {
                ALOGV("setMode() in call force output standby");
                spOut->doStandby_l();
            }
            if (spIn != 0) {
                ALOGV("setMode() in call force input standby");
                spIn->doStandby_l();
            }

            ALOGV("setMode() openPcmOut_l()");
            openPcmOut_l();
            openMixer_l();
            setInputSource_l(AUDIO_SOURCE_DEFAULT);
            setVoiceVolume_l(mVoiceVol);
            mInCallAudioMode = true;
        }
        if (mMode != AudioSystem::MODE_IN_CALL && mInCallAudioMode) {
            setInputSource_l(mInputSource);
            if (mMixer != NULL) {
                TRACE_DRIVER_IN(DRV_MIXER_GET)
                struct mixer_ctl *ctl= mixer_get_ctl_by_name(mMixer, "Playback Path");
                TRACE_DRIVER_OUT
                if (ctl != NULL) {
                    ALOGV("setMode() reset Playback Path to RCV");
                    TRACE_DRIVER_IN(DRV_MIXER_SEL)
                    mixer_ctl_set_enum_by_string(ctl, "RCV");
                    TRACE_DRIVER_OUT
                }
            }
            ALOGV("setMode() closePcmOut_l()");
            closeMixer_l();
            closePcmOut_l();

            if (spOut != 0) {
                ALOGV("setMode() off call force output standby");
                spOut->doStandby_l();
            }
            if (spIn != 0) {
                ALOGV("setMode() off call force input standby");
                spIn->doStandby_l();
            }

            mInCallAudioMode = false;
        }

        if (!modeNeedsCPActive) {
            if(mActivatedCP)
                mActivatedCP = false;
        }
    }

    if (spIn != 0) {
        spIn->unlock();
    }
    if (spOut != 0) {
        spOut->unlock();
    }

    return status;
}

status_t AudioHardware::setMicMute(bool state)
{
    ALOGV("setMicMute(%d) mMicMute %d", state, mMicMute);
    sp<AudioStreamInALSA> spIn;
    {
        AutoMutex lock(mLock);
        if (mMicMute != state) {
            mMicMute = state;
            // in call mute is handled by RIL
            if (mMode != AudioSystem::MODE_IN_CALL) {
                spIn = getActiveInput_l();
            }
        }
    }

    if (spIn != 0) {
        spIn->standby();
    }

    return NO_ERROR;
}

status_t AudioHardware::getMicMute(bool* state)
{
    *state = mMicMute;
    return NO_ERROR;
}

status_t AudioHardware::setParameters(const String8& keyValuePairs)
{
    AudioParameter param = AudioParameter(keyValuePairs);
    String8 value;
    String8 key;
    const char BT_NREC_KEY[] = "bt_headset_nrec";
    const char BT_NREC_VALUE_ON[] = "on";
    const char TTY_MODE_KEY[] = "tty_mode";
    const char TTY_MODE_VALUE_OFF[] = "tty_off";
    const char TTY_MODE_VALUE_VCO[] = "tty_vco";
    const char TTY_MODE_VALUE_HCO[] = "tty_hco";
    const char TTY_MODE_VALUE_FULL[] = "tty_full";

    key = String8(BT_NREC_KEY);
    if (param.get(key, value) == NO_ERROR) {
        if (value == BT_NREC_VALUE_ON) {
            mBluetoothNrec = true;
        } else {
            mBluetoothNrec = false;
            ALOGD("Turning noise reduction and echo cancellation off for BT "
                 "headset");
        }
        param.remove(String8(BT_NREC_KEY));
    }

    key = String8(TTY_MODE_KEY);
    if (param.get(key, value) == NO_ERROR) {
        int ttyMode;
        if (value == TTY_MODE_VALUE_OFF) {
            ttyMode = TTY_MODE_OFF;
        } else if (value == TTY_MODE_VALUE_VCO) {
            ttyMode = TTY_MODE_VCO;
        } else if (value == TTY_MODE_VALUE_HCO) {
            ttyMode = TTY_MODE_HCO;
        } else if (value == TTY_MODE_VALUE_FULL) {
            ttyMode = TTY_MODE_FULL;
        } else {
            return BAD_VALUE;
        }

        if (ttyMode != mTTYMode) {
            ALOGV("new tty mode %d", ttyMode);
            mTTYMode = ttyMode;
            if (mOutput != 0 && mMode == AudioSystem::MODE_IN_CALL) {
                setIncallPath_l(mOutput->device());
            }
        }
        param.remove(String8(TTY_MODE_KEY));
     }

    return NO_ERROR;
}

String8 AudioHardware::getParameters(const String8& keys)
{
    AudioParameter request = AudioParameter(keys);
    AudioParameter reply = AudioParameter();

    ALOGV("getParameters() %s", keys.string());

    return reply.toString();
}

size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
    if (format != AudioSystem::PCM_16_BIT) {
        ALOGW("getInputBufferSize bad format: %d", format);
        return 0;
    }
    if (channelCount < 1 || channelCount > 2) {
        ALOGW("getInputBufferSize bad channel count: %d", channelCount);
        return 0;
    }

    if (sampleRate != getInputSampleRate(sampleRate)) {
        ALOGW("getInputBufferSize bad sample rate: %d", sampleRate);
        return 0;
    }

    return AudioStreamInALSA::getBufferSize(sampleRate, channelCount);
}

status_t AudioHardware::setVoiceVolume(float volume)
{
    AutoMutex lock(mLock);

    setVoiceVolume_l(volume);

    return NO_ERROR;
}

void AudioHardware::setVoiceVolume_l(float volume)
{
    ALOGD("### setVoiceVolume_l");

    mVoiceVol = volume;

    if ( (AudioSystem::MODE_IN_CALL == mMode) && (mSecRilLibHandle) &&
         (connectRILDIfRequired() == OK) ) {

        uint32_t device = AudioSystem::DEVICE_OUT_EARPIECE;
        if (mOutput != 0) {
            device = mOutput->device();
        }
        int int_volume = (int)(volume * 5);
        SoundType type;

        ALOGD("### route(%d) call volume(%f)", device, volume);
        switch (device) {
            case AudioSystem::DEVICE_OUT_EARPIECE:
                ALOGD("### earpiece call volume");
                type = SOUND_TYPE_VOICE;
                break;

            case AudioSystem::DEVICE_OUT_SPEAKER:
                ALOGD("### speaker call volume");
                type = SOUND_TYPE_SPEAKER;
                break;

            case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO:
            case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
            case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
                ALOGD("### bluetooth call volume");
                type = SOUND_TYPE_BTVOICE;
                break;

            case AudioSystem::DEVICE_OUT_WIRED_HEADSET:
            case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE: // Use receive path with 3 pole headset.
                ALOGD("### headset call volume");
                type = SOUND_TYPE_HEADSET;
                break;

            default:
                ALOGW("### Call volume setting error!!!0x%08x \n", device);
                type = SOUND_TYPE_VOICE;
                break;
        }
        setCallVolume(mRilClient, type, int_volume);
    }

}

status_t AudioHardware::setMasterVolume(float volume)
{
    ALOGV("Set master volume to %f.\n", volume);
    // We return an error code here to let the audioflinger do in-software
    // volume on top of the maximum volume that we set through the SND API.
    // return error - software mixer will handle it
    return -1;
}

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

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 AudioHardware::dump(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    bool locked = tryLock(mLock);
    if (!locked) {
        snprintf(buffer, SIZE, "\n\tAudioHardware maybe deadlocked\n");
    } else {
        mLock.unlock();
    }

    snprintf(buffer, SIZE, "\tInit %s\n", (mInit) ? "OK" : "Failed");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tMic Mute %s\n", (mMicMute) ? "ON" : "OFF");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmPcm: %p\n", mPcm);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmPcmOpenCnt: %d\n", mPcmOpenCnt);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmMixer: %p\n", mMixer);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmMixerOpenCnt: %d\n", mMixerOpenCnt);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tIn Call Audio Mode %s\n",
             (mInCallAudioMode) ? "ON" : "OFF");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tInput source %d\n", mInputSource);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmSecRilLibHandle: %p\n", mSecRilLibHandle);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmRilClient: %p\n", mRilClient);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tCP %s\n",
             (mActivatedCP) ? "Activated" : "Deactivated");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmDriverOp: %d\n", mDriverOp);
    result.append(buffer);

    snprintf(buffer, SIZE, "\n\tmOutput %p dump:\n", mOutput.get());
    result.append(buffer);
    write(fd, result.string(), result.size());
    if (mOutput != 0) {
        mOutput->dump(fd, args);
    }

    snprintf(buffer, SIZE, "\n\t%d inputs opened:\n", mInputs.size());
    write(fd, buffer, strlen(buffer));
    for (size_t i = 0; i < mInputs.size(); i++) {
        snprintf(buffer, SIZE, "\t- input %d dump:\n", i);
        write(fd, buffer, strlen(buffer));
        mInputs[i]->dump(fd, args);
    }

    return NO_ERROR;
}

status_t AudioHardware::setIncallPath_l(uint32_t device)
{
    ALOGV("setIncallPath_l: device %x", device);

    // Setup sound path for CP clocking
    if ((mSecRilLibHandle) &&
        (connectRILDIfRequired() == OK)) {

        if (mMode == AudioSystem::MODE_IN_CALL) {
            ALOGD("### incall mode route (%d)", device);
            AudioPath path;
            switch(device){
                case AudioSystem::DEVICE_OUT_EARPIECE:
                    ALOGD("### incall mode earpiece route");
                    path = SOUND_AUDIO_PATH_HANDSET;
                    break;

                case AudioSystem::DEVICE_OUT_SPEAKER:
                    ALOGD("### incall mode speaker route");
                    path = SOUND_AUDIO_PATH_SPEAKER;
                    break;

                case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO:
                case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
                case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
                    ALOGD("### incall mode bluetooth route %s NR", mBluetoothNrec ? "" : "NO");
                    if (mBluetoothNrec) {
                        path = SOUND_AUDIO_PATH_BLUETOOTH;
                    } else {
                        path = SOUND_AUDIO_PATH_BLUETOOTH_NO_NR;
                    }
                    break;

                case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE :
                    ALOGD("### incall mode headphone route");
                    path = SOUND_AUDIO_PATH_HEADPHONE;
                    break;
                case AudioSystem::DEVICE_OUT_WIRED_HEADSET :
                    ALOGD("### incall mode headset route");
                    path = SOUND_AUDIO_PATH_HEADSET;
                    break;
                default:
                    ALOGW("### incall mode Error!! route = [%d]", device);
                    path = SOUND_AUDIO_PATH_HANDSET;
                    break;
            }

            setCallAudioPath(mRilClient, path);

            if (mMixer != NULL) {
                TRACE_DRIVER_IN(DRV_MIXER_GET)
                struct mixer_ctl *ctl= mixer_get_ctl_by_name(mMixer, "Voice Call Path");
                TRACE_DRIVER_OUT
                ALOGE_IF(ctl == NULL, "setIncallPath_l() could not get mixer ctl");
                if (ctl != NULL) {
                    ALOGV("setIncallPath_l() Voice Call Path, (%x)", device);
                    TRACE_DRIVER_IN(DRV_MIXER_SEL)
                    mixer_ctl_set_enum_by_string(ctl, getVoiceRouteFromDevice(device));
                    TRACE_DRIVER_OUT
                }
            }
        }
    }
    return NO_ERROR;
}

struct pcm *AudioHardware::openPcmOut_l()
{
    ALOGD("openPcmOut_l() mPcmOpenCnt: %d", mPcmOpenCnt);
    if (mPcmOpenCnt++ == 0) {
        if (mPcm != NULL) {
            ALOGE("openPcmOut_l() mPcmOpenCnt == 0 and mPcm == %p\n", mPcm);
            mPcmOpenCnt--;
            return NULL;
        }
        unsigned flags = PCM_OUT;

        struct pcm_config config = {
            channels : 2,
            rate : AUDIO_HW_OUT_SAMPLERATE,
            period_size : AUDIO_HW_OUT_PERIOD_SZ,
            period_count : AUDIO_HW_OUT_PERIOD_CNT,
            format : PCM_FORMAT_S16_LE,
            start_threshold : 0,
            stop_threshold : 0,
            silence_threshold : 0,
            avail_min : 0,
        };

        TRACE_DRIVER_IN(DRV_PCM_OPEN)
        mPcm = pcm_open(0, 0, flags, &config);
        TRACE_DRIVER_OUT
        if (!pcm_is_ready(mPcm)) {
            ALOGE("openPcmOut_l() cannot open pcm_out driver: %s\n", pcm_get_error(mPcm));
            TRACE_DRIVER_IN(DRV_PCM_CLOSE)
            pcm_close(mPcm);
            TRACE_DRIVER_OUT
            mPcmOpenCnt--;
            mPcm = NULL;
        }
    }
    return mPcm;
}

void AudioHardware::closePcmOut_l()
{
    ALOGD("closePcmOut_l() mPcmOpenCnt: %d", mPcmOpenCnt);
    if (mPcmOpenCnt == 0) {
        ALOGE("closePcmOut_l() mPcmOpenCnt == 0");
        return;
    }

    if (--mPcmOpenCnt == 0) {
        TRACE_DRIVER_IN(DRV_PCM_CLOSE)
        pcm_close(mPcm);
        TRACE_DRIVER_OUT
        mPcm = NULL;
    }
}

struct mixer *AudioHardware::openMixer_l()
{
    ALOGV("openMixer_l() mMixerOpenCnt: %d", mMixerOpenCnt);
    if (mMixerOpenCnt++ == 0) {
        if (mMixer != NULL) {
            ALOGE("openMixer_l() mMixerOpenCnt == 0 and mMixer == %p\n", mMixer);
            mMixerOpenCnt--;
            return NULL;
        }
        TRACE_DRIVER_IN(DRV_MIXER_OPEN)
        mMixer = mixer_open(0);
        TRACE_DRIVER_OUT
        if (mMixer == NULL) {
            ALOGE("openMixer_l() cannot open mixer");
            mMixerOpenCnt--;
            return NULL;
        }
    }
    return mMixer;
}

void AudioHardware::closeMixer_l()
{
    ALOGV("closeMixer_l() mMixerOpenCnt: %d", mMixerOpenCnt);
    if (mMixerOpenCnt == 0) {
        ALOGE("closeMixer_l() mMixerOpenCnt == 0");
        return;
    }

    if (--mMixerOpenCnt == 0) {
        TRACE_DRIVER_IN(DRV_MIXER_CLOSE)
        mixer_close(mMixer);
        TRACE_DRIVER_OUT
        mMixer = NULL;
    }
}

const char *AudioHardware::getOutputRouteFromDevice(uint32_t device)
{
    switch (device) {
    case AudioSystem::DEVICE_OUT_EARPIECE:
        return "RCV";
    case AudioSystem::DEVICE_OUT_SPEAKER:
        if (mMode == AudioSystem::MODE_RINGTONE) return "RING_SPK";
        else return "SPK";
    case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE:
        if (mMode == AudioSystem::MODE_RINGTONE) return "RING_NO_MIC";
        else return "HP_NO_MIC";
    case AudioSystem::DEVICE_OUT_WIRED_HEADSET:
        if (mMode == AudioSystem::MODE_RINGTONE) return "RING_HP";
        else return "HP";
    case (AudioSystem::DEVICE_OUT_SPEAKER|AudioSystem::DEVICE_OUT_WIRED_HEADPHONE):
    case (AudioSystem::DEVICE_OUT_SPEAKER|AudioSystem::DEVICE_OUT_WIRED_HEADSET):
        if (mMode == AudioSystem::MODE_RINGTONE) return "RING_SPK_HP";
        else return "SPK_HP";
    case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO:
    case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
    case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
        return "BT";
    default:
        return "OFF";
    }
}

const char *AudioHardware::getVoiceRouteFromDevice(uint32_t device)
{
    switch (device) {
    case AudioSystem::DEVICE_OUT_EARPIECE:
        return "RCV";
    case AudioSystem::DEVICE_OUT_SPEAKER:
        return "SPK";
    case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE:
    case AudioSystem::DEVICE_OUT_WIRED_HEADSET:
        switch (mTTYMode) {
        case TTY_MODE_VCO:
            return "TTY_VCO";
        case TTY_MODE_HCO:
            return "TTY_HCO";
        case TTY_MODE_FULL:
            return "TTY_FULL";
        case TTY_MODE_OFF:
        default:
            if (device == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
                return "HP_NO_MIC";
            } else {
                return "HP";
            }
        }
    case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO:
    case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
    case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
        return "BT";
    default:
        return "OFF";
    }
}

const char *AudioHardware::getInputRouteFromDevice(uint32_t device)
{
    if (mMicMute) {
        return "MIC OFF";
    }

    switch (device) {
    case AudioSystem::DEVICE_IN_BUILTIN_MIC:
        return "Main Mic";
    case AudioSystem::DEVICE_IN_WIRED_HEADSET:
        return "Hands Free Mic";
    case AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET:
        return "BT Sco Mic";
    default:
        return "MIC OFF";
    }
}

uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate)
{
    size_t i;
    uint32_t prevDelta;
    uint32_t delta;
    size_t size = sizeof(inputConfigTable)/sizeof(uint32_t)/INPUT_CONFIG_CNT;

    for (i = 0, prevDelta = 0xFFFFFFFF; i < size; i++, prevDelta = delta) {
        delta = abs(sampleRate - inputConfigTable[i][INPUT_CONFIG_SAMPLE_RATE]);
        if (delta > prevDelta) break;
    }
    // i is always > 0 here
    return inputConfigTable[i-1][INPUT_CONFIG_SAMPLE_RATE];
}

// getActiveInput_l() must be called with mLock held
sp <AudioHardware::AudioStreamInALSA> AudioHardware::getActiveInput_l()
{
    sp< AudioHardware::AudioStreamInALSA> spIn;

    for (size_t i = 0; i < mInputs.size(); i++) {
        // return first input found not being in standby mode
        // as only one input can be in this state
        if (!mInputs[i]->checkStandby()) {
            spIn = mInputs[i];
            break;
        }
    }

    return spIn;
}

status_t AudioHardware::setInputSource_l(audio_source source)
{
     ALOGV("setInputSource_l(%d)", source);
     if (source != mInputSource) {
         if ((source == AUDIO_SOURCE_DEFAULT) || (mMode != AudioSystem::MODE_IN_CALL)) {
             if (mMixer) {
                 TRACE_DRIVER_IN(DRV_MIXER_GET)
                 struct mixer_ctl *ctl= mixer_get_ctl_by_name(mMixer, "Input Source");
                 TRACE_DRIVER_OUT
                 if (ctl == NULL) {
                     return NO_INIT;
                 }
                 const char* sourceName;
                 switch (source) {
                     case AUDIO_SOURCE_DEFAULT: // intended fall-through
                     case AUDIO_SOURCE_MIC:     // intended fall-through
                     case AUDIO_SOURCE_VOICE_COMMUNICATION:
                         sourceName = inputPathNameDefault;
                         break;
                     case AUDIO_SOURCE_CAMCORDER:
                         sourceName = inputPathNameCamcorder;
                         break;
                     case AUDIO_SOURCE_VOICE_RECOGNITION:
                         sourceName = inputPathNameVoiceRecognition;
                         break;
                     case AUDIO_SOURCE_VOICE_UPLINK:   // intended fall-through
                     case AUDIO_SOURCE_VOICE_DOWNLINK: // intended fall-through
                     case AUDIO_SOURCE_VOICE_CALL:     // intended fall-through
                     default:
                         return NO_INIT;
                 }
                 ALOGV("mixer_ctl_set_enum_by_string, Input Source, (%s)", sourceName);
                 TRACE_DRIVER_IN(DRV_MIXER_SEL)
                 mixer_ctl_set_enum_by_string(ctl, sourceName);
                 TRACE_DRIVER_OUT
             }
         }
         mInputSource = source;
     }

     return NO_ERROR;
}

struct echo_reference_itfe *AudioHardware::getEchoReference(audio_format_t format,
                                                              uint32_t channelCount,
                                                              uint32_t samplingRate)
{
    ALOGV("AudioHardware::getEchoReference %p", mEchoReference);
    releaseEchoReference(mEchoReference);
    if (mOutput != NULL) {
        uint32_t wrChannelCount = popcount(mOutput->channels());
        uint32_t wrSampleRate = mOutput->sampleRate();

        int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
                              channelCount,
                              samplingRate,
                              AUDIO_FORMAT_PCM_16_BIT,
                              wrChannelCount,
                              wrSampleRate,
                              &mEchoReference);
        if (status == 0) {
            mOutput->addEchoReference(mEchoReference);
        }
    }
    return mEchoReference;
}

void AudioHardware::releaseEchoReference(struct echo_reference_itfe *reference)
{
    ALOGV("AudioHardware::releaseEchoReference %p", mEchoReference);
    if (mEchoReference != NULL && reference == mEchoReference) {
        if (mOutput != NULL) {
            mOutput->removeEchoReference(reference);
        }
        release_echo_reference(mEchoReference);
        mEchoReference = NULL;
    }
}


//------------------------------------------------------------------------------
//  AudioStreamOutALSA
//------------------------------------------------------------------------------

AudioHardware::AudioStreamOutALSA::AudioStreamOutALSA() :
    mHardware(0), mPcm(0), mMixer(0), mRouteCtl(0),
    mStandby(true), mDevices(0), mChannels(AUDIO_HW_OUT_CHANNELS),
    mSampleRate(AUDIO_HW_OUT_SAMPLERATE), mBufferSize(AUDIO_HW_OUT_PERIOD_BYTES),
    mDriverOp(DRV_NONE), mStandbyCnt(0), mSleepReq(false), mEchoReference(NULL)
{
}

status_t AudioHardware::AudioStreamOutALSA::set(
    AudioHardware* hw, uint32_t devices, int *pFormat,
    uint32_t *pChannels, uint32_t *pRate)
{
    int lFormat = pFormat ? *pFormat : 0;
    uint32_t lChannels = pChannels ? *pChannels : 0;
    uint32_t lRate = pRate ? *pRate : 0;

    mHardware = hw;
    mDevices = devices;

    // fix up defaults
    if (lFormat == 0) lFormat = format();
    if (lChannels == 0) lChannels = channels();
    if (lRate == 0) lRate = sampleRate();

    // check values
    if ((lFormat != format()) ||
        (lChannels != channels()) ||
        (lRate != sampleRate())) {
        if (pFormat) *pFormat = format();
        if (pChannels) *pChannels = channels();
        if (pRate) *pRate = sampleRate();
        return BAD_VALUE;
    }

    if (pFormat) *pFormat = lFormat;
    if (pChannels) *pChannels = lChannels;
    if (pRate) *pRate = lRate;

    mChannels = lChannels;
    mSampleRate = lRate;
    mBufferSize = AUDIO_HW_OUT_PERIOD_BYTES;

    return NO_ERROR;
}

AudioHardware::AudioStreamOutALSA::~AudioStreamOutALSA()
{
    standby();
}

int AudioHardware::AudioStreamOutALSA::getPlaybackDelay(size_t frames,
                                                        struct echo_reference_buffer *buffer)
{
    size_t kernelFr;

    int rc = pcm_get_htimestamp(mPcm, &kernelFr, &buffer->time_stamp);
    if (rc < 0) {
        buffer->time_stamp.tv_sec  = 0;
        buffer->time_stamp.tv_nsec = 0;
        buffer->delay_ns           = 0;
        ALOGV("getPlaybackDelay(): pcm_get_htimestamp error, setting playbackTimestamp to 0");
        return rc;
    }

    kernelFr = pcm_get_buffer_size(mPcm) - kernelFr;

    // adjust render time stamp with delay added by current driver buffer.
    // Add the duration of current frame as we want the render time of the last
    // sample being written.
    long delayNs = (long)(((int64_t)(kernelFr + frames)* 1000000000) /AUDIO_HW_OUT_SAMPLERATE);

    ALOGV("AudioStreamOutALSA::getPlaybackDelay delayNs: [%ld], "\
         "kernelFr:[%d], frames:[%d], buffSize:[%d], time_stamp:[%ld].[%ld]",
         delayNs, (int)kernelFr, (int)frames, pcm_get_buffer_size(mPcm),
         (long)buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec);

    buffer->delay_ns = delayNs;

    return 0;
}

ssize_t AudioHardware::AudioStreamOutALSA::write(const void* buffer, size_t bytes)
{
    ALOGV("-----AudioStreamInALSA::write(%p, %d) START", buffer, (int)bytes);
    status_t status = NO_INIT;
    const uint8_t* p = static_cast<const uint8_t*>(buffer);
    int ret;

    if (mHardware == NULL) return NO_INIT;

    if (mSleepReq) {
        // 10ms are always shorter than the time to reconfigure the audio path
        // which is the only condition when mSleepReq would be true.
        usleep(10000);
    }

    { // scope for the lock

        AutoMutex lock(mLock);

        if (mStandby) {
            AutoMutex hwLock(mHardware->lock());

            ALOGD("AudioHardware pcm playback is exiting standby.");
            sp<AudioStreamInALSA> spIn = mHardware->getActiveInput_l();
            while (spIn != 0) {
                int cnt = spIn->prepareLock();
                mHardware->lock().unlock();
                // Mutex acquisition order is always out -> in -> hw
                spIn->lock();
                mHardware->lock().lock();
                // make sure that another thread did not change input state
                // while the mutex is released
                if ((spIn == mHardware->getActiveInput_l()) &&
                        (cnt == spIn->standbyCnt())) {
                    ALOGV("AudioStreamOutALSA::write() force input standby");
                    spIn->close_l();
                    break;
                }
                spIn->unlock();
                spIn = mHardware->getActiveInput_l();
            }
            // spIn is not 0 here only if the input was active and has been
            // closed above

            // open output before input
            open_l();

            if (spIn != 0) {
                if (spIn->open_l() != NO_ERROR) {
                    spIn->doStandby_l();
                }
                spIn->unlock();
            }
            if (mPcm == NULL) {
                goto Error;
            }
            mStandby = false;
        }

        if (mEchoReference != NULL) {
            struct echo_reference_buffer b;
            b.raw = (void *)buffer;
            b.frame_count = bytes / frameSize();

            getPlaybackDelay(bytes / frameSize(), &b);
            mEchoReference->write(mEchoReference, &b);
        }

        TRACE_DRIVER_IN(DRV_PCM_WRITE)
        ret = pcm_write(mPcm,(void*) p, bytes);
        TRACE_DRIVER_OUT

        if (ret == 0) {
            ALOGV("-----AudioStreamInALSA::write(%p, %d) END", buffer, (int)bytes);
            return bytes;
        }
        ALOGW("write error: %d", errno);
        status = -errno;
    }
Error:
    standby();

    // Simulate audio output timing in case of error
    usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate());
    ALOGE("AudioStreamOutALSA::write END WITH ERROR !!!!!!!!!(%p, %u)", buffer, bytes);
    return status;
}

status_t AudioHardware::AudioStreamOutALSA::standby()
{
    if (mHardware == NULL) return NO_INIT;

    mSleepReq = true;
    {
        AutoMutex lock(mLock);
        mSleepReq = false;

        { // scope for the AudioHardware lock
            AutoMutex hwLock(mHardware->lock());

            doStandby_l();
        }
    }

    return NO_ERROR;
}

void AudioHardware::AudioStreamOutALSA::doStandby_l()
{
    mStandbyCnt++;

    if (!mStandby) {
        ALOGD("AudioHardware pcm playback is going to standby.");
        // stop echo reference capture
        if (mEchoReference != NULL) {
            mEchoReference->write(mEchoReference, NULL);
        }
        mStandby = true;
    }

    close_l();
}

void AudioHardware::AudioStreamOutALSA::close_l()
{
    if (mMixer) {
        mHardware->closeMixer_l();
        mMixer = NULL;
        mRouteCtl = NULL;
    }
    if (mPcm) {
        mHardware->closePcmOut_l();
        mPcm = NULL;
    }
}

status_t AudioHardware::AudioStreamOutALSA::open_l()
{
    ALOGV("open pcm_out driver");
    mPcm = mHardware->openPcmOut_l();
    if (mPcm == NULL) {
        return NO_INIT;
    }

    mMixer = mHardware->openMixer_l();
    if (mMixer) {
        ALOGV("open playback normal");
        TRACE_DRIVER_IN(DRV_MIXER_GET)
        mRouteCtl = mixer_get_ctl_by_name(mMixer, "Playback Path");
        TRACE_DRIVER_OUT
    }
    if (mHardware->mode() != AudioSystem::MODE_IN_CALL) {
        const char *route = mHardware->getOutputRouteFromDevice(mDevices);
        ALOGV("write() wakeup setting route %s", route);
        if (mRouteCtl) {
            TRACE_DRIVER_IN(DRV_MIXER_SEL)
            mixer_ctl_set_enum_by_string(mRouteCtl, route);
            TRACE_DRIVER_OUT
        }
    }
    return NO_ERROR;
}

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

    bool locked = tryLock(mLock);
    if (!locked) {
        snprintf(buffer, SIZE, "\n\t\tAudioStreamOutALSA maybe deadlocked\n");
    } else {
        mLock.unlock();
    }

    snprintf(buffer, SIZE, "\t\tmHardware: %p\n", mHardware);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmPcm: %p\n", mPcm);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmMixer: %p\n", mMixer);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmRouteCtl: %p\n", mRouteCtl);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tStandby %s\n", (mStandby) ? "ON" : "OFF");
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmDevices: 0x%08x\n", mDevices);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmChannels: 0x%08x\n", mChannels);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmSampleRate: %d\n", mSampleRate);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmBufferSize: %d\n", mBufferSize);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmDriverOp: %d\n", mDriverOp);
    result.append(buffer);

    ::write(fd, result.string(), result.size());

    return NO_ERROR;
}

bool AudioHardware::AudioStreamOutALSA::checkStandby()
{
    return mStandby;
}

status_t AudioHardware::AudioStreamOutALSA::setParameters(const String8& keyValuePairs)
{
    AudioParameter param = AudioParameter(keyValuePairs);
    status_t status = NO_ERROR;
    int device;
    ALOGD("AudioStreamOutALSA::setParameters() %s", keyValuePairs.string());

    if (mHardware == NULL) return NO_INIT;

    mSleepReq = true;
    {
        AutoMutex lock(mLock);
        mSleepReq = false;
        if (param.getInt(String8(AudioParameter::keyRouting), device) == NO_ERROR)
        {
            if (device != 0) {
                AutoMutex hwLock(mHardware->lock());

                if (mDevices != (uint32_t)device) {
                    mDevices = (uint32_t)device;
                    if (mHardware->mode() != AudioSystem::MODE_IN_CALL) {
                        doStandby_l();
                    }
                }
                if (mHardware->mode() == AudioSystem::MODE_IN_CALL) {
                    mHardware->setIncallPath_l(device);
                }
            }
            param.remove(String8(AudioParameter::keyRouting));
        }
    }

    if (param.size()) {
        status = BAD_VALUE;
    }


    return status;

}

String8 AudioHardware::AudioStreamOutALSA::getParameters(const String8& keys)
{
    AudioParameter param = AudioParameter(keys);
    String8 value;
    String8 key = String8(AudioParameter::keyRouting);

    if (param.get(key, value) == NO_ERROR) {
        param.addInt(key, (int)mDevices);
    }

    ALOGV("AudioStreamOutALSA::getParameters() %s", param.toString().string());
    return param.toString();
}

status_t AudioHardware::AudioStreamOutALSA::getRenderPosition(uint32_t *dspFrames)
{
    //TODO
    return INVALID_OPERATION;
}

int AudioHardware::AudioStreamOutALSA::prepareLock()
{
    // request sleep next time write() is called so that caller can acquire
    // mLock
    mSleepReq = true;
    return mStandbyCnt;
}

void AudioHardware::AudioStreamOutALSA::lock()
{
    mLock.lock();
    mSleepReq = false;
}

void AudioHardware::AudioStreamOutALSA::unlock() {
    mLock.unlock();
}

void AudioHardware::AudioStreamOutALSA::addEchoReference(struct echo_reference_itfe *reference)
{
    ALOGV("AudioStreamOutALSA::addEchoReference %p", mEchoReference);
    if (mEchoReference == NULL) {
        mEchoReference = reference;
    }
}

void AudioHardware::AudioStreamOutALSA::removeEchoReference(struct echo_reference_itfe *reference)
{
    ALOGV("AudioStreamOutALSA::removeEchoReference %p", mEchoReference);
    if (mEchoReference == reference) {
        mEchoReference->write(mEchoReference, NULL);
        mEchoReference = NULL;
    }
}


//------------------------------------------------------------------------------
//  AudioStreamInALSA
//------------------------------------------------------------------------------

AudioHardware::AudioStreamInALSA::AudioStreamInALSA() :
    mHardware(0), mPcm(0), mMixer(0), mRouteCtl(0),
    mStandby(true), mDevices(0), mChannels(AUDIO_HW_IN_CHANNELS), mChannelCount(1),
    mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_PERIOD_BYTES),
    mDownSampler(NULL), mReadStatus(NO_ERROR), mInputBuf(NULL),
    mDriverOp(DRV_NONE), mStandbyCnt(0), mSleepReq(false),
    mProcBuf(NULL), mProcBufSize(0), mRefBuf(NULL), mRefBufSize(0),
    mEchoReference(NULL), mNeedEchoReference(false)
{
}

status_t AudioHardware::AudioStreamInALSA::set(
    AudioHardware* hw, uint32_t devices, int *pFormat,
    uint32_t *pChannels, uint32_t *pRate, AudioSystem::audio_in_acoustics acoustics)
{
    if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) {
        *pFormat = AUDIO_HW_IN_FORMAT;
        return BAD_VALUE;
    }
    if (pRate == 0) {
        return BAD_VALUE;
    }
    uint32_t rate = AudioHardware::getInputSampleRate(*pRate);
    if (rate != *pRate) {
        *pRate = rate;
        return BAD_VALUE;
    }

    if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO &&
        *pChannels != AudioSystem::CHANNEL_IN_STEREO)) {
        *pChannels = AUDIO_HW_IN_CHANNELS;
        return BAD_VALUE;
    }

    mHardware = hw;

    ALOGV("AudioStreamInALSA::set(%d, %d, %u)", *pFormat, *pChannels, *pRate);

    mBufferSize = getBufferSize(*pRate, AudioSystem::popCount(*pChannels));
    mDevices = devices;
    mChannels = *pChannels;
    mChannelCount = AudioSystem::popCount(mChannels);
    mSampleRate = rate;
    if (mSampleRate != AUDIO_HW_OUT_SAMPLERATE) {
        mBufferProvider.mProvider.get_next_buffer = getNextBufferStatic;
        mBufferProvider.mProvider.release_buffer = releaseBufferStatic;
        mBufferProvider.mInputStream = this;
        int status = create_resampler(AUDIO_HW_OUT_SAMPLERATE,
                                                    mSampleRate,
                                                    mChannelCount,
                                                    RESAMPLER_QUALITY_VOIP,
                                                    &mBufferProvider.mProvider,
                                                    &mDownSampler);
        if (status != 0) {
            ALOGW("AudioStreamInALSA::set() downsampler init failed: %d", status);
            mDownSampler = NULL;
            return status;
        }
    }
    mInputBuf = new int16_t[AUDIO_HW_IN_PERIOD_SZ * mChannelCount];

    return NO_ERROR;
}

AudioHardware::AudioStreamInALSA::~AudioStreamInALSA()
{
    standby();

    if (mDownSampler != NULL) {
        release_resampler(mDownSampler);
    }
    delete[] mInputBuf;
    delete[] mProcBuf;
}

// readFrames() reads frames from kernel driver, down samples to capture rate if necessary
// and output the number of frames requested to the buffer specified
ssize_t AudioHardware::AudioStreamInALSA::readFrames(void* buffer, ssize_t frames)
{
    ssize_t framesWr = 0;
    while (framesWr < frames) {
        size_t framesRd = frames - framesWr;
        if (mDownSampler != NULL) {
            mDownSampler->resample_from_provider(mDownSampler,
                    (int16_t *)((char *)buffer + framesWr * frameSize()),
                    &framesRd);
        } else {
            struct resampler_buffer buf = {
                    { raw : NULL, },
                    frame_count : framesRd,
            };
            getNextBuffer(&buf);
            if (buf.raw != NULL) {
                memcpy((char *)buffer + framesWr * frameSize(),
                        buf.raw,
                        buf.frame_count * frameSize());
                framesRd = buf.frame_count;
            }
            releaseBuffer(&buf);
        }
        // mReadStatus is updated by getNextBuffer() also called by
        // mDownSampler->resample_from_provider()
        if (mReadStatus != 0) {
            return mReadStatus;
        }
        framesWr += framesRd;
    }
    return framesWr;
}

// processFrames() reads frames from kernel driver (via readFrames()), calls the active
// audio pre processings and output the number of frames requested to the buffer specified
ssize_t AudioHardware::AudioStreamInALSA::processFrames(void* buffer, ssize_t frames)
{
    ssize_t framesWr = 0;
    while (framesWr < frames) {
        // first reload enough frames at the end of process input buffer
        if (mProcFramesIn < (size_t)frames) {
            // expand process input buffer if necessary
            if (mProcBufSize < (size_t)frames) {
                mProcBufSize = (size_t)frames;
                mProcBuf = (int16_t *)realloc(mProcBuf,
                                              mProcBufSize * mChannelCount * sizeof(int16_t));
                ALOGV("processFrames(): mProcBuf %p size extended to %d frames",
                     mProcBuf, mProcBufSize);
            }
            ssize_t framesRd = readFrames(mProcBuf + mProcFramesIn * mChannelCount,
                                          frames - mProcFramesIn);
            if (framesRd < 0) {
                framesWr = framesRd;
                break;
            }
            mProcFramesIn += framesRd;
        }

        if (mEchoReference != NULL) {
            pushEchoReference(mProcFramesIn);
        }

        //inBuf.frameCount and outBuf.frameCount indicate respectively the maximum number of frames
        //to be consumed and produced by process()
        audio_buffer_t inBuf = {
                mProcFramesIn,
                {mProcBuf}
        };
        audio_buffer_t outBuf = {
                frames - framesWr,
                {(int16_t *)buffer + framesWr * mChannelCount}
        };

        for (size_t i = 0; i < mPreprocessors.size(); i++) {
            (*mPreprocessors[i])->process(mPreprocessors[i],
                                                   &inBuf,
                                                   &outBuf);
        }

        // process() has updated the number of frames consumed and produced in
        // inBuf.frameCount and outBuf.frameCount respectively
        // move remaining frames to the beginning of mProcBuf
        mProcFramesIn -= inBuf.frameCount;
        if (mProcFramesIn) {
            memcpy(mProcBuf,
                   mProcBuf + inBuf.frameCount * mChannelCount,
                   mProcFramesIn * mChannelCount * sizeof(int16_t));
        }

        // if not enough frames were passed to process(), read more and retry.
        if (outBuf.frameCount == 0) {
            continue;
        }
        framesWr += outBuf.frameCount;
    }
    return framesWr;
}

int32_t AudioHardware::AudioStreamInALSA::updateEchoReference(size_t frames)
{
    struct echo_reference_buffer b;
    b.delay_ns = 0;

    ALOGV("updateEchoReference1 START, frames = [%d], mRefFramesIn = [%d],  b.frame_count = [%d]",
         frames, mRefFramesIn, frames - mRefFramesIn);
    if (mRefFramesIn < frames) {
        if (mRefBufSize < frames) {
            mRefBufSize = frames;
            mRefBuf = (int16_t *)realloc(mRefBuf,
                                         mRefBufSize * mChannelCount * sizeof(int16_t));
        }

        b.frame_count = frames - mRefFramesIn;
        b.raw = (void *)(mRefBuf + mRefFramesIn * mChannelCount);

        getCaptureDelay(frames, &b);

        if (mEchoReference->read(mEchoReference, &b) == NO_ERROR)
        {
            mRefFramesIn += b.frame_count;
            ALOGV("updateEchoReference2: mRefFramesIn:[%d], mRefBufSize:[%d], "\
                 "frames:[%d], b.frame_count:[%d]", mRefFramesIn, mRefBufSize,frames,b.frame_count);
        }

    }else{
        ALOGV("updateEchoReference3: NOT enough frames to read ref buffer");
    }
    return b.delay_ns;
}

void AudioHardware::AudioStreamInALSA::pushEchoReference(size_t frames)
{
    // read frames from echo reference buffer and update echo delay
    // mRefFramesIn is updated with frames available in mRefBuf
    int32_t delayUs = (int32_t)(updateEchoReference(frames)/1000);

    if (mRefFramesIn < frames) {
        frames = mRefFramesIn;
    }

    audio_buffer_t refBuf = {
            frames,
            {mRefBuf}
    };

    for (size_t i = 0; i < mPreprocessors.size(); i++) {
        if ((*mPreprocessors[i])->process_reverse == NULL) {
            continue;
        }
        (*mPreprocessors[i])->process_reverse(mPreprocessors[i],
                                               &refBuf,
                                               NULL);
        setPreProcessorEchoDelay(mPreprocessors[i], delayUs);
    }

    mRefFramesIn -= refBuf.frameCount;
    if (mRefFramesIn) {
    ALOGV("pushEchoReference5: shifting mRefBuf down by = %d frames", mRefFramesIn);
        memcpy(mRefBuf,
               mRefBuf + refBuf.frameCount * mChannelCount,
               mRefFramesIn * mChannelCount * sizeof(int16_t));
    }
}

status_t AudioHardware::AudioStreamInALSA::setPreProcessorEchoDelay(effect_handle_t handle,
                                                                    int32_t delayUs)
{
    uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
    effect_param_t *param = (effect_param_t *)buf;

    param->psize = sizeof(uint32_t);
    param->vsize = sizeof(uint32_t);
    *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY;
    *((int32_t *)param->data + 1) = delayUs;

    ALOGV("setPreProcessorEchoDelay: %d us", delayUs);

    return setPreprocessorParam(handle, param);
}

status_t AudioHardware::AudioStreamInALSA::setPreprocessorParam(effect_handle_t handle,
                                                                effect_param_t *param)
{
    uint32_t size = sizeof(int);
    uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;

    status_t status = (*handle)->command(handle,
                                           EFFECT_CMD_SET_PARAM,
                                           sizeof (effect_param_t) + psize,
                                           param,
                                           &size,
                                           &param->status);
    if (status == NO_ERROR) {
        status = param->status;
    }
    return status;
}

void AudioHardware::AudioStreamInALSA::getCaptureDelay(size_t frames,
                                                       struct echo_reference_buffer *buffer)
{

    // read frames available in kernel driver buffer
    size_t kernelFr;
    struct timespec tstamp;

    if (pcm_get_htimestamp(mPcm, &kernelFr, &tstamp) < 0) {
        buffer->time_stamp.tv_sec  = 0;
        buffer->time_stamp.tv_nsec = 0;
        buffer->delay_ns           = 0;
        ALOGW("read getCaptureDelay(): pcm_htimestamp error");
        return;
    }

    // read frames available in audio HAL input buffer
    // add number of frames being read as we want the capture time of first sample in current
    // buffer
    long bufDelay = (long)(((int64_t)(mInputFramesIn + mProcFramesIn) * 1000000000)
                                    / AUDIO_HW_IN_SAMPLERATE);
    // add delay introduced by resampler
    long rsmpDelay = 0;
    if (mDownSampler) {
        rsmpDelay = mDownSampler->delay_ns(mDownSampler);
    }

    long kernelDelay = (long)(((int64_t)kernelFr * 1000000000) / AUDIO_HW_IN_SAMPLERATE);

    // correct capture time stamp
    long delayNs = kernelDelay + bufDelay + rsmpDelay;

    buffer->time_stamp = tstamp;
    buffer->delay_ns   = delayNs;
    ALOGV("AudioStreamInALSA::getCaptureDelay TimeStamp = [%ld].[%ld], delayCaptureNs: [%d],"\
         " kernelDelay:[%ld], bufDelay:[%ld], rsmpDelay:[%ld], kernelFr:[%d], "\
         "mInputFramesIn:[%d], mProcFramesIn:[%d], frames:[%d]",
         buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns,
         kernelDelay, bufDelay, rsmpDelay, kernelFr, mInputFramesIn, mProcFramesIn, frames);

}

ssize_t AudioHardware::AudioStreamInALSA::read(void* buffer, ssize_t bytes)
{
    ALOGV("-----AudioStreamInALSA::read(%p, %d) START", buffer, (int)bytes);
    status_t status = NO_INIT;

    if (mHardware == NULL) return NO_INIT;

    if (mSleepReq) {
        // 10ms are always shorter than the time to reconfigure the audio path
        // which is the only condition when mSleepReq would be true.
        usleep(10000);
    }

    { // scope for the lock
        AutoMutex lock(mLock);

        if (mStandby) {
            AutoMutex hwLock(mHardware->lock());

            ALOGD("AudioHardware pcm capture is exiting standby.");
            sp<AudioStreamOutALSA> spOut = mHardware->output();
            while (spOut != 0) {
                spOut->prepareLock();
                mHardware->lock().unlock();
                mLock.unlock();
                // Mutex acquisition order is always out -> in -> hw
                spOut->lock();
                mLock.lock();
                mHardware->lock().lock();
                // make sure that another thread did not change output state
                // while the mutex is released
                if (spOut == mHardware->output()) {
                    break;
                }
                spOut->unlock();
                spOut = mHardware->output();
            }
            // open output before input
            if (spOut != 0) {
                if (!spOut->checkStandby()) {
                    ALOGV("AudioStreamInALSA::read() force output standby");
                    spOut->close_l();
                    if (spOut->open_l() != NO_ERROR) {
                        spOut->doStandby_l();
                    }
                }
                ALOGV("AudioStreamInALSA exit standby mNeedEchoReference %d mEchoReference %p",
                     mNeedEchoReference, mEchoReference);
                if (mNeedEchoReference && mEchoReference == NULL) {
                    mEchoReference = mHardware->getEchoReference(AUDIO_FORMAT_PCM_16_BIT,
                                                                 mChannelCount,
                                                                 mSampleRate);
                }
                spOut->unlock();
            }

            open_l();

            if (mPcm == NULL) {
                goto Error;
            }
            mStandby = false;
        }

        size_t framesRq = bytes / mChannelCount/sizeof(int16_t);
        ssize_t framesRd;

        if (mPreprocessors.size() == 0) {
            framesRd = readFrames(buffer, framesRq);
        } else {
            framesRd = processFrames(buffer, framesRq);
        }

        if (framesRd >= 0) {
            ALOGV("-----AudioStreamInALSA::read(%p, %d) END", buffer, (int)bytes);
            return framesRd * mChannelCount * sizeof(int16_t);
        }

        ALOGW("read error: %d", (int)framesRd);
        status = framesRd;
    }

Error:

    standby();

    // Simulate audio output timing in case of error
    usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate());
    ALOGE("-----AudioStreamInALSA::read(%p, %d) END ERROR", buffer, (int)bytes);
    return status;
}

status_t AudioHardware::AudioStreamInALSA::standby()
{
    if (mHardware == NULL) return NO_INIT;

    mSleepReq = true;
    {
        AutoMutex lock(mLock);
        mSleepReq = false;

        { // scope for AudioHardware lock
            AutoMutex hwLock(mHardware->lock());

            doStandby_l();
        }
    }
    return NO_ERROR;
}

void AudioHardware::AudioStreamInALSA::doStandby_l()
{
    mStandbyCnt++;

    if (!mStandby) {
        ALOGD("AudioHardware pcm capture is going to standby.");
        if (mEchoReference != NULL) {
            // stop reading from echo reference
            mEchoReference->read(mEchoReference, NULL);
            // Mutex acquisition order is always out -> in -> hw
            sp<AudioStreamOutALSA> spOut = mHardware->output();
            if (spOut != 0) {
                spOut->prepareLock();
                mHardware->lock().unlock();
                mLock.unlock();
                spOut->lock();
                mLock.lock();
                mHardware->lock().lock();
                mHardware->releaseEchoReference(mEchoReference);
                spOut->unlock();
            }
            mEchoReference = NULL;
        }

        mStandby = true;
    }
    close_l();
}

void AudioHardware::AudioStreamInALSA::close_l()
{
    if (mMixer) {
        mHardware->closeMixer_l();
        mMixer = NULL;
        mRouteCtl = NULL;
    }

    if (mPcm) {
        TRACE_DRIVER_IN(DRV_PCM_CLOSE)
        pcm_close(mPcm);
        TRACE_DRIVER_OUT
        mPcm = NULL;
    }

    delete[] mProcBuf;
    mProcBuf = NULL;
    mProcBufSize = 0;
    delete[] mRefBuf;
    mRefBuf = NULL;
    mRefBufSize = 0;
}

status_t AudioHardware::AudioStreamInALSA::open_l()
{
    unsigned flags = PCM_IN;

    struct pcm_config config = {
        channels : mChannelCount,
        rate : AUDIO_HW_IN_SAMPLERATE,
        period_size : AUDIO_HW_IN_PERIOD_SZ,
        period_count : AUDIO_HW_IN_PERIOD_CNT,
        format : PCM_FORMAT_S16_LE,
        start_threshold : 0,
        stop_threshold : 0,
        silence_threshold : 0,
        avail_min : 0,
    };

    ALOGV("open pcm_in driver");
    TRACE_DRIVER_IN(DRV_PCM_OPEN)
    mPcm = pcm_open(0, 0, flags, &config);
    TRACE_DRIVER_OUT
    if (!pcm_is_ready(mPcm)) {
        ALOGE("cannot open pcm_in driver: %s\n", pcm_get_error(mPcm));
        TRACE_DRIVER_IN(DRV_PCM_CLOSE)
        pcm_close(mPcm);
        TRACE_DRIVER_OUT
        mPcm = NULL;
        return NO_INIT;
    }

    if (mDownSampler != NULL) {
        mDownSampler->reset(mDownSampler);
    }
    mInputFramesIn = 0;

    mProcBufSize = 0;
    mProcFramesIn = 0;
    mRefBufSize = 0;
    mRefFramesIn = 0;

    mMixer = mHardware->openMixer_l();
    if (mMixer) {
        TRACE_DRIVER_IN(DRV_MIXER_GET)
        mRouteCtl = mixer_get_ctl_by_name(mMixer, "Capture MIC Path");
        TRACE_DRIVER_OUT
    }

    if (mHardware->mode() != AudioSystem::MODE_IN_CALL) {
        const char *route = mHardware->getInputRouteFromDevice(mDevices);
        ALOGV("read() wakeup setting route %s", route);
        if (mRouteCtl) {
            TRACE_DRIVER_IN(DRV_MIXER_SEL)
            mixer_ctl_set_enum_by_string(mRouteCtl, route);
            TRACE_DRIVER_OUT
        }
    }

    return NO_ERROR;
}

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

    bool locked = tryLock(mLock);
    if (!locked) {
        snprintf(buffer, SIZE, "\n\t\tAudioStreamInALSA maybe deadlocked\n");
    } else {
        mLock.unlock();
    }

    snprintf(buffer, SIZE, "\t\tmHardware: %p\n", mHardware);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmPcm: %p\n", mPcm);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmMixer: %p\n", mMixer);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tStandby %s\n", (mStandby) ? "ON" : "OFF");
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmDevices: 0x%08x\n", mDevices);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmChannels: 0x%08x\n", mChannels);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmSampleRate: %d\n", mSampleRate);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmBufferSize: %d\n", mBufferSize);
    result.append(buffer);
    snprintf(buffer, SIZE, "\t\tmDriverOp: %d\n", mDriverOp);
    result.append(buffer);
    write(fd, result.string(), result.size());

    return NO_ERROR;
}

bool AudioHardware::AudioStreamInALSA::checkStandby()
{
    return mStandby;
}

status_t AudioHardware::AudioStreamInALSA::setParameters(const String8& keyValuePairs)
{
    AudioParameter param = AudioParameter(keyValuePairs);
    status_t status = NO_ERROR;
    int value;

    ALOGD("AudioStreamInALSA::setParameters() %s", keyValuePairs.string());

    if (mHardware == NULL) return NO_INIT;

    mSleepReq = true;
    {
        AutoMutex lock(mLock);
        mSleepReq = false;

        if (param.getInt(String8(AudioParameter::keyInputSource), value) == NO_ERROR) {
            AutoMutex hwLock(mHardware->lock());

            mHardware->openMixer_l();
            mHardware->setInputSource_l((audio_source)value);
            mHardware->closeMixer_l();

            param.remove(String8(AudioParameter::keyInputSource));
        }

        if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR)
        {
            if (value != 0) {
                AutoMutex hwLock(mHardware->lock());

                if (mDevices != (uint32_t)value) {
                    mDevices = (uint32_t)value;
                    if (mHardware->mode() != AudioSystem::MODE_IN_CALL) {
                        doStandby_l();
                    }
                }
            }
            param.remove(String8(AudioParameter::keyRouting));
        }
    }


    if (param.size()) {
        status = BAD_VALUE;
    }

    return status;

}

String8 AudioHardware::AudioStreamInALSA::getParameters(const String8& keys)
{
    AudioParameter param = AudioParameter(keys);
    String8 value;
    String8 key = String8(AudioParameter::keyRouting);

    if (param.get(key, value) == NO_ERROR) {
        param.addInt(key, (int)mDevices);
    }

    ALOGV("AudioStreamInALSA::getParameters() %s", param.toString().string());
    return param.toString();
}

status_t AudioHardware::AudioStreamInALSA::addAudioEffect(effect_handle_t effect)
{
    ALOGV("AudioStreamInALSA::addAudioEffect() %p", effect);

    effect_descriptor_t desc;
    status_t status = (*effect)->get_descriptor(effect, &desc);
    if (status == 0) {
        if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
            ALOGV("AudioStreamInALSA::addAudioEffect() mNeedEchoReference true");
            mNeedEchoReference = true;
            standby();
        }
        ALOGV("AudioStreamInALSA::addAudioEffect() name %s", desc.name);
    } else {
        ALOGV("AudioStreamInALSA::addAudioEffect() get_descriptor() error");
    }

    AutoMutex lock(mLock);
    mPreprocessors.add(effect);
    return NO_ERROR;
}

status_t AudioHardware::AudioStreamInALSA::removeAudioEffect(effect_handle_t effect)
{
    status_t status = INVALID_OPERATION;
    ALOGV("AudioStreamInALSA::removeAudioEffect() %p", effect);
    {
        AutoMutex lock(mLock);
        for (size_t i = 0; i < mPreprocessors.size(); i++) {
            if (mPreprocessors[i] == effect) {
                mPreprocessors.removeAt(i);
                status = NO_ERROR;
                break;
            }
        }
    }

    if (status == NO_ERROR) {
        effect_descriptor_t desc;
        if ((*effect)->get_descriptor(effect, &desc) == 0) {
            if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
                ALOGV("AudioStreamInALSA::removeAudioEffect() mNeedEchoReference false");
                mNeedEchoReference = false;
                standby();
            }
        }
    }

    return status;
}

extern "C" {
int AudioHardware::AudioStreamInALSA::getNextBufferStatic(
                                                    struct resampler_buffer_provider *provider,
                                                    struct resampler_buffer* buffer)
{
    ResamplerBufferProvider *bufferProvider = (ResamplerBufferProvider *)provider;
    return bufferProvider->mInputStream->getNextBuffer(buffer);
}

void AudioHardware::AudioStreamInALSA::releaseBufferStatic(
                                                    struct resampler_buffer_provider *provider,
                                                    struct resampler_buffer* buffer)
{
    ResamplerBufferProvider *bufferProvider = (ResamplerBufferProvider *)provider;
    return bufferProvider->mInputStream->releaseBuffer(buffer);
}

}; // extern "C"

status_t AudioHardware::AudioStreamInALSA::getNextBuffer(struct resampler_buffer *buffer)
{
    if (mPcm == NULL) {
        buffer->raw = NULL;
        buffer->frame_count = 0;
        mReadStatus = NO_INIT;
        return NO_INIT;
    }

    if (mInputFramesIn == 0) {
        TRACE_DRIVER_IN(DRV_PCM_READ)
        mReadStatus = pcm_read(mPcm,(void*) mInputBuf, AUDIO_HW_IN_PERIOD_SZ * frameSize());
        TRACE_DRIVER_OUT
        if (mReadStatus != 0) {
            buffer->raw = NULL;
            buffer->frame_count = 0;
            return mReadStatus;
        }
        mInputFramesIn = AUDIO_HW_IN_PERIOD_SZ;
    }

    buffer->frame_count = (buffer->frame_count > mInputFramesIn) ? mInputFramesIn:buffer->frame_count;
    buffer->i16 = mInputBuf + (AUDIO_HW_IN_PERIOD_SZ - mInputFramesIn) * mChannelCount;

    return mReadStatus;
}

void AudioHardware::AudioStreamInALSA::releaseBuffer(struct resampler_buffer *buffer)
{
    mInputFramesIn -= buffer->frame_count;
}

size_t AudioHardware::AudioStreamInALSA::getBufferSize(uint32_t sampleRate, int channelCount)
{
    size_t i;
    size_t size = sizeof(inputConfigTable)/sizeof(uint32_t)/INPUT_CONFIG_CNT;

    for (i = 0; i < size; i++) {
        if (sampleRate == inputConfigTable[i][INPUT_CONFIG_SAMPLE_RATE]) {
            return (AUDIO_HW_IN_PERIOD_SZ*channelCount*sizeof(int16_t)) /
                    inputConfigTable[i][INPUT_CONFIG_BUFFER_RATIO];
        }
    }
    // this should never happen as getBufferSize() is always called after getInputSampleRate()
    // that checks for valid sampling rates.
    ALOGE("AudioStreamInALSA::getBufferSize() invalid sampling rate %d", sampleRate);
    return 0;
}

int AudioHardware::AudioStreamInALSA::prepareLock()
{
    // request sleep next time read() is called so that caller can acquire
    // mLock
    mSleepReq = true;
    return mStandbyCnt;
}

void AudioHardware::AudioStreamInALSA::lock()
{
    mLock.lock();
    mSleepReq = false;
}

void AudioHardware::AudioStreamInALSA::unlock() {
    mLock.unlock();
}

//------------------------------------------------------------------------------
//  Factory
//------------------------------------------------------------------------------

extern "C" AudioHardwareInterface* createAudioHardware(void) {
    return new AudioHardware();
}

}; // namespace android
