/*
**
** 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.
*/

#include <cutils/properties.h>
#include <string.h>
#include <unistd.h>

#define LOG_TAG "AudioHardwareInterface"
#include <utils/Log.h>
#include <utils/String8.h>

#include "AudioHardwareStub.h"
#include "AudioHardwareGeneric.h"

//#define DUMP_FLINGER_OUT        // if defined allows recording samples in a file
#ifdef DUMP_FLINGER_OUT
#include "AudioDumpInterface.h"
#endif


// change to 1 to log routing calls
#define LOG_ROUTING_CALLS 0

namespace android {

#if LOG_ROUTING_CALLS
static const char* routingModeStrings[] =
{
    "OUT OF RANGE",
    "INVALID",
    "CURRENT",
    "NORMAL",
    "RINGTONE",
    "IN_CALL"
};

static const char* routeStrings[] =
{
    "EARPIECE ",
    "SPEAKER ",
    "BLUETOOTH ",
    "HEADSET ",
    "BLUETOOTH_A2DP "
};
static const char* routeNone = "NONE";

static const char* displayMode(int mode)
{
    if ((mode < -2) || (mode > 2))
        return routingModeStrings[0];
    return routingModeStrings[mode+3];
}

static const char* displayRoutes(uint32_t routes)
{
    static char routeStr[80];
    if (routes == 0)
        return routeNone;
    routeStr[0] = 0;
    int bitMask = 1;
    for (int i = 0; i < 4; ++i, bitMask <<= 1) {
        if (routes & bitMask) {
            strcat(routeStr, routeStrings[i]);
        }
    }
    routeStr[strlen(routeStr)-1] = 0;
    return routeStr;
}
#endif

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

AudioHardwareInterface* AudioHardwareInterface::create()
{
    /*
     * FIXME: This code needs to instantiate the correct audio device
     * interface. For now - we use compile-time switches.
     */
    AudioHardwareInterface* hw = 0;
    char value[PROPERTY_VALUE_MAX];

#ifdef GENERIC_AUDIO
    hw = new AudioHardwareGeneric();
#else
    // if running in emulation - use the emulator driver
    if (property_get("ro.kernel.qemu", value, 0)) {
        LOGD("Running in emulation - using generic audio driver");
        hw = new AudioHardwareGeneric();
    }
    else {
        LOGV("Creating Vendor Specific AudioHardware");
        hw = createAudioHardware();
    }
#endif
    if (hw->initCheck() != NO_ERROR) {
        LOGW("Using stubbed audio hardware. No sound will be produced.");
        delete hw;
        hw = new AudioHardwareStub();
    }
    
#ifdef DUMP_FLINGER_OUT
    // This code adds a record of buffers in a file to write calls made by AudioFlinger.
    // It replaces the current AudioHardwareInterface object by an intermediate one which
    // will record buffers in a file (after sending them to hardware) for testing purpose.
    // This feature is enabled by defining symbol DUMP_FLINGER_OUT.
    // The output file is FLINGER_DUMP_NAME. Pause are not recorded in the file.
    
    hw = new AudioDumpInterface(hw);    // replace interface
#endif
    return hw;
}

AudioStreamOut::~AudioStreamOut()
{
}

AudioStreamIn::~AudioStreamIn() {}

AudioHardwareBase::AudioHardwareBase()
{
    // force a routing update on initialization
    memset(&mRoutes, 0, sizeof(mRoutes));
    mMode = 0;
}

// generics for audio routing - the real work is done in doRouting
status_t AudioHardwareBase::setRouting(int mode, uint32_t routes)
{
#if LOG_ROUTING_CALLS
    LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes));
#endif
    if (mode == AudioSystem::MODE_CURRENT)
        mode = mMode;
    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
        return BAD_VALUE;
    uint32_t old = mRoutes[mode];
    mRoutes[mode] = routes;
    if ((mode != mMode) || (old == routes))
        return NO_ERROR;
#if LOG_ROUTING_CALLS
    const char* oldRouteStr = strdup(displayRoutes(old));
    LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]",
           displayMode(mode), oldRouteStr, displayRoutes(routes));
    delete oldRouteStr;
#endif
    return doRouting();
}

status_t AudioHardwareBase::getRouting(int mode, uint32_t* routes)
{
    if (mode == AudioSystem::MODE_CURRENT)
        mode = mMode;
    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
        return BAD_VALUE;
    *routes = mRoutes[mode];
#if LOG_ROUTING_CALLS
    LOGD("getRouting: mode=%s, routes=[%s]",
           displayMode(mode), displayRoutes(*routes));
#endif
    return NO_ERROR;
}

status_t AudioHardwareBase::setMode(int mode)
{
#if LOG_ROUTING_CALLS
    LOGD("setMode(%s)", displayMode(mode));
#endif
    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
        return BAD_VALUE;
    if (mMode == mode)
        return NO_ERROR;
#if LOG_ROUTING_CALLS
    LOGD("doRouting: old mode=%s, new mode=%s route=[%s]",
            displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode]));
#endif
    mMode = mode;
    return doRouting();
}

status_t AudioHardwareBase::getMode(int* mode)
{
    // Implement: set audio routing
    *mode = mMode;
    return NO_ERROR;
}

status_t AudioHardwareBase::setParameter(const char* key, const char* value)
{
    // default implementation is to ignore
    return NO_ERROR;
}


// default implementation
size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
    if (sampleRate != 8000) {
        LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
        return 0;
    }
    if (format != AudioSystem::PCM_16_BIT) {
        LOGW("getInputBufferSize bad format: %d", format);
        return 0;
    }
    if (channelCount != 1) {
        LOGW("getInputBufferSize bad channel count: %d", channelCount);
        return 0;
    }

    return 320;
}

status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
    result.append(buffer);
    for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) {
        snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]);
        result.append(buffer);
    }
    ::write(fd, result.string(), result.size());
    dump(fd, args);  // Dump the state of the concrete child.
    return NO_ERROR;
}

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

}; // namespace android
