/*
 * 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_NDEBUG 0

#define LOG_TAG "MtpDeviceJNI"
#include "utils/Log.h"

#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>

#include <memory>
#include <string>

#include "jni.h"
#include "JNIHelp.h"
#include "ScopedPrimitiveArray.h"

#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "nativehelper/ScopedLocalRef.h"
#include "private/android_filesystem_config.h"

#include "MtpTypes.h"
#include "MtpDevice.h"
#include "MtpDeviceInfo.h"
#include "MtpStorageInfo.h"
#include "MtpObjectInfo.h"
#include "MtpProperty.h"

using namespace android;

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

namespace {

static jfieldID field_context;

jclass clazz_deviceInfo;
jclass clazz_storageInfo;
jclass clazz_objectInfo;
jclass clazz_event;
jclass clazz_io_exception;
jclass clazz_operation_canceled_exception;

jmethodID constructor_deviceInfo;
jmethodID constructor_storageInfo;
jmethodID constructor_objectInfo;
jmethodID constructor_event;

// MtpDeviceInfo fields
static jfieldID field_deviceInfo_manufacturer;
static jfieldID field_deviceInfo_model;
static jfieldID field_deviceInfo_version;
static jfieldID field_deviceInfo_serialNumber;
static jfieldID field_deviceInfo_operationsSupported;
static jfieldID field_deviceInfo_eventsSupported;

// MtpStorageInfo fields
static jfieldID field_storageInfo_storageId;
static jfieldID field_storageInfo_maxCapacity;
static jfieldID field_storageInfo_freeSpace;
static jfieldID field_storageInfo_description;
static jfieldID field_storageInfo_volumeIdentifier;

// MtpObjectInfo fields
static jfieldID field_objectInfo_handle;
static jfieldID field_objectInfo_storageId;
static jfieldID field_objectInfo_format;
static jfieldID field_objectInfo_protectionStatus;
static jfieldID field_objectInfo_compressedSize;
static jfieldID field_objectInfo_thumbFormat;
static jfieldID field_objectInfo_thumbCompressedSize;
static jfieldID field_objectInfo_thumbPixWidth;
static jfieldID field_objectInfo_thumbPixHeight;
static jfieldID field_objectInfo_imagePixWidth;
static jfieldID field_objectInfo_imagePixHeight;
static jfieldID field_objectInfo_imagePixDepth;
static jfieldID field_objectInfo_parent;
static jfieldID field_objectInfo_associationType;
static jfieldID field_objectInfo_associationDesc;
static jfieldID field_objectInfo_sequenceNumber;
static jfieldID field_objectInfo_name;
static jfieldID field_objectInfo_dateCreated;
static jfieldID field_objectInfo_dateModified;
static jfieldID field_objectInfo_keywords;

// MtpEvent fields
static jfieldID field_event_eventCode;
static jfieldID field_event_parameter1;
static jfieldID field_event_parameter2;
static jfieldID field_event_parameter3;

class JavaArrayWriter {
public:
    JavaArrayWriter(JNIEnv* env, jbyteArray array) :
        mEnv(env), mArray(array), mSize(mEnv->GetArrayLength(mArray)) {}
    bool write(void* data, uint32_t offset, uint32_t length) {
        if (static_cast<uint32_t>(mSize) < offset + length) {
            return false;
        }
        mEnv->SetByteArrayRegion(mArray, offset, length, static_cast<jbyte*>(data));
        return true;
    }
    static bool writeTo(void* data, uint32_t offset, uint32_t length, void* clientData) {
        return static_cast<JavaArrayWriter*>(clientData)->write(data, offset, length);
    }

private:
    JNIEnv* mEnv;
    jbyteArray mArray;
    jsize mSize;
};

}

MtpDevice* get_device_from_object(JNIEnv* env, jobject javaDevice)
{
    return (MtpDevice*)env->GetLongField(javaDevice, field_context);
}

void fill_jobject_from_object_info(JNIEnv* env, jobject object, MtpObjectInfo* objectInfo) {
    if (objectInfo->mHandle)
        env->SetIntField(object, field_objectInfo_handle, objectInfo->mHandle);
    if (objectInfo->mStorageID)
        env->SetIntField(object, field_objectInfo_storageId, objectInfo->mStorageID);
    if (objectInfo->mFormat)
        env->SetIntField(object, field_objectInfo_format, objectInfo->mFormat);
    if (objectInfo->mProtectionStatus)
        env->SetIntField(object, field_objectInfo_protectionStatus, objectInfo->mProtectionStatus);
    if (objectInfo->mCompressedSize)
        env->SetIntField(object, field_objectInfo_compressedSize, objectInfo->mCompressedSize);
    if (objectInfo->mThumbFormat)
        env->SetIntField(object, field_objectInfo_thumbFormat, objectInfo->mThumbFormat);
    if (objectInfo->mThumbCompressedSize) {
        env->SetIntField(object, field_objectInfo_thumbCompressedSize,
                objectInfo->mThumbCompressedSize);
    }
    if (objectInfo->mThumbPixWidth)
        env->SetIntField(object, field_objectInfo_thumbPixWidth, objectInfo->mThumbPixWidth);
    if (objectInfo->mThumbPixHeight)
        env->SetIntField(object, field_objectInfo_thumbPixHeight, objectInfo->mThumbPixHeight);
    if (objectInfo->mImagePixWidth)
        env->SetIntField(object, field_objectInfo_imagePixWidth, objectInfo->mImagePixWidth);
    if (objectInfo->mImagePixHeight)
        env->SetIntField(object, field_objectInfo_imagePixHeight, objectInfo->mImagePixHeight);
    if (objectInfo->mImagePixDepth)
        env->SetIntField(object, field_objectInfo_imagePixDepth, objectInfo->mImagePixDepth);
    if (objectInfo->mParent)
        env->SetIntField(object, field_objectInfo_parent, objectInfo->mParent);
    if (objectInfo->mAssociationType)
        env->SetIntField(object, field_objectInfo_associationType, objectInfo->mAssociationType);
    if (objectInfo->mAssociationDesc)
        env->SetIntField(object, field_objectInfo_associationDesc, objectInfo->mAssociationDesc);
    if (objectInfo->mSequenceNumber)
        env->SetIntField(object, field_objectInfo_sequenceNumber, objectInfo->mSequenceNumber);
    if (objectInfo->mName)
        env->SetObjectField(object, field_objectInfo_name, env->NewStringUTF(objectInfo->mName));
    if (objectInfo->mDateCreated)
        env->SetLongField(object, field_objectInfo_dateCreated, objectInfo->mDateCreated * 1000LL);
    if (objectInfo->mDateModified) {
        env->SetLongField(object, field_objectInfo_dateModified,
                objectInfo->mDateModified * 1000LL);
    }
    if (objectInfo->mKeywords) {
        env->SetObjectField(object, field_objectInfo_keywords,
            env->NewStringUTF(objectInfo->mKeywords));
    }
}

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

static jboolean
android_mtp_MtpDevice_open(JNIEnv *env, jobject thiz, jstring deviceName, jint fd)
{
    const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
    if (deviceNameStr == NULL) {
        return JNI_FALSE;
    }

    // The passed in fd is maintained by the UsbDeviceConnection
    fd = dup(fd);

    MtpDevice* device = MtpDevice::open(deviceNameStr, fd);
    env->ReleaseStringUTFChars(deviceName, deviceNameStr);

    if (device)
        env->SetLongField(thiz, field_context,  (jlong)device);
    return (jboolean)(device != NULL);
}

static void
android_mtp_MtpDevice_close(JNIEnv *env, jobject thiz)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (device) {
        device->close();
        delete device;
        env->SetLongField(thiz, field_context, 0);
    }
}

static jobject
android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device) {
        ALOGD("android_mtp_MtpDevice_get_device_info device is null");
        return NULL;
    }
    std::unique_ptr<MtpDeviceInfo> deviceInfo(device->getDeviceInfo());
    if (!deviceInfo) {
        ALOGD("android_mtp_MtpDevice_get_device_info deviceInfo is null");
        return NULL;
    }
    jobject info = env->NewObject(clazz_deviceInfo, constructor_deviceInfo);
    if (info == NULL) {
        ALOGE("Could not create a MtpDeviceInfo object");
        return NULL;
    }

    if (deviceInfo->mManufacturer)
        env->SetObjectField(info, field_deviceInfo_manufacturer,
            env->NewStringUTF(deviceInfo->mManufacturer));
    if (deviceInfo->mModel)
        env->SetObjectField(info, field_deviceInfo_model,
            env->NewStringUTF(deviceInfo->mModel));
    if (deviceInfo->mVersion)
        env->SetObjectField(info, field_deviceInfo_version,
            env->NewStringUTF(deviceInfo->mVersion));
    if (deviceInfo->mSerial)
        env->SetObjectField(info, field_deviceInfo_serialNumber,
            env->NewStringUTF(deviceInfo->mSerial));
    assert(deviceInfo->mOperations);
    {
        const size_t size = deviceInfo->mOperations->size();
        ScopedLocalRef<jintArray> operations(env, static_cast<jintArray>(env->NewIntArray(size)));
        {
            ScopedIntArrayRW elements(env, operations.get());
            if (elements.get() == NULL) {
                ALOGE("Could not create operationsSupported element.");
                return NULL;
            }
            for (size_t i = 0; i < size; ++i) {
                elements[i] = deviceInfo->mOperations->itemAt(i);
            }
            env->SetObjectField(info, field_deviceInfo_operationsSupported, operations.get());
        }
    }
    assert(deviceInfo->mEvents);
    {
        const size_t size = deviceInfo->mEvents->size();
        ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size)));
        {
            ScopedIntArrayRW elements(env, events.get());
            if (elements.get() == NULL) {
                ALOGE("Could not create eventsSupported element.");
                return NULL;
            }
            for (size_t i = 0; i < size; ++i) {
                elements[i] = deviceInfo->mEvents->itemAt(i);
            }
            env->SetObjectField(info, field_deviceInfo_eventsSupported, events.get());
        }
    }

    return info;
}

static jintArray
android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device)
        return NULL;
    MtpStorageIDList* storageIDs = device->getStorageIDs();
    if (!storageIDs)
        return NULL;

    int length = storageIDs->size();
    jintArray array = env->NewIntArray(length);
    // FIXME is this cast safe?
    env->SetIntArrayRegion(array, 0, length, (const jint *)storageIDs->array());

    delete storageIDs;
    return array;
}

static jobject
android_mtp_MtpDevice_get_storage_info(JNIEnv *env, jobject thiz, jint storageID)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device)
        return NULL;
    MtpStorageInfo* storageInfo = device->getStorageInfo(storageID);
    if (!storageInfo)
        return NULL;

    jobject info = env->NewObject(clazz_storageInfo, constructor_storageInfo);
    if (info == NULL) {
        ALOGE("Could not create a MtpStorageInfo object");
        delete storageInfo;
        return NULL;
    }

    if (storageInfo->mStorageID)
        env->SetIntField(info, field_storageInfo_storageId, storageInfo->mStorageID);
    if (storageInfo->mMaxCapacity)
        env->SetLongField(info, field_storageInfo_maxCapacity, storageInfo->mMaxCapacity);
    if (storageInfo->mFreeSpaceBytes)
        env->SetLongField(info, field_storageInfo_freeSpace, storageInfo->mFreeSpaceBytes);
    if (storageInfo->mStorageDescription)
        env->SetObjectField(info, field_storageInfo_description,
            env->NewStringUTF(storageInfo->mStorageDescription));
    if (storageInfo->mVolumeIdentifier)
        env->SetObjectField(info, field_storageInfo_volumeIdentifier,
            env->NewStringUTF(storageInfo->mVolumeIdentifier));

    delete storageInfo;
    return info;
}

static jintArray
android_mtp_MtpDevice_get_object_handles(JNIEnv *env, jobject thiz,
        jint storageID, jint format, jint objectID)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device)
        return NULL;
    MtpObjectHandleList* handles = device->getObjectHandles(storageID, format, objectID);
    if (!handles)
        return NULL;

    int length = handles->size();
    jintArray array = env->NewIntArray(length);
    // FIXME is this cast safe?
    env->SetIntArrayRegion(array, 0, length, (const jint *)handles->array());

    delete handles;
    return array;
}

static jobject
android_mtp_MtpDevice_get_object_info(JNIEnv *env, jobject thiz, jint objectID)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device)
        return NULL;
    MtpObjectInfo* objectInfo = device->getObjectInfo(objectID);
    if (!objectInfo)
        return NULL;
    jobject info = env->NewObject(clazz_objectInfo, constructor_objectInfo);
    if (info == NULL) {
        ALOGE("Could not create a MtpObjectInfo object");
        delete objectInfo;
        return NULL;
    }

    fill_jobject_from_object_info(env, info, objectInfo);
    delete objectInfo;
    return info;
}

bool check_uint32_arg(JNIEnv *env, const char* name, jlong value, uint32_t* out) {
    if (value < 0 || 0xffffffff < value) {
        jniThrowException(
                env,
                "java/lang/IllegalArgumentException",
                (std::string("argument must be a 32-bit unsigned integer: ") + name).c_str());
        return false;
    }
    *out = static_cast<uint32_t>(value);
    return true;
}

static jbyteArray
android_mtp_MtpDevice_get_object(JNIEnv *env, jobject thiz, jint objectID, jlong objectSizeLong)
{
    uint32_t objectSize;
    if (!check_uint32_arg(env, "objectSize", objectSizeLong, &objectSize)) {
        return nullptr;
    }

    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device) {
        return nullptr;
    }

    ScopedLocalRef<jbyteArray> array(env, env->NewByteArray(objectSize));
    if (!array.get()) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return nullptr;
    }

    JavaArrayWriter writer(env, array.get());

    if (device->readObject(objectID, JavaArrayWriter::writeTo, objectSize, &writer)) {
        return array.release();
    }
    return nullptr;
}

static jlong
android_mtp_MtpDevice_get_partial_object(JNIEnv *env,
                                         jobject thiz,
                                         jint objectID,
                                         jlong offsetLong,
                                         jlong sizeLong,
                                         jbyteArray array)
{
    if (!array) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "Array must not be null.");
        return -1;
    }

    uint32_t offset;
    uint32_t size;
    if (!check_uint32_arg(env, "offset", offsetLong, &offset) ||
            !check_uint32_arg(env, "size", sizeLong, &size)) {
        return -1;
    }

    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
        return -1;
    }

    JavaArrayWriter writer(env, array);
    uint32_t written_size;
    const bool success = device->readPartialObject(
            objectID, offset, size, &written_size, JavaArrayWriter::writeTo, &writer);
    if (!success) {
        jniThrowException(env, "java/io/IOException", "Failed to read data.");
        return -1;
    }
    return static_cast<jlong>(written_size);
}

static jint
android_mtp_MtpDevice_get_partial_object_64(JNIEnv *env,
                                            jobject thiz,
                                            jint objectID,
                                            jlong offset,
                                            jlong size,
                                            jbyteArray array) {
    if (!array) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "Array must not be null.");
        return -1;
    }

    if (offset < 0) {
        jniThrowException(
                env,
                "java/lang/IllegalArgumentException",
                "Offset argument must not be a negative value.");
        return -1;
    }

    if (size < 0 || 0xffffffffL < size) {
        jniThrowException(
                env,
                "java/lang/IllegalArgumentException",
                "Size argument must be a 32-bit unsigned integer.");
        return -1;
    }

    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
        return -1;
    }

    const uint32_t native_object_handle = static_cast<uint32_t>(objectID);
    const uint64_t native_offset = static_cast<uint64_t>(offset);
    const uint32_t native_size = static_cast<uint32_t>(size);

    JavaArrayWriter writer(env, array);
    uint32_t written_size;
    const bool success = device->readPartialObject64(
            native_object_handle,
            native_offset,
            native_size,
            &written_size,
            JavaArrayWriter::writeTo,
            &writer);
    if (!success) {
        jniThrowException(env, "java/io/IOException", "Failed to read data.");
        return -1;
    }
    return static_cast<jint>(written_size);
}

static jbyteArray
android_mtp_MtpDevice_get_thumbnail(JNIEnv *env, jobject thiz, jint objectID)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device)
        return NULL;

    int length;
    void* thumbnail = device->getThumbnail(objectID, length);
    if (! thumbnail)
        return NULL;
    jbyteArray array = env->NewByteArray(length);
    env->SetByteArrayRegion(array, 0, length, (const jbyte *)thumbnail);

    free(thumbnail);
    return array;
}

static jboolean
android_mtp_MtpDevice_delete_object(JNIEnv *env, jobject thiz, jint object_id)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (device && device->deleteObject(object_id)) {
        return JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}

static jint
android_mtp_MtpDevice_get_parent(JNIEnv *env, jobject thiz, jint object_id)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (device)
        return static_cast<jint>(device->getParent(object_id));
    else
        return -1;
}

static jint
android_mtp_MtpDevice_get_storage_id(JNIEnv *env, jobject thiz, jint object_id)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (device)
        return static_cast<jint>(device->getStorageID(object_id));
    else
        return -1;
}

static jboolean
android_mtp_MtpDevice_import_file(JNIEnv *env, jobject thiz, jint object_id, jstring dest_path)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (device) {
        const char *destPathStr = env->GetStringUTFChars(dest_path, NULL);
        if (destPathStr == NULL) {
            return JNI_FALSE;
        }

        jboolean result = device->readObject(object_id, destPathStr, AID_SDCARD_RW, 0664);
        env->ReleaseStringUTFChars(dest_path, destPathStr);
        return result;
    }

    return JNI_FALSE;
}

static jboolean
android_mtp_MtpDevice_import_file_to_fd(JNIEnv *env, jobject thiz, jint object_id, jint fd)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (device)
        return device->readObject(object_id, fd);
    else
        return JNI_FALSE;
}

static jboolean
android_mtp_MtpDevice_send_object(
        JNIEnv *env, jobject thiz, jint object_id, jlong sizeLong, jint fd)
{
    uint32_t size;
    if (!check_uint32_arg(env, "size", sizeLong, &size))
        return JNI_FALSE;

    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device)
        return JNI_FALSE;

    return device->sendObject(object_id, size, fd);
}

static jobject
android_mtp_MtpDevice_send_object_info(JNIEnv *env, jobject thiz, jobject info)
{
    MtpDevice* device = get_device_from_object(env, thiz);
    if (!device) {
        return NULL;
    }

    // Updating existing objects is not supported.
    if (env->GetIntField(info, field_objectInfo_handle) != -1) {
        return NULL;
    }

    MtpObjectInfo* object_info = new MtpObjectInfo(-1);
    object_info->mStorageID = env->GetIntField(info, field_objectInfo_storageId);
    object_info->mFormat = env->GetIntField(info, field_objectInfo_format);
    object_info->mProtectionStatus = env->GetIntField(info, field_objectInfo_protectionStatus);
    object_info->mCompressedSize = env->GetIntField(info, field_objectInfo_compressedSize);
    object_info->mThumbFormat = env->GetIntField(info, field_objectInfo_thumbFormat);
    object_info->mThumbCompressedSize =
            env->GetIntField(info, field_objectInfo_thumbCompressedSize);
    object_info->mThumbPixWidth = env->GetIntField(info, field_objectInfo_thumbPixWidth);
    object_info->mThumbPixHeight = env->GetIntField(info, field_objectInfo_thumbPixHeight);
    object_info->mImagePixWidth = env->GetIntField(info, field_objectInfo_imagePixWidth);
    object_info->mImagePixHeight = env->GetIntField(info, field_objectInfo_imagePixHeight);
    object_info->mImagePixDepth = env->GetIntField(info, field_objectInfo_imagePixDepth);
    object_info->mParent = env->GetIntField(info, field_objectInfo_parent);
    object_info->mAssociationType = env->GetIntField(info, field_objectInfo_associationType);
    object_info->mAssociationDesc = env->GetIntField(info, field_objectInfo_associationDesc);
    object_info->mSequenceNumber = env->GetIntField(info, field_objectInfo_sequenceNumber);

    jstring name_jstring = (jstring) env->GetObjectField(info, field_objectInfo_name);
    if (name_jstring != NULL) {
        const char* name_string = env->GetStringUTFChars(name_jstring, NULL);
        object_info->mName = strdup(name_string);
        env->ReleaseStringUTFChars(name_jstring, name_string);
    }

    object_info->mDateCreated = env->GetLongField(info, field_objectInfo_dateCreated) / 1000LL;
    object_info->mDateModified = env->GetLongField(info, field_objectInfo_dateModified) / 1000LL;

    jstring keywords_jstring = (jstring) env->GetObjectField(info, field_objectInfo_keywords);
    if (keywords_jstring != NULL) {
        const char* keywords_string = env->GetStringUTFChars(keywords_jstring, NULL);
        object_info->mKeywords = strdup(keywords_string);
        env->ReleaseStringUTFChars(keywords_jstring, keywords_string);
    }

    int object_handle = device->sendObjectInfo(object_info);
    if (object_handle == -1) {
        delete object_info;
        return NULL;
    }

    object_info->mHandle = object_handle;
    jobject result = env->NewObject(clazz_objectInfo, constructor_objectInfo);
    if (result == NULL) {
        ALOGE("Could not create a MtpObjectInfo object");
        delete object_info;
        return NULL;
    }

    fill_jobject_from_object_info(env, result, object_info);
    delete object_info;
    return result;
}

static jint android_mtp_MtpDevice_submit_event_request(JNIEnv *env, jobject thiz)
{
    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        env->ThrowNew(clazz_io_exception, "");
        return -1;
    }
    return device->submitEventRequest();
}

static jobject android_mtp_MtpDevice_reap_event_request(JNIEnv *env, jobject thiz, jint seq)
{
    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        env->ThrowNew(clazz_io_exception, "");
        return NULL;
    }
    uint32_t parameters[3];
    const int eventCode = device->reapEventRequest(seq, &parameters);
    if (eventCode <= 0) {
        env->ThrowNew(clazz_operation_canceled_exception, "");
        return NULL;
    }
    jobject result = env->NewObject(clazz_event, constructor_event);
    env->SetIntField(result, field_event_eventCode, eventCode);
    env->SetIntField(result, field_event_parameter1, static_cast<jint>(parameters[0]));
    env->SetIntField(result, field_event_parameter2, static_cast<jint>(parameters[1]));
    env->SetIntField(result, field_event_parameter3, static_cast<jint>(parameters[2]));
    return result;
}

static void android_mtp_MtpDevice_discard_event_request(JNIEnv *env, jobject thiz, jint seq)
{
    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        return;
    }
    device->discardEventRequest(seq);
}

// Returns object size in 64-bit integer. If the MTP device does not support the property, it
// throws IOException.
static jlong android_mtp_MtpDevice_get_object_size_long(
        JNIEnv *env, jobject thiz, jint handle, jint format) {
    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice.");
        return 0;
    }

    std::unique_ptr<MtpProperty> property(
            device->getObjectPropDesc(MTP_PROPERTY_OBJECT_SIZE, format));
    if (!property) {
        env->ThrowNew(clazz_io_exception, "Failed to obtain property desc.");
        return 0;
    }

    if (property->getDataType() != MTP_TYPE_UINT64) {
        env->ThrowNew(clazz_io_exception, "Unexpected property data type.");
        return 0;
    }

    if (!device->getObjectPropValue(handle, property.get())) {
        env->ThrowNew(clazz_io_exception, "Failed to obtain property value.");
        return 0;
    }

    const jlong object_size = static_cast<jlong>(property->getCurrentValue().u.u64);
    if (object_size < 0) {
        env->ThrowNew(clazz_io_exception, "Object size is too large to express as jlong.");
        return 0;
    }

    return object_size;
}

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

static const JNINativeMethod gMethods[] = {
    {"native_open",             "(Ljava/lang/String;I)Z",
                                        (void *)android_mtp_MtpDevice_open},
    {"native_close",            "()V",  (void *)android_mtp_MtpDevice_close},
    {"native_get_device_info",  "()Landroid/mtp/MtpDeviceInfo;",
                                        (void *)android_mtp_MtpDevice_get_device_info},
    {"native_get_storage_ids",  "()[I", (void *)android_mtp_MtpDevice_get_storage_ids},
    {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;",
                                        (void *)android_mtp_MtpDevice_get_storage_info},
    {"native_get_object_handles","(III)[I",
                                        (void *)android_mtp_MtpDevice_get_object_handles},
    {"native_get_object_info",  "(I)Landroid/mtp/MtpObjectInfo;",
                                        (void *)android_mtp_MtpDevice_get_object_info},
    {"native_get_object",       "(IJ)[B",(void *)android_mtp_MtpDevice_get_object},
    {"native_get_partial_object", "(IJJ[B)J", (void *)android_mtp_MtpDevice_get_partial_object},
    {"native_get_partial_object_64", "(IJJ[B)I",
                                        (void *)android_mtp_MtpDevice_get_partial_object_64},
    {"native_get_thumbnail",    "(I)[B",(void *)android_mtp_MtpDevice_get_thumbnail},
    {"native_delete_object",    "(I)Z", (void *)android_mtp_MtpDevice_delete_object},
    {"native_get_parent",       "(I)I", (void *)android_mtp_MtpDevice_get_parent},
    {"native_get_storage_id",   "(I)I", (void *)android_mtp_MtpDevice_get_storage_id},
    {"native_import_file",      "(ILjava/lang/String;)Z",
                                        (void *)android_mtp_MtpDevice_import_file},
    {"native_import_file",      "(II)Z",(void *)android_mtp_MtpDevice_import_file_to_fd},
    {"native_send_object",      "(IJI)Z",(void *)android_mtp_MtpDevice_send_object},
    {"native_send_object_info", "(Landroid/mtp/MtpObjectInfo;)Landroid/mtp/MtpObjectInfo;",
                                        (void *)android_mtp_MtpDevice_send_object_info},
    {"native_submit_event_request",  "()I", (void *)android_mtp_MtpDevice_submit_event_request},
    {"native_reap_event_request",   "(I)Landroid/mtp/MtpEvent;",
                                            (void *)android_mtp_MtpDevice_reap_event_request},
    {"native_discard_event_request", "(I)V", (void *)android_mtp_MtpDevice_discard_event_request},

    {"native_get_object_size_long", "(II)J", (void *)android_mtp_MtpDevice_get_object_size_long},
};

int register_android_mtp_MtpDevice(JNIEnv *env)
{
    jclass clazz;

    ALOGD("register_android_mtp_MtpDevice\n");

    clazz = env->FindClass("android/mtp/MtpDeviceInfo");
    if (clazz == NULL) {
        ALOGE("Can't find android/mtp/MtpDeviceInfo");
        return -1;
    }
    constructor_deviceInfo = env->GetMethodID(clazz, "<init>", "()V");
    if (constructor_deviceInfo == NULL) {
        ALOGE("Can't find android/mtp/MtpDeviceInfo constructor");
        return -1;
    }
    field_deviceInfo_manufacturer = env->GetFieldID(clazz, "mManufacturer", "Ljava/lang/String;");
    if (field_deviceInfo_manufacturer == NULL) {
        ALOGE("Can't find MtpDeviceInfo.mManufacturer");
        return -1;
    }
    field_deviceInfo_model = env->GetFieldID(clazz, "mModel", "Ljava/lang/String;");
    if (field_deviceInfo_model == NULL) {
        ALOGE("Can't find MtpDeviceInfo.mModel");
        return -1;
    }
    field_deviceInfo_version = env->GetFieldID(clazz, "mVersion", "Ljava/lang/String;");
    if (field_deviceInfo_version == NULL) {
        ALOGE("Can't find MtpDeviceInfo.mVersion");
        return -1;
    }
    field_deviceInfo_serialNumber = env->GetFieldID(clazz, "mSerialNumber", "Ljava/lang/String;");
    if (field_deviceInfo_serialNumber == NULL) {
        ALOGE("Can't find MtpDeviceInfo.mSerialNumber");
        return -1;
    }
    field_deviceInfo_operationsSupported = env->GetFieldID(clazz, "mOperationsSupported", "[I");
    if (field_deviceInfo_operationsSupported == NULL) {
        ALOGE("Can't find MtpDeviceInfo.mOperationsSupported");
        return -1;
    }
    field_deviceInfo_eventsSupported = env->GetFieldID(clazz, "mEventsSupported", "[I");
    if (field_deviceInfo_eventsSupported == NULL) {
        ALOGE("Can't find MtpDeviceInfo.mEventsSupported");
        return -1;
    }
    clazz_deviceInfo = (jclass)env->NewGlobalRef(clazz);

    clazz = env->FindClass("android/mtp/MtpStorageInfo");
    if (clazz == NULL) {
        ALOGE("Can't find android/mtp/MtpStorageInfo");
        return -1;
    }
    constructor_storageInfo = env->GetMethodID(clazz, "<init>", "()V");
    if (constructor_storageInfo == NULL) {
        ALOGE("Can't find android/mtp/MtpStorageInfo constructor");
        return -1;
    }
    field_storageInfo_storageId = env->GetFieldID(clazz, "mStorageId", "I");
    if (field_storageInfo_storageId == NULL) {
        ALOGE("Can't find MtpStorageInfo.mStorageId");
        return -1;
    }
    field_storageInfo_maxCapacity = env->GetFieldID(clazz, "mMaxCapacity", "J");
    if (field_storageInfo_maxCapacity == NULL) {
        ALOGE("Can't find MtpStorageInfo.mMaxCapacity");
        return -1;
    }
    field_storageInfo_freeSpace = env->GetFieldID(clazz, "mFreeSpace", "J");
    if (field_storageInfo_freeSpace == NULL) {
        ALOGE("Can't find MtpStorageInfo.mFreeSpace");
        return -1;
    }
    field_storageInfo_description = env->GetFieldID(clazz, "mDescription", "Ljava/lang/String;");
    if (field_storageInfo_description == NULL) {
        ALOGE("Can't find MtpStorageInfo.mDescription");
        return -1;
    }
    field_storageInfo_volumeIdentifier = env->GetFieldID(clazz, "mVolumeIdentifier", "Ljava/lang/String;");
    if (field_storageInfo_volumeIdentifier == NULL) {
        ALOGE("Can't find MtpStorageInfo.mVolumeIdentifier");
        return -1;
    }
    clazz_storageInfo = (jclass)env->NewGlobalRef(clazz);

    clazz = env->FindClass("android/mtp/MtpObjectInfo");
    if (clazz == NULL) {
        ALOGE("Can't find android/mtp/MtpObjectInfo");
        return -1;
    }
    constructor_objectInfo = env->GetMethodID(clazz, "<init>", "()V");
    if (constructor_objectInfo == NULL) {
        ALOGE("Can't find android/mtp/MtpObjectInfo constructor");
        return -1;
    }
    field_objectInfo_handle = env->GetFieldID(clazz, "mHandle", "I");
    if (field_objectInfo_handle == NULL) {
        ALOGE("Can't find MtpObjectInfo.mHandle");
        return -1;
    }
    field_objectInfo_storageId = env->GetFieldID(clazz, "mStorageId", "I");
    if (field_objectInfo_storageId == NULL) {
        ALOGE("Can't find MtpObjectInfo.mStorageId");
        return -1;
    }
    field_objectInfo_format = env->GetFieldID(clazz, "mFormat", "I");
    if (field_objectInfo_format == NULL) {
        ALOGE("Can't find MtpObjectInfo.mFormat");
        return -1;
    }
    field_objectInfo_protectionStatus = env->GetFieldID(clazz, "mProtectionStatus", "I");
    if (field_objectInfo_protectionStatus == NULL) {
        ALOGE("Can't find MtpObjectInfo.mProtectionStatus");
        return -1;
    }
    field_objectInfo_compressedSize = env->GetFieldID(clazz, "mCompressedSize", "I");
    if (field_objectInfo_compressedSize == NULL) {
        ALOGE("Can't find MtpObjectInfo.mCompressedSize");
        return -1;
    }
    field_objectInfo_thumbFormat = env->GetFieldID(clazz, "mThumbFormat", "I");
    if (field_objectInfo_thumbFormat == NULL) {
        ALOGE("Can't find MtpObjectInfo.mThumbFormat");
        return -1;
    }
    field_objectInfo_thumbCompressedSize = env->GetFieldID(clazz, "mThumbCompressedSize", "I");
    if (field_objectInfo_thumbCompressedSize == NULL) {
        ALOGE("Can't find MtpObjectInfo.mThumbCompressedSize");
        return -1;
    }
    field_objectInfo_thumbPixWidth = env->GetFieldID(clazz, "mThumbPixWidth", "I");
    if (field_objectInfo_thumbPixWidth == NULL) {
        ALOGE("Can't find MtpObjectInfo.mThumbPixWidth");
        return -1;
    }
    field_objectInfo_thumbPixHeight = env->GetFieldID(clazz, "mThumbPixHeight", "I");
    if (field_objectInfo_thumbPixHeight == NULL) {
        ALOGE("Can't find MtpObjectInfo.mThumbPixHeight");
        return -1;
    }
    field_objectInfo_imagePixWidth = env->GetFieldID(clazz, "mImagePixWidth", "I");
    if (field_objectInfo_imagePixWidth == NULL) {
        ALOGE("Can't find MtpObjectInfo.mImagePixWidth");
        return -1;
    }
    field_objectInfo_imagePixHeight = env->GetFieldID(clazz, "mImagePixHeight", "I");
    if (field_objectInfo_imagePixHeight == NULL) {
        ALOGE("Can't find MtpObjectInfo.mImagePixHeight");
        return -1;
    }
    field_objectInfo_imagePixDepth = env->GetFieldID(clazz, "mImagePixDepth", "I");
    if (field_objectInfo_imagePixDepth == NULL) {
        ALOGE("Can't find MtpObjectInfo.mImagePixDepth");
        return -1;
    }
    field_objectInfo_parent = env->GetFieldID(clazz, "mParent", "I");
    if (field_objectInfo_parent == NULL) {
        ALOGE("Can't find MtpObjectInfo.mParent");
        return -1;
    }
    field_objectInfo_associationType = env->GetFieldID(clazz, "mAssociationType", "I");
    if (field_objectInfo_associationType == NULL) {
        ALOGE("Can't find MtpObjectInfo.mAssociationType");
        return -1;
    }
    field_objectInfo_associationDesc = env->GetFieldID(clazz, "mAssociationDesc", "I");
    if (field_objectInfo_associationDesc == NULL) {
        ALOGE("Can't find MtpObjectInfo.mAssociationDesc");
        return -1;
    }
    field_objectInfo_sequenceNumber = env->GetFieldID(clazz, "mSequenceNumber", "I");
    if (field_objectInfo_sequenceNumber == NULL) {
        ALOGE("Can't find MtpObjectInfo.mSequenceNumber");
        return -1;
    }
    field_objectInfo_name = env->GetFieldID(clazz, "mName", "Ljava/lang/String;");
    if (field_objectInfo_name == NULL) {
        ALOGE("Can't find MtpObjectInfo.mName");
        return -1;
    }
    field_objectInfo_dateCreated = env->GetFieldID(clazz, "mDateCreated", "J");
    if (field_objectInfo_dateCreated == NULL) {
        ALOGE("Can't find MtpObjectInfo.mDateCreated");
        return -1;
    }
    field_objectInfo_dateModified = env->GetFieldID(clazz, "mDateModified", "J");
    if (field_objectInfo_dateModified == NULL) {
        ALOGE("Can't find MtpObjectInfo.mDateModified");
        return -1;
    }
    field_objectInfo_keywords = env->GetFieldID(clazz, "mKeywords", "Ljava/lang/String;");
    if (field_objectInfo_keywords == NULL) {
        ALOGE("Can't find MtpObjectInfo.mKeywords");
        return -1;
    }
    clazz_objectInfo = (jclass)env->NewGlobalRef(clazz);

    clazz = env->FindClass("android/mtp/MtpEvent");
    if (clazz == NULL) {
        ALOGE("Can't find android/mtp/MtpEvent");
        return -1;
    }
    constructor_event = env->GetMethodID(clazz, "<init>", "()V");
    if (constructor_event == NULL) {
        ALOGE("Can't find android/mtp/MtpEvent constructor");
        return -1;
    }
    field_event_eventCode = env->GetFieldID(clazz, "mEventCode", "I");
    if (field_event_eventCode == NULL) {
        ALOGE("Can't find MtpObjectInfo.mEventCode");
        return -1;
    }
    field_event_parameter1 = env->GetFieldID(clazz, "mParameter1", "I");
    if (field_event_parameter1 == NULL) {
        ALOGE("Can't find MtpObjectInfo.mParameter1");
        return -1;
    }
    field_event_parameter2 = env->GetFieldID(clazz, "mParameter2", "I");
    if (field_event_parameter2 == NULL) {
        ALOGE("Can't find MtpObjectInfo.mParameter2");
        return -1;
    }
    field_event_parameter3 = env->GetFieldID(clazz, "mParameter3", "I");
    if (field_event_parameter3 == NULL) {
        ALOGE("Can't find MtpObjectInfo.mParameter3");
        return -1;
    }
    clazz_event = (jclass)env->NewGlobalRef(clazz);

    clazz = env->FindClass("android/mtp/MtpDevice");
    if (clazz == NULL) {
        ALOGE("Can't find android/mtp/MtpDevice");
        return -1;
    }
    field_context = env->GetFieldID(clazz, "mNativeContext", "J");
    if (field_context == NULL) {
        ALOGE("Can't find MtpDevice.mNativeContext");
        return -1;
    }
    clazz = env->FindClass("java/io/IOException");
    if (clazz == NULL) {
        ALOGE("Can't find java.io.IOException");
        return -1;
    }
    clazz_io_exception = (jclass)env->NewGlobalRef(clazz);
    clazz = env->FindClass("android/os/OperationCanceledException");
    if (clazz == NULL) {
        ALOGE("Can't find android.os.OperationCanceledException");
        return -1;
    }
    clazz_operation_canceled_exception = (jclass)env->NewGlobalRef(clazz);

    return AndroidRuntime::registerNativeMethods(env,
                "android/mtp/MtpDevice", gMethods, NELEM(gMethods));
}
