/*
**
** 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 "IEffect"
#include <utils/Log.h>
#include <stdint.h>
#include <sys/types.h>
#include <binder/Parcel.h>
#include <media/IEffect.h>

namespace android {

enum {
    ENABLE = IBinder::FIRST_CALL_TRANSACTION,
    DISABLE,
    COMMAND,
    DISCONNECT,
    GET_CBLK
};

class BpEffect: public BpInterface<IEffect>
{
public:
    BpEffect(const sp<IBinder>& impl)
        : BpInterface<IEffect>(impl)
    {
    }

    status_t enable()
    {
        LOGV("enable");
        Parcel data, reply;
        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
        remote()->transact(ENABLE, data, &reply);
        return reply.readInt32();
    }

    status_t disable()
    {
        LOGV("disable");
        Parcel data, reply;
        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
        remote()->transact(DISABLE, data, &reply);
        return reply.readInt32();
    }

    status_t command(uint32_t cmdCode,
                     uint32_t cmdSize,
                     void *pCmdData,
                     uint32_t *pReplySize,
                     void *pReplyData)
    {
        LOGV("command");
        Parcel data, reply;
        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
        data.writeInt32(cmdCode);
        int size = cmdSize;
        if (pCmdData == NULL) {
            size = 0;
        }
        data.writeInt32(size);
        if (size) {
            data.write(pCmdData, size);
        }
        if (pReplySize == NULL) {
            size = 0;
        } else {
            size = *pReplySize;
        }
        data.writeInt32(size);

        status_t status = remote()->transact(COMMAND, data, &reply);
        if (status != NO_ERROR) {
            if (pReplySize != NULL)
                *pReplySize = 0;
            return status;
        }

        status = reply.readInt32();
        size = reply.readInt32();
        if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
            reply.read(pReplyData, size);
            *pReplySize = size;
        }
        return status;
    }

    void disconnect()
    {
        LOGV("disconnect");
        Parcel data, reply;
        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
        remote()->transact(DISCONNECT, data, &reply);
        return;
    }

    virtual sp<IMemory> getCblk() const
    {
        Parcel data, reply;
        sp<IMemory> cblk;
        data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_CBLK, data, &reply);
        if (status == NO_ERROR) {
            cblk = interface_cast<IMemory>(reply.readStrongBinder());
        }
        return cblk;
    }
 };

IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect");

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

status_t BnEffect::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case ENABLE: {
            LOGV("ENABLE");
            CHECK_INTERFACE(IEffect, data, reply);
            reply->writeInt32(enable());
            return NO_ERROR;
        } break;

        case DISABLE: {
            LOGV("DISABLE");
            CHECK_INTERFACE(IEffect, data, reply);
            reply->writeInt32(disable());
            return NO_ERROR;
        } break;

        case COMMAND: {
            LOGV("COMMAND");
            CHECK_INTERFACE(IEffect, data, reply);
            uint32_t cmdCode = data.readInt32();
            uint32_t cmdSize = data.readInt32();
            char *cmd = NULL;
            if (cmdSize) {
                cmd = (char *)malloc(cmdSize);
                data.read(cmd, cmdSize);
            }
            uint32_t replySize = data.readInt32();
            uint32_t replySz = replySize;
            char *resp = NULL;
            if (replySize) {
                resp = (char *)malloc(replySize);
            }
            status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
            reply->writeInt32(status);
            if (replySz < replySize) {
                replySize = replySz;
            }
            reply->writeInt32(replySize);
            if (replySize) {
                reply->write(resp, replySize);
            }
            if (cmd) {
                free(cmd);
            }
            if (resp) {
                free(resp);
            }
            return NO_ERROR;
        } break;

        case DISCONNECT: {
            LOGV("DISCONNECT");
            CHECK_INTERFACE(IEffect, data, reply);
            disconnect();
            return NO_ERROR;
        } break;

        case GET_CBLK: {
             CHECK_INTERFACE(IEffect, data, reply);
             reply->writeStrongBinder(getCblk()->asBinder());
             return NO_ERROR;
         } break;

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

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

}; // namespace android

