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


//#define LOG_NDEBUG 0
#define LOG_TAG "AudioEffect"

#include <stdint.h>
#include <sys/types.h>
#include <limits.h>

#include <private/media/AudioEffectShared.h>
#include <media/AudioEffect.h>

#include <utils/Log.h>
#include <binder/IPCThreadState.h>



namespace android {

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

AudioEffect::AudioEffect()
    : mStatus(NO_INIT)
{
}


AudioEffect::AudioEffect(const effect_uuid_t *type,
                const effect_uuid_t *uuid,
                int32_t priority,
                effect_callback_t cbf,
                void* user,
                int sessionId,
                audio_io_handle_t io
                )
    : mStatus(NO_INIT)
{
    mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
}

AudioEffect::AudioEffect(const char *typeStr,
                const char *uuidStr,
                int32_t priority,
                effect_callback_t cbf,
                void* user,
                int sessionId,
                audio_io_handle_t io
                )
    : mStatus(NO_INIT)
{
    effect_uuid_t type;
    effect_uuid_t *pType = NULL;
    effect_uuid_t uuid;
    effect_uuid_t *pUuid = NULL;

    ALOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr);

    if (typeStr != NULL) {
        if (stringToGuid(typeStr, &type) == NO_ERROR) {
            pType = &type;
        }
    }

    if (uuidStr != NULL) {
        if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
            pUuid = &uuid;
        }
    }

    mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io);
}

status_t AudioEffect::set(const effect_uuid_t *type,
                const effect_uuid_t *uuid,
                int32_t priority,
                effect_callback_t cbf,
                void* user,
                int sessionId,
                audio_io_handle_t io)
{
    sp<IEffect> iEffect;
    sp<IMemory> cblk;
    int enabled;

    ALOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0);

    if (mIEffect != 0) {
        ALOGW("Effect already in use");
        return INVALID_OPERATION;
    }

    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
    if (audioFlinger == 0) {
        ALOGE("set(): Could not get audioflinger");
        return NO_INIT;
    }

    if (type == NULL && uuid == NULL) {
        ALOGW("Must specify at least type or uuid");
        return BAD_VALUE;
    }

    mPriority = priority;
    mCbf = cbf;
    mUserData = user;
    mSessionId = sessionId;

    memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
    mDescriptor.type = *(type != NULL ? type : EFFECT_UUID_NULL);
    mDescriptor.uuid = *(uuid != NULL ? uuid : EFFECT_UUID_NULL);

    mIEffectClient = new EffectClient(this);

    iEffect = audioFlinger->createEffect(getpid(), &mDescriptor,
            mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled);

    if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
        ALOGE("set(): AudioFlinger could not create effect, status: %d", mStatus);
        return mStatus;
    }

    mEnabled = (volatile int32_t)enabled;

    mIEffect = iEffect;
    cblk = iEffect->getCblk();
    if (cblk == 0) {
        mStatus = NO_INIT;
        ALOGE("Could not get control block");
        return mStatus;
    }

    mIEffect = iEffect;
    mCblkMemory = cblk;
    mCblk = static_cast<effect_param_cblk_t*>(cblk->pointer());
    int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
    mCblk->buffer = (uint8_t *)mCblk + bufOffset;

    iEffect->asBinder()->linkToDeath(mIEffectClient);
    ALOGV("set() %p OK effect: %s id: %d status %d enabled %d", this, mDescriptor.name, mId, mStatus, mEnabled);

    return mStatus;
}


AudioEffect::~AudioEffect()
{
    ALOGV("Destructor %p", this);

    if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) {
        if (mIEffect != NULL) {
            mIEffect->disconnect();
            mIEffect->asBinder()->unlinkToDeath(mIEffectClient);
        }
        IPCThreadState::self()->flushCommands();
    }
    mIEffect.clear();
    mIEffectClient.clear();
    mCblkMemory.clear();
}


status_t AudioEffect::initCheck() const
{
    return mStatus;
}

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

effect_descriptor_t AudioEffect::descriptor() const
{
    return mDescriptor;
}

bool AudioEffect::getEnabled() const
{
    return (mEnabled != 0);
}

status_t AudioEffect::setEnabled(bool enabled)
{
    if (mStatus != NO_ERROR) {
        return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
    }

    status_t status = NO_ERROR;

    AutoMutex lock(mLock);
    if (enabled != mEnabled) {
        if (enabled) {
            ALOGV("enable %p", this);
            status = mIEffect->enable();
        } else {
            ALOGV("disable %p", this);
            status = mIEffect->disable();
        }
        if (status == NO_ERROR) {
            mEnabled = enabled;
        }
    }
    return status;
}

status_t AudioEffect::command(uint32_t cmdCode,
                              uint32_t cmdSize,
                              void *cmdData,
                              uint32_t *replySize,
                              void *replyData)
{
    if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
        ALOGV("command() bad status %d", mStatus);
        return mStatus;
    }

    if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
        if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) {
            return NO_ERROR;
        }
        if (replySize == NULL || *replySize != sizeof(status_t) || replyData == NULL) {
            return BAD_VALUE;
        }
        mLock.lock();
    }

    status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);

    if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
        if (status == NO_ERROR) {
            status = *(status_t *)replyData;
        }
        if (status == NO_ERROR) {
            mEnabled = (cmdCode == EFFECT_CMD_ENABLE);
        }
        mLock.unlock();
    }

    return status;
}


