/*
 * Copyright (C) 2012 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 "IHDCP"
#include <utils/Log.h>

#include <binder/Parcel.h>
#include <media/IHDCP.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/foundation/ADebug.h>

namespace android {

enum {
    OBSERVER_NOTIFY = IBinder::FIRST_CALL_TRANSACTION,
    HDCP_SET_OBSERVER,
    HDCP_INIT_ASYNC,
    HDCP_SHUTDOWN_ASYNC,
    HDCP_GET_CAPS,
    HDCP_ENCRYPT,
    HDCP_ENCRYPT_NATIVE,
    HDCP_DECRYPT,
};

struct BpHDCPObserver : public BpInterface<IHDCPObserver> {
    BpHDCPObserver(const sp<IBinder> &impl)
        : BpInterface<IHDCPObserver>(impl) {
    }

    virtual void notify(
            int msg, int ext1, int ext2, const Parcel *obj) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCPObserver::getInterfaceDescriptor());
        data.writeInt32(msg);
        data.writeInt32(ext1);
        data.writeInt32(ext2);
        if (obj && obj->dataSize() > 0) {
            data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize());
        }
        remote()->transact(OBSERVER_NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);
    }
};

IMPLEMENT_META_INTERFACE(HDCPObserver, "android.hardware.IHDCPObserver");

struct BpHDCP : public BpInterface<IHDCP> {
    BpHDCP(const sp<IBinder> &impl)
        : BpInterface<IHDCP>(impl) {
    }

    virtual status_t setObserver(const sp<IHDCPObserver> &observer) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(observer));
        remote()->transact(HDCP_SET_OBSERVER, data, &reply);
        return reply.readInt32();
    }

    virtual status_t initAsync(const char *host, unsigned port) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        data.writeCString(host);
        data.writeInt32(port);
        remote()->transact(HDCP_INIT_ASYNC, data, &reply);
        return reply.readInt32();
    }

    virtual status_t shutdownAsync() {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        remote()->transact(HDCP_SHUTDOWN_ASYNC, data, &reply);
        return reply.readInt32();
    }

    virtual uint32_t getCaps() {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        remote()->transact(HDCP_GET_CAPS, data, &reply);
        return reply.readInt32();
    }

    virtual status_t encrypt(
            const void *inData, size_t size, uint32_t streamCTR,
            uint64_t *outInputCTR, void *outData) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        data.writeInt32(size);
        data.write(inData, size);
        data.writeInt32(streamCTR);
        remote()->transact(HDCP_ENCRYPT, data, &reply);

        status_t err = reply.readInt32();

        if (err != OK) {
            *outInputCTR = 0;

            return err;
        }

        *outInputCTR = reply.readInt64();
        reply.read(outData, size);

        return err;
    }

    virtual status_t encryptNative(
            const sp<GraphicBuffer> &graphicBuffer,
            size_t offset, size_t size, uint32_t streamCTR,
            uint64_t *outInputCTR, void *outData) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        data.write(*graphicBuffer);
        data.writeInt32(offset);
        data.writeInt32(size);
        data.writeInt32(streamCTR);
        remote()->transact(HDCP_ENCRYPT_NATIVE, data, &reply);

        status_t err = reply.readInt32();

        if (err != OK) {
            *outInputCTR = 0;
            return err;
        }

        *outInputCTR = reply.readInt64();
        reply.read(outData, size);

        return err;
    }

    virtual status_t decrypt(
            const void *inData, size_t size,
            uint32_t streamCTR, uint64_t inputCTR,
            void *outData) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        data.writeInt32(size);
        data.write(inData, size);
        data.writeInt32(streamCTR);
        data.writeInt64(inputCTR);
        remote()->transact(HDCP_DECRYPT, data, &reply);

        status_t err = reply.readInt32();

        if (err != OK) {
            return err;
        }

        reply.read(outData, size);

        return err;
    }
};

IMPLEMENT_META_INTERFACE(HDCP, "android.hardware.IHDCP");

status_t BnHDCPObserver::onTransact(
        uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
    switch (code) {
        case OBSERVER_NOTIFY:
        {
            CHECK_INTERFACE(IHDCPObserver, data, reply);

            int msg = data.readInt32();
            int ext1 = data.readInt32();
            int ext2 = data.readInt32();

            Parcel obj;
            if (data.dataAvail() > 0) {
                obj.appendFrom(
                        const_cast<Parcel *>(&data),
                        data.dataPosition(),
                        data.dataAvail());
            }

            notify(msg, ext1, ext2, &obj);

            return OK;
        }

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

status_t BnHDCP::onTransact(
        uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
    switch (code) {
        case HDCP_SET_OBSERVER:
        {
            CHECK_INTERFACE(IHDCP, data, reply);

            sp<IHDCPObserver> observer =
                interface_cast<IHDCPObserver>(data.readStrongBinder());

            reply->writeInt32(setObserver(observer));
            return OK;
        }

        case HDCP_INIT_ASYNC:
        {
            CHECK_INTERFACE(IHDCP, data, reply);

            const char *host = data.readCString();
            unsigned port = data.readInt32();

            reply->writeInt32(initAsync(host, port));
            return OK;
        }

        case HDCP_SHUTDOWN_ASYNC:
        {
            CHECK_INTERFACE(IHDCP, data, reply);

            reply->writeInt32(shutdownAsync());
            return OK;
        }

        case HDCP_GET_CAPS:
        {
            CHECK_INTERFACE(IHDCP, data, reply);

            reply->writeInt32(getCaps());
            return OK;
        }

        case HDCP_ENCRYPT:
        {
            size_t size = data.readInt32();
            void *inData = NULL;
            // watch out for overflow
            if (size <= SIZE_MAX / 2) {
                inData = malloc(2 * size);
            }
            if (inData == NULL) {
                reply->writeInt32(ERROR_OUT_OF_RANGE);
                return OK;
            }

            void *outData = (uint8_t *)inData + size;

            status_t err = data.read(inData, size);
            if (err != OK) {
                free(inData);
                reply->writeInt32(err);
                return OK;
            }

            uint32_t streamCTR = data.readInt32();
            uint64_t inputCTR;
            err = encrypt(inData, size, streamCTR, &inputCTR, outData);

            reply->writeInt32(err);

            if (err == OK) {
                reply->writeInt64(inputCTR);
                reply->write(outData, size);
            }

            free(inData);
            inData = outData = NULL;

            return OK;
        }

        case HDCP_ENCRYPT_NATIVE:
        {
            CHECK_INTERFACE(IHDCP, data, reply);

            sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
            data.read(*graphicBuffer);
            size_t offset = data.readInt32();
            size_t size = data.readInt32();
            uint32_t streamCTR = data.readInt32();
            void *outData = NULL;
            uint64_t inputCTR;

            status_t err = ERROR_OUT_OF_RANGE;

            outData = malloc(size);

            if (outData != NULL) {
                err = encryptNative(graphicBuffer, offset, size,
                                             streamCTR, &inputCTR, outData);
            }

            reply->writeInt32(err);

            if (err == OK) {
                reply->writeInt64(inputCTR);
                reply->write(outData, size);
            }

            free(outData);
            outData = NULL;

            return OK;
        }

        case HDCP_DECRYPT:
        {
            size_t size = data.readInt32();
            size_t bufSize = 2 * size;

            // watch out for overflow
            void *inData = NULL;
            if (bufSize > size) {
                inData = malloc(bufSize);
            }

            if (inData == NULL) {
                reply->writeInt32(ERROR_OUT_OF_RANGE);
                return OK;
            }

            void *outData = (uint8_t *)inData + size;

            data.read(inData, size);

            uint32_t streamCTR = data.readInt32();
            uint64_t inputCTR = data.readInt64();
            status_t err = decrypt(inData, size, streamCTR, inputCTR, outData);

            reply->writeInt32(err);

            if (err == OK) {
                reply->write(outData, size);
            }

            free(inData);
            inData = outData = NULL;

            return OK;
        }

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

}  // namespace android
