/*
 * Copyright (C) 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_TAG "IMountService"

#include <storage/IMountService.h>
#include <binder/Parcel.h>

namespace android {

enum {
    TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION,
    TRANSACTION_unregisterListener,
    TRANSACTION_isUsbMassStorageConnected,
    TRANSACTION_setUsbMassStorageEnabled,
    TRANSACTION_isUsbMassStorageEnabled,
    TRANSACTION_mountVolume,
    TRANSACTION_unmountVolume,
    TRANSACTION_formatVolume,
    TRANSACTION_getStorageUsers,
    TRANSACTION_getVolumeState,
    TRANSACTION_createSecureContainer,
    TRANSACTION_finalizeSecureContainer,
    TRANSACTION_destroySecureContainer,
    TRANSACTION_mountSecureContainer,
    TRANSACTION_unmountSecureContainer,
    TRANSACTION_isSecureContainerMounted,
    TRANSACTION_renameSecureContainer,
    TRANSACTION_getSecureContainerPath,
    TRANSACTION_getSecureContainerList,
    TRANSACTION_shutdown,
    TRANSACTION_finishMediaUpdate,
    TRANSACTION_mountObb,
    TRANSACTION_unmountObb,
    TRANSACTION_isObbMounted,
    TRANSACTION_getMountedObbPath,
    TRANSACTION_isExternalStorageEmulated,
    TRANSACTION_decryptStorage,
    TRANSACTION_encryptStorage,
};

class BpMountService: public BpInterface<IMountService>
{
public:
    BpMountService(const sp<IBinder>& impl)
        : BpInterface<IMountService>(impl)
    {
    }

    virtual void registerListener(const sp<IMountServiceListener>& listener)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeStrongBinder(listener->asBinder());
        if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) {
            ALOGD("registerListener could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("registerListener caught exception %d\n", err);
            return;
        }
    }

    virtual void unregisterListener(const sp<IMountServiceListener>& listener)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeStrongBinder(listener->asBinder());
        if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) {
            ALOGD("unregisterListener could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("unregisterListener caught exception %d\n", err);
            return;
        }
    }

    virtual bool isUsbMassStorageConnected()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) {
            ALOGD("isUsbMassStorageConnected could not contact remote\n");
            return false;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("isUsbMassStorageConnected caught exception %d\n", err);
            return false;
        }
        return reply.readInt32() != 0;
    }

    virtual void setUsbMassStorageEnabled(const bool enable)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeInt32(enable != 0);
        if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
            ALOGD("setUsbMassStorageEnabled could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("setUsbMassStorageEnabled caught exception %d\n", err);
            return;
        }
    }

    virtual bool isUsbMassStorageEnabled()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
            ALOGD("isUsbMassStorageEnabled could not contact remote\n");
            return false;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("isUsbMassStorageEnabled caught exception %d\n", err);
            return false;
        }
        return reply.readInt32() != 0;
    }

    int32_t mountVolume(const String16& mountPoint)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(mountPoint);
        if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) {
            ALOGD("mountVolume could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("mountVolume caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(mountPoint);
        data.writeInt32(force ? 1 : 0);
        data.writeInt32(removeEncryption ? 1 : 0);
        if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
            ALOGD("unmountVolume could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("unmountVolume caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t formatVolume(const String16& mountPoint)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(mountPoint);
        if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) {
            ALOGD("formatVolume could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("formatVolume caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t getStorageUsers(const String16& mountPoint, int32_t** users)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(mountPoint);
        if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) {
            ALOGD("getStorageUsers could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("getStorageUsers caught exception %d\n", err);
            return err;
        }
        const int32_t numUsers = reply.readInt32();
        *users = (int32_t*)malloc(sizeof(int32_t)*numUsers);
        for (int i = 0; i < numUsers; i++) {
            **users++ = reply.readInt32();
        }
        return numUsers;
    }

    int32_t getVolumeState(const String16& mountPoint)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(mountPoint);
        if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) {
            ALOGD("getVolumeState could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("getVolumeState caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype,
            const String16& key, const int32_t ownerUid)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        data.writeInt32(sizeMb);
        data.writeString16(fstype);
        data.writeString16(key);
        data.writeInt32(ownerUid);
        if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) {
            ALOGD("createSecureContainer could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("createSecureContainer caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t finalizeSecureContainer(const String16& id)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) {
            ALOGD("finalizeSecureContainer couldn't call remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("finalizeSecureContainer caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t destroySecureContainer(const String16& id)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) {
            ALOGD("destroySecureContainer couldn't call remote");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("destroySecureContainer caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        data.writeString16(key);
        data.writeInt32(ownerUid);
        if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) {
            ALOGD("mountSecureContainer couldn't call remote");
            return -1;
        }
        int32_t err = reply.readExceptionCode(); // What to do...
        if (err < 0) {
            ALOGD("mountSecureContainer caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t unmountSecureContainer(const String16& id, const bool force)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        data.writeInt32(force ? 1 : 0);
        if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
            ALOGD("unmountSecureContainer couldn't call remote");
            return -1;
        }
        int32_t err = reply.readExceptionCode(); // What to do...
        if (err < 0) {
            ALOGD("unmountSecureContainer caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    bool isSecureContainerMounted(const String16& id)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) {
            ALOGD("isSecureContainerMounted couldn't call remote");
            return false;
        }
        int32_t err = reply.readExceptionCode(); // What to do...
        if (err < 0) {
            ALOGD("isSecureContainerMounted caught exception %d\n", err);
            return false;
        }
        return reply.readInt32() != 0;
    }

    int32_t renameSecureContainer(const String16& oldId, const String16& newId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(oldId);
        data.writeString16(newId);
        if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) {
            ALOGD("renameSecureContainer couldn't call remote");
            return -1;
        }
        int32_t err = reply.readExceptionCode(); // What to do...
        if (err < 0) {
            ALOGD("renameSecureContainer caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    bool getSecureContainerPath(const String16& id, String16& path)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
            ALOGD("getSecureContainerPath couldn't call remote");
            return false;
        }
        int32_t err = reply.readExceptionCode(); // What to do...
        if (err < 0) {
            ALOGD("getSecureContainerPath caught exception %d\n", err);
            return false;
        }
        path = reply.readString16();
        return true;
    }

    int32_t getSecureContainerList(const String16& id, String16*& containers)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(id);
        if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) {
            ALOGD("getSecureContainerList couldn't call remote");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("getSecureContainerList caught exception %d\n", err);
            return err;
        }
        const int32_t numStrings = reply.readInt32();
        containers = new String16[numStrings];
        for (int i = 0; i < numStrings; i++) {
            containers[i] = reply.readString16();
        }
        return numStrings;
    }

    void shutdown(const sp<IMountShutdownObserver>& observer)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeStrongBinder(observer->asBinder());
        if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) {
            ALOGD("shutdown could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("shutdown caught exception %d\n", err);
            return;
        }
        reply.readExceptionCode();
    }

    void finishMediaUpdate()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) {
            ALOGD("finishMediaUpdate could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("finishMediaUpdate caught exception %d\n", err);
            return;
        }
        reply.readExceptionCode();
    }

    void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
            const sp<IObbActionListener>& token, int32_t nonce)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(rawPath);
        data.writeString16(canonicalPath);
        data.writeString16(key);
        data.writeStrongBinder(token->asBinder());
        data.writeInt32(nonce);
        if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
            ALOGD("mountObb could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("mountObb caught exception %d\n", err);
            return;
        }
    }

    void unmountObb(const String16& filename, const bool force,
            const sp<IObbActionListener>& token, const int32_t nonce)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(filename);
        data.writeInt32(force ? 1 : 0);
        data.writeStrongBinder(token->asBinder());
        data.writeInt32(nonce);
        if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
            ALOGD("unmountObb could not contact remote\n");
            return;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("unmountObb caught exception %d\n", err);
            return;
        }
    }

    bool isObbMounted(const String16& filename)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(filename);
        if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
            ALOGD("isObbMounted could not contact remote\n");
            return false;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("isObbMounted caught exception %d\n", err);
            return false;
        }
        return reply.readInt32() != 0;
    }

    bool getMountedObbPath(const String16& filename, String16& path)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(filename);
        if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
            ALOGD("getMountedObbPath could not contact remote\n");
            return false;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("getMountedObbPath caught exception %d\n", err);
            return false;
        }
        path = reply.readString16();
        return true;
    }

    int32_t decryptStorage(const String16& password)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(password);
        if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
            ALOGD("decryptStorage could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("decryptStorage caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }

    int32_t encryptStorage(const String16& password)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(password);
        if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
            ALOGD("encryptStorage could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            ALOGD("encryptStorage caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }
};

IMPLEMENT_META_INTERFACE(MountService, "IMountService");

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

};