status_t AudioEffect::setParameter(effect_param_t *param)
{
    if (mStatus != NO_ERROR) {
        return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
    }

    if (param == NULL || param->psize == 0 || param->vsize == 0) {
        return BAD_VALUE;
    }

    uint32_t size = sizeof(int);
    uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;

    ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);

    return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, &param->status);
}

status_t AudioEffect::setParameterDeferred(effect_param_t *param)
{
    if (mStatus != NO_ERROR) {
        return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
    }

    if (param == NULL || param->psize == 0 || param->vsize == 0) {
        return BAD_VALUE;
    }

    Mutex::Autolock _l(mCblk->lock);

    int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
    int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int);

    if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) {
        return NO_MEMORY;
    }
    int *p = (int *)(mCblk->buffer + mCblk->clientIndex);
    *p++ = size;
    memcpy(p, param, sizeof(effect_param_t) + psize);
    mCblk->clientIndex += size;

    return NO_ERROR;
}

status_t AudioEffect::setParameterCommit()
{
    if (mStatus != NO_ERROR) {
        return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
    }

    Mutex::Autolock _l(mCblk->lock);
    if (mCblk->clientIndex == 0) {
        return INVALID_OPERATION;
    }
    uint32_t size = 0;
    return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL);
}

status_t AudioEffect::getParameter(effect_param_t *param)
{
    if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
        return mStatus;
    }

    if (param == NULL || param->psize == 0 || param->vsize == 0) {
        return BAD_VALUE;
    }

    ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);

    uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;

    return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, &psize, param);
}


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

void AudioEffect::binderDied()
{
    ALOGW("IEffect died");
    mStatus = DEAD_OBJECT;
    if (mCbf != NULL) {
        status_t status = DEAD_OBJECT;
        mCbf(EVENT_ERROR, mUserData, &status);
    }
    mIEffect.clear();
}

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

void AudioEffect::controlStatusChanged(bool controlGranted)
{
    ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, mUserData);
    if (controlGranted) {
        if (mStatus == ALREADY_EXISTS) {
            mStatus = NO_ERROR;
        }
    } else {
        if (mStatus == NO_ERROR) {
            mStatus = ALREADY_EXISTS;
        }
    }
    if (mCbf != NULL) {
        mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted);
    }
}

void AudioEffect::enableStatusChanged(bool enabled)
{
    ALOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf);
    if (mStatus == ALREADY_EXISTS) {
        mEnabled = enabled;
        if (mCbf != NULL) {
            mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
        }
    }
}

void AudioEffect::commandExecuted(uint32_t cmdCode,
                                  uint32_t cmdSize,
                                  void *cmdData,
                                  uint32_t replySize,
                                  void *replyData)
{
    if (cmdData == NULL || replyData == NULL) {
        return;
    }

    if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) {
        effect_param_t *cmd = (effect_param_t *)cmdData;
        cmd->status = *(int32_t *)replyData;
        mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd);
    }
}

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

status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
{
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    return af->queryNumberEffects(numEffects);
}

status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
{
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    return af->queryEffect(index, descriptor);
}

status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid,
        effect_descriptor_t *descriptor) /*const*/
{
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    return af->getEffectDescriptor(uuid, descriptor);
}


status_t AudioEffect::queryDefaultPreProcessing(int audioSession,
                                          effect_descriptor_t *descriptors,
                                          uint32_t *count)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;
    return aps->queryDefaultPreProcessing(audioSession, descriptors, count);
}
// -------------------------------------------------------------------------

status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
{
    if (str == NULL || guid == NULL) {
        return BAD_VALUE;
    }

    int tmp[10];

    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
        return BAD_VALUE;
    }
    guid->timeLow = (uint32_t)tmp[0];
    guid->timeMid = (uint16_t)tmp[1];
    guid->timeHiAndVersion = (uint16_t)tmp[2];
    guid->clockSeq = (uint16_t)tmp[3];
    guid->node[0] = (uint8_t)tmp[4];
    guid->node[1] = (uint8_t)tmp[5];
    guid->node[2] = (uint8_t)tmp[6];
    guid->node[3] = (uint8_t)tmp[7];
    guid->node[4] = (uint8_t)tmp[8];
    guid->node[5] = (uint8_t)tmp[9];

    return NO_ERROR;
}

status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen)
{
    if (guid == NULL || str == NULL) {
        return BAD_VALUE;
    }

    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
            guid->timeLow,
            guid->timeMid,
            guid->timeHiAndVersion,
            guid->clockSeq,
            guid->node[0],
            guid->node[1],
            guid->node[2],
            guid->node[3],
            guid->node[4],
            guid->node[5]);

    return NO_ERROR;
}


}; // namespace android
