/*
 * 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 "MtpDatabaseJNI"
#include "utils/Log.h"
#include "utils/String8.h"

#include "android_media_Streams.h"
#include "mtp.h"
#include "IMtpDatabase.h"
#include "MtpDataPacket.h"
#include "MtpObjectInfo.h"
#include "MtpProperty.h"
#include "MtpStringBuffer.h"
#include "MtpUtils.h"

#include "src/piex_types.h"
#include "src/piex.h"

#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
#include "core_jni_helpers.h"
#include <jni.h>
#include <media/stagefright/NuMediaExtractor.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>

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

using namespace android;

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

// MtpDatabase methods
static jmethodID method_beginSendObject;
static jmethodID method_endSendObject;
static jmethodID method_rescanFile;
static jmethodID method_getObjectList;
static jmethodID method_getNumObjects;
static jmethodID method_getSupportedPlaybackFormats;
static jmethodID method_getSupportedCaptureFormats;
static jmethodID method_getSupportedObjectProperties;
static jmethodID method_getSupportedDeviceProperties;
static jmethodID method_setObjectProperty;
static jmethodID method_getDeviceProperty;
static jmethodID method_setDeviceProperty;
static jmethodID method_getObjectPropertyList;
static jmethodID method_getObjectInfo;
static jmethodID method_getObjectFilePath;
static jmethodID method_openFilePath;
static jmethodID method_getThumbnailInfo;
static jmethodID method_getThumbnailData;
static jmethodID method_beginDeleteObject;
static jmethodID method_endDeleteObject;
static jmethodID method_beginMoveObject;
static jmethodID method_endMoveObject;
static jmethodID method_beginCopyObject;
static jmethodID method_endCopyObject;
static jmethodID method_getObjectReferences;
static jmethodID method_setObjectReferences;

// MtpDatabase fields.
static jfieldID field_context;

// MtpPropertyList methods
static jmethodID method_getCode;
static jmethodID method_getCount;
static jmethodID method_getObjectHandles;
static jmethodID method_getPropertyCodes;
static jmethodID method_getDataTypes;
static jmethodID method_getLongValues;
static jmethodID method_getStringValues;

// Initializer for the jfieldIDs and jmethodIDs above. This method must be invoked
// before using these static fields and methods for JNI accesses.
static void initializeJavaIDs(JNIEnv* env) {
    static std::once_flag sJniInitialized;

#define GET_METHOD_ID(name, jclass, signature)                              \
    method_##name = GetMethodIDOrDie(env, jclass, #name, signature);

    std::call_once(sJniInitialized, [](JNIEnv* env) {
        const jclass mdb_class = FindClassOrDie(env, "android/mtp/MtpDatabase");
        GET_METHOD_ID(beginSendObject, mdb_class, "(Ljava/lang/String;III)I");
        GET_METHOD_ID(endSendObject, mdb_class, "(IZ)V");
        GET_METHOD_ID(rescanFile, mdb_class, "(Ljava/lang/String;II)V");
        GET_METHOD_ID(getObjectList, mdb_class, "(III)[I");
        GET_METHOD_ID(getNumObjects, mdb_class, "(III)I");
        GET_METHOD_ID(getSupportedPlaybackFormats, mdb_class, "()[I");
        GET_METHOD_ID(getSupportedCaptureFormats, mdb_class, "()[I");
        GET_METHOD_ID(getSupportedObjectProperties, mdb_class, "(I)[I");
        GET_METHOD_ID(getSupportedDeviceProperties, mdb_class, "()[I");
        GET_METHOD_ID(setObjectProperty, mdb_class, "(IIJLjava/lang/String;)I");
        GET_METHOD_ID(getDeviceProperty, mdb_class, "(I[J[C)I");
        GET_METHOD_ID(setDeviceProperty, mdb_class, "(IJLjava/lang/String;)I");
        GET_METHOD_ID(getObjectPropertyList, mdb_class, "(IIIII)Landroid/mtp/MtpPropertyList;");
        GET_METHOD_ID(getObjectInfo, mdb_class, "(I[I[C[J)Z");
        GET_METHOD_ID(getObjectFilePath, mdb_class, "(I[C[J)I");
        GET_METHOD_ID(openFilePath, mdb_class, "(Ljava/lang/String;Z)I");
        GET_METHOD_ID(getThumbnailInfo, mdb_class, "(I[J)Z");
        GET_METHOD_ID(getThumbnailData, mdb_class, "(I)[B");
        GET_METHOD_ID(beginDeleteObject, mdb_class, "(I)I");
        GET_METHOD_ID(endDeleteObject, mdb_class, "(IZ)V");
        GET_METHOD_ID(beginMoveObject, mdb_class, "(III)I");
        GET_METHOD_ID(endMoveObject, mdb_class, "(IIIIIZ)V");
        GET_METHOD_ID(beginCopyObject, mdb_class, "(III)I");
        GET_METHOD_ID(endCopyObject, mdb_class, "(IZ)V");
        GET_METHOD_ID(getObjectReferences, mdb_class, "(I)[I");
        GET_METHOD_ID(setObjectReferences, mdb_class, "(I[I)I");
        field_context = GetFieldIDOrDie(env, mdb_class, "mNativeContext", "J");

        const jclass mpl_class = FindClassOrDie(env, "android/mtp/MtpPropertyList");
        GET_METHOD_ID(getCode, mpl_class, "()I");
        GET_METHOD_ID(getCount, mpl_class, "()I");
        GET_METHOD_ID(getObjectHandles, mpl_class, "()[I");
        GET_METHOD_ID(getPropertyCodes, mpl_class, "()[I");
        GET_METHOD_ID(getDataTypes, mpl_class, "()[I");
        GET_METHOD_ID(getLongValues, mpl_class, "()[J");
        GET_METHOD_ID(getStringValues, mpl_class, "()[Ljava/lang/String;");

        return 0;
    }, env);

#undef GET_METHOD_ID
}


IMtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
    return (IMtpDatabase *)env->GetLongField(database, field_context);
}

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

class MtpDatabase : public IMtpDatabase {
private:
    jobject         mDatabase;
    jintArray       mIntBuffer;
    jlongArray      mLongBuffer;
    jcharArray      mStringBuffer;

public:
                                    MtpDatabase(JNIEnv *env, jobject client);
    virtual                         ~MtpDatabase();
    void                            cleanup(JNIEnv *env);

    virtual MtpObjectHandle         beginSendObject(const char* path,
                                            MtpObjectFormat format,
                                            MtpObjectHandle parent,
                                            MtpStorageID storage);

    virtual void                    endSendObject(MtpObjectHandle handle, bool succeeded);

    virtual void                    rescanFile(const char* path,
                                            MtpObjectHandle handle,
                                            MtpObjectFormat format);

    virtual MtpObjectHandleList*    getObjectList(MtpStorageID storageID,
                                    MtpObjectFormat format,
                                    MtpObjectHandle parent);

    virtual int                     getNumObjects(MtpStorageID storageID,
                                            MtpObjectFormat format,
                                            MtpObjectHandle parent);

    // callee should delete[] the results from these
    // results can be NULL
    virtual MtpObjectFormatList*    getSupportedPlaybackFormats();
    virtual MtpObjectFormatList*    getSupportedCaptureFormats();
    virtual MtpObjectPropertyList*  getSupportedObjectProperties(MtpObjectFormat format);
    virtual MtpDevicePropertyList*  getSupportedDeviceProperties();

    virtual MtpResponseCode         getObjectPropertyValue(MtpObjectHandle handle,
                                            MtpObjectProperty property,
                                            MtpDataPacket& packet);

    virtual MtpResponseCode         setObjectPropertyValue(MtpObjectHandle handle,
                                            MtpObjectProperty property,
                                            MtpDataPacket& packet);

    virtual MtpResponseCode         getDevicePropertyValue(MtpDeviceProperty property,
                                            MtpDataPacket& packet);

    virtual MtpResponseCode         setDevicePropertyValue(MtpDeviceProperty property,
                                            MtpDataPacket& packet);

    virtual MtpResponseCode         resetDeviceProperty(MtpDeviceProperty property);

    virtual MtpResponseCode         getObjectPropertyList(MtpObjectHandle handle,
                                            uint32_t format, uint32_t property,
                                            int groupCode, int depth,
                                            MtpDataPacket& packet);

    virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
                                            MtpObjectInfo& info);

    virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);

    virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
                                            MtpStringBuffer& outFilePath,
                                            int64_t& outFileLength,
                                            MtpObjectFormat& outFormat);
    virtual int                     openFilePath(const char* path, bool transcode);
    virtual MtpResponseCode         beginDeleteObject(MtpObjectHandle handle);
    virtual void                    endDeleteObject(MtpObjectHandle handle, bool succeeded);

    bool                            getObjectPropertyInfo(MtpObjectProperty property, int& type);
    bool                            getDevicePropertyInfo(MtpDeviceProperty property, int& type);

    virtual MtpObjectHandleList*    getObjectReferences(MtpObjectHandle handle);

    virtual MtpResponseCode         setObjectReferences(MtpObjectHandle handle,
                                            MtpObjectHandleList* references);

    virtual MtpProperty*            getObjectPropertyDesc(MtpObjectProperty property,
                                            MtpObjectFormat format);

    virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property);

    virtual MtpResponseCode         beginMoveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
                                            MtpStorageID newStorage);

    virtual void                    endMoveObject(MtpObjectHandle oldParent, MtpObjectHandle newParent,
                                            MtpStorageID oldStorage, MtpStorageID newStorage,
                                             MtpObjectHandle handle, bool succeeded);

    virtual MtpResponseCode         beginCopyObject(MtpObjectHandle handle, MtpObjectHandle newParent,
                                            MtpStorageID newStorage);
    virtual void                    endCopyObject(MtpObjectHandle handle, bool succeeded);

};

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

static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
    if (env->ExceptionCheck()) {
        ALOGE("An exception was thrown by callback '%s'.", methodName);
        LOGE_EX(env);
        env->ExceptionClear();
    }
}

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

MtpDatabase::MtpDatabase(JNIEnv *env, jobject client)
    :   mDatabase(env->NewGlobalRef(client)),
        mIntBuffer(NULL),
        mLongBuffer(NULL),
        mStringBuffer(NULL)
{
    // create buffers for out arguments
    // we don't need to be thread-safe so this is OK
    jintArray intArray = env->NewIntArray(3);
    if (!intArray) {
        return; // Already threw.
    }
    mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
    jlongArray longArray = env->NewLongArray(3);
    if (!longArray) {
        return; // Already threw.
    }
    mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
    // Needs to be long enough to hold a file path for getObjectFilePath()
    jcharArray charArray = env->NewCharArray(PATH_MAX + 1);
    if (!charArray) {
        return; // Already threw.
    }
    mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
}

void MtpDatabase::cleanup(JNIEnv *env) {
    env->DeleteGlobalRef(mDatabase);
    env->DeleteGlobalRef(mIntBuffer);
    env->DeleteGlobalRef(mLongBuffer);
    env->DeleteGlobalRef(mStringBuffer);
}

MtpDatabase::~MtpDatabase() {
}

MtpObjectHandle MtpDatabase::beginSendObject(const char* path,
                                               MtpObjectFormat format,
                                               MtpObjectHandle parent,
                                               MtpStorageID storage) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jstring pathStr = env->NewStringUTF(path);
    MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
            pathStr, (jint)format, (jint)parent, (jint)storage);

    if (pathStr)
        env->DeleteLocalRef(pathStr);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

void MtpDatabase::endSendObject(MtpObjectHandle handle, bool succeeded) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    env->CallVoidMethod(mDatabase, method_endSendObject, (jint)handle, (jboolean)succeeded);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

void MtpDatabase::rescanFile(const char* path, MtpObjectHandle handle,
                                  MtpObjectFormat format) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jstring pathStr = env->NewStringUTF(path);
    env->CallVoidMethod(mDatabase, method_rescanFile, pathStr,
                        (jint)handle, (jint)format);

    if (pathStr)
        env->DeleteLocalRef(pathStr);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

MtpObjectHandleList* MtpDatabase::getObjectList(MtpStorageID storageID,
                                                  MtpObjectFormat format,
                                                  MtpObjectHandle parent) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
                (jint)storageID, (jint)format, (jint)parent);
    if (!array)
        return NULL;
    MtpObjectHandleList* list = new MtpObjectHandleList();
    jint* handles = env->GetIntArrayElements(array, 0);
    jsize length = env->GetArrayLength(array);
    for (int i = 0; i < length; i++)
        list->push_back(handles[i]);
    env->ReleaseIntArrayElements(array, handles, 0);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return list;
}

int MtpDatabase::getNumObjects(MtpStorageID storageID,
                                 MtpObjectFormat format,
                                 MtpObjectHandle parent) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    int result = env->CallIntMethod(mDatabase, method_getNumObjects,
                (jint)storageID, (jint)format, (jint)parent);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

MtpObjectFormatList* MtpDatabase::getSupportedPlaybackFormats() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
            method_getSupportedPlaybackFormats);
    if (!array)
        return NULL;
    MtpObjectFormatList* list = new MtpObjectFormatList();
    jint* formats = env->GetIntArrayElements(array, 0);
    jsize length = env->GetArrayLength(array);
    for (int i = 0; i < length; i++)
        list->push_back(formats[i]);
    env->ReleaseIntArrayElements(array, formats, 0);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return list;
}

MtpObjectFormatList* MtpDatabase::getSupportedCaptureFormats() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
            method_getSupportedCaptureFormats);
    if (!array)
        return NULL;
    MtpObjectFormatList* list = new MtpObjectFormatList();
    jint* formats = env->GetIntArrayElements(array, 0);
    jsize length = env->GetArrayLength(array);
    for (int i = 0; i < length; i++)
        list->push_back(formats[i]);
    env->ReleaseIntArrayElements(array, formats, 0);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return list;
}

MtpObjectPropertyList* MtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
            method_getSupportedObjectProperties, (jint)format);
    if (!array)
        return NULL;
    MtpObjectPropertyList* list = new MtpObjectPropertyList();
    jint* properties = env->GetIntArrayElements(array, 0);
    jsize length = env->GetArrayLength(array);
    for (int i = 0; i < length; i++)
        list->push_back(properties[i]);
    env->ReleaseIntArrayElements(array, properties, 0);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return list;
}

MtpDevicePropertyList* MtpDatabase::getSupportedDeviceProperties() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
            method_getSupportedDeviceProperties);
    if (!array)
        return NULL;
    MtpDevicePropertyList* list = new MtpDevicePropertyList();
    jint* properties = env->GetIntArrayElements(array, 0);
    jsize length = env->GetArrayLength(array);
    for (int i = 0; i < length; i++)
        list->push_back(properties[i]);
    env->ReleaseIntArrayElements(array, properties, 0);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return list;
}

MtpResponseCode MtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
                                                      MtpObjectProperty property,
                                                      MtpDataPacket& packet) {
    static_assert(sizeof(jint) >= sizeof(MtpObjectHandle),
                  "Casting MtpObjectHandle to jint loses a value");
    static_assert(sizeof(jint) >= sizeof(MtpObjectProperty),
                  "Casting MtpObjectProperty to jint loses a value");
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jobject list = env->CallObjectMethod(
            mDatabase,
            method_getObjectPropertyList,
            static_cast<jint>(handle),
            0,
            static_cast<jint>(property),
            0,
            0);
    MtpResponseCode result = env->CallIntMethod(list, method_getCode);
    jint count = env->CallIntMethod(list, method_getCount);
    if (count != 1)
        result = MTP_RESPONSE_GENERAL_ERROR;

    if (result == MTP_RESPONSE_OK) {
        jintArray objectHandlesArray = (jintArray)env->CallObjectMethod(list, method_getObjectHandles);
        jintArray propertyCodesArray = (jintArray)env->CallObjectMethod(list, method_getPropertyCodes);
        jintArray dataTypesArray = (jintArray)env->CallObjectMethod(list, method_getDataTypes);
        jlongArray longValuesArray = (jlongArray)env->CallObjectMethod(list, method_getLongValues);
        jobjectArray stringValuesArray = (jobjectArray)env->CallObjectMethod(list, method_getStringValues);

        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
        jlong* longValues = env->GetLongArrayElements(longValuesArray, 0);

        int type = dataTypes[0];
        jlong longValue = (longValues ? longValues[0] : 0);

        switch (type) {
            case MTP_TYPE_INT8:
                packet.putInt8(longValue);
                break;
            case MTP_TYPE_UINT8:
                packet.putUInt8(longValue);
                break;
            case MTP_TYPE_INT16:
                packet.putInt16(longValue);
                break;
            case MTP_TYPE_UINT16:
                packet.putUInt16(longValue);
                break;
            case MTP_TYPE_INT32:
                packet.putInt32(longValue);
                break;
            case MTP_TYPE_UINT32:
                packet.putUInt32(longValue);
                break;
            case MTP_TYPE_INT64:
                packet.putInt64(longValue);
                break;
            case MTP_TYPE_UINT64:
                packet.putUInt64(longValue);
                break;
            case MTP_TYPE_INT128:
                packet.putInt128(longValue);
                break;
            case MTP_TYPE_UINT128:
                packet.putUInt128(longValue);
                break;
            case MTP_TYPE_STR:
            {
                jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
                const char* str = (stringValue ? env->GetStringUTFChars(stringValue, NULL) : NULL);
                if (stringValue) {
                    packet.putString(str);
                    env->ReleaseStringUTFChars(stringValue, str);
                } else {
                    packet.putEmptyString();
                }
                env->DeleteLocalRef(stringValue);
                break;
             }
            default:
                ALOGE("unsupported type in getObjectPropertyValue\n");
                result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
        }
        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
        env->ReleaseLongArrayElements(longValuesArray, longValues, 0);

        env->DeleteLocalRef(objectHandlesArray);
        env->DeleteLocalRef(propertyCodesArray);
        env->DeleteLocalRef(dataTypesArray);
        env->DeleteLocalRef(longValuesArray);
        env->DeleteLocalRef(stringValuesArray);
    }

    env->DeleteLocalRef(list);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

static bool readLongValue(int type, MtpDataPacket& packet, jlong& longValue) {
    switch (type) {
        case MTP_TYPE_INT8: {
            int8_t temp;
            if (!packet.getInt8(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_UINT8: {
            uint8_t temp;
            if (!packet.getUInt8(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_INT16: {
            int16_t temp;
            if (!packet.getInt16(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_UINT16: {
            uint16_t temp;
            if (!packet.getUInt16(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_INT32: {
            int32_t temp;
            if (!packet.getInt32(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_UINT32: {
            uint32_t temp;
            if (!packet.getUInt32(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_INT64: {
            int64_t temp;
            if (!packet.getInt64(temp)) return false;
            longValue = temp;
            break;
        }
        case MTP_TYPE_UINT64: {
            uint64_t temp;
            if (!packet.getUInt64(temp)) return false;
            longValue = temp;
            break;
        }
        default:
            ALOGE("unsupported type in readLongValue");
            return false;
    }
    return true;
}

MtpResponseCode MtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
                                                      MtpObjectProperty property,
                                                      MtpDataPacket& packet) {
    int         type;

    if (!getObjectPropertyInfo(property, type))
        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jlong longValue = 0;
    jstring stringValue = NULL;
    MtpResponseCode result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;

    if (type == MTP_TYPE_STR) {
        MtpStringBuffer buffer;
        if (!packet.getString(buffer)) goto fail;
        stringValue = env->NewStringUTF((const char *)buffer);
    } else {
        if (!readLongValue(type, packet, longValue)) goto fail;
    }

    result = env->CallIntMethod(mDatabase, method_setObjectProperty,
                (jint)handle, (jint)property, longValue, stringValue);
    if (stringValue)
        env->DeleteLocalRef(stringValue);

fail:
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

MtpResponseCode MtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
                                                      MtpDataPacket& packet) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    int type;

    if (!getDevicePropertyInfo(property, type))
        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;

    jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
                (jint)property, mLongBuffer, mStringBuffer);
    if (result != MTP_RESPONSE_OK) {
        checkAndClearExceptionFromCallback(env, __FUNCTION__);
        return result;
    }

    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
    jlong longValue = longValues[0];
    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);

    switch (type) {
        case MTP_TYPE_INT8:
            packet.putInt8(longValue);
            break;
        case MTP_TYPE_UINT8:
            packet.putUInt8(longValue);
            break;
        case MTP_TYPE_INT16:
            packet.putInt16(longValue);
            break;
        case MTP_TYPE_UINT16:
            packet.putUInt16(longValue);
            break;
        case MTP_TYPE_INT32:
            packet.putInt32(longValue);
            break;
        case MTP_TYPE_UINT32:
            packet.putUInt32(longValue);
            break;
        case MTP_TYPE_INT64:
            packet.putInt64(longValue);
            break;
        case MTP_TYPE_UINT64:
            packet.putUInt64(longValue);
            break;
        case MTP_TYPE_INT128:
            packet.putInt128(longValue);
            break;
        case MTP_TYPE_UINT128:
            packet.putInt128(longValue);
            break;
        case MTP_TYPE_STR:
        {
            jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
            packet.putString(str);
            env->ReleaseCharArrayElements(mStringBuffer, str, 0);
            break;
        }
        default:
            ALOGE("unsupported type in getDevicePropertyValue\n");
            return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
    }

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return MTP_RESPONSE_OK;
}

MtpResponseCode MtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
                                                      MtpDataPacket& packet) {
    int         type;

    if (!getDevicePropertyInfo(property, type))
        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jlong longValue = 0;
    jstring stringValue = NULL;
    MtpResponseCode result = MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;

    if (type == MTP_TYPE_STR) {
        MtpStringBuffer buffer;
        if (!packet.getString(buffer)) goto fail;
        stringValue = env->NewStringUTF((const char *)buffer);
    } else {
        if (!readLongValue(type, packet, longValue)) goto fail;
    }

    result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
                (jint)property, longValue, stringValue);
    if (stringValue)
        env->DeleteLocalRef(stringValue);

fail:
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

MtpResponseCode MtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) {
    return -1;
}

MtpResponseCode MtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
                                                     uint32_t format, uint32_t property,
                                                     int groupCode, int depth,
                                                     MtpDataPacket& packet) {
    static_assert(sizeof(jint) >= sizeof(MtpObjectHandle),
                  "Casting MtpObjectHandle to jint loses a value");
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jobject list = env->CallObjectMethod(
            mDatabase,
            method_getObjectPropertyList,
            static_cast<jint>(handle),
            static_cast<jint>(format),
            static_cast<jint>(property),
            static_cast<jint>(groupCode),
            static_cast<jint>(depth));
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    if (!list)
        return MTP_RESPONSE_GENERAL_ERROR;
    int count = env->CallIntMethod(list, method_getCount);
    MtpResponseCode result = env->CallIntMethod(list, method_getCode);

    packet.putUInt32(count);
    if (count > 0) {
        jintArray objectHandlesArray = (jintArray)env->CallObjectMethod(list, method_getObjectHandles);
        jintArray propertyCodesArray = (jintArray)env->CallObjectMethod(list, method_getPropertyCodes);
        jintArray dataTypesArray = (jintArray)env->CallObjectMethod(list, method_getDataTypes);
        jlongArray longValuesArray = (jlongArray)env->CallObjectMethod(list, method_getLongValues);
        jobjectArray stringValuesArray = (jobjectArray)env->CallObjectMethod(list, method_getStringValues);

        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);

        for (int i = 0; i < count; i++) {
            packet.putUInt32(objectHandles[i]);
            packet.putUInt16(propertyCodes[i]);
            int type = dataTypes[i];
            packet.putUInt16(type);

            if (type == MTP_TYPE_STR) {
                jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
                const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
                if (valueStr) {
                    packet.putString(valueStr);
                    env->ReleaseStringUTFChars(value, valueStr);
                } else {
                    packet.putEmptyString();
                }
                env->DeleteLocalRef(value);
                continue;
            }

            if (!longValues) {
                ALOGE("bad longValuesArray value in MyMtpDatabase::getObjectPropertyList");
                continue;
            }

            switch (type) {
                case MTP_TYPE_INT8:
                    packet.putInt8(longValues[i]);
                    break;
                case MTP_TYPE_UINT8:
                    packet.putUInt8(longValues[i]);
                    break;
                case MTP_TYPE_INT16:
                    packet.putInt16(longValues[i]);
                    break;
                case MTP_TYPE_UINT16:
                    packet.putUInt16(longValues[i]);
                    break;
                case MTP_TYPE_INT32:
                    packet.putInt32(longValues[i]);
                    break;
                case MTP_TYPE_UINT32:
                    packet.putUInt32(longValues[i]);
                    break;
                case MTP_TYPE_INT64:
                    packet.putInt64(longValues[i]);
                    break;
                case MTP_TYPE_UINT64:
                    packet.putUInt64(longValues[i]);
                    break;
                case MTP_TYPE_INT128:
                    packet.putInt128(longValues[i]);
                    break;
                case MTP_TYPE_UINT128:
                    packet.putUInt128(longValues[i]);
                    break;
                default:
                    ALOGE("bad or unsupported data type in MtpDatabase::getObjectPropertyList");
                    break;
            }
        }

        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
        env->ReleaseLongArrayElements(longValuesArray, longValues, 0);

        env->DeleteLocalRef(objectHandlesArray);
        env->DeleteLocalRef(propertyCodesArray);
        env->DeleteLocalRef(dataTypesArray);
        env->DeleteLocalRef(longValuesArray);
        env->DeleteLocalRef(stringValuesArray);
    }

    env->DeleteLocalRef(list);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle,
                                             MtpObjectInfo& info) {
    MtpStringBuffer path;
    int64_t         length;
    MtpObjectFormat format;

    MtpResponseCode result = getObjectFilePath(handle, path, length, format);
    if (result != MTP_RESPONSE_OK) {
        return result;
    }
    info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
                (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
    }

    jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
    info.mStorageID = intValues[0];
    info.mFormat = intValues[1];
    info.mParent = intValues[2];
    env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);

    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
    info.mDateCreated = longValues[0];
    info.mDateModified = longValues[1];
    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);

    if ((false)) {
        info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
                                MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
                                MTP_ASSOCIATION_TYPE_UNDEFINED);
    }
    info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;

    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
    MtpStringBuffer temp(str);
    info.mName = strdup(temp);
    env->ReleaseCharArrayElements(mStringBuffer, str, 0);

    // read EXIF data for thumbnail information
    switch (info.mFormat) {
        case MTP_FORMAT_EXIF_JPEG:
        case MTP_FORMAT_HEIF:
        case MTP_FORMAT_JFIF:
        case MTP_FORMAT_PNG:
        case MTP_FORMAT_BMP:
        case MTP_FORMAT_GIF: {
            env = AndroidRuntime::getJNIEnv();
            if (env->CallBooleanMethod(
                    mDatabase, method_getThumbnailInfo, (jint)handle, mLongBuffer)) {

                jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
                jlong size = longValues[0];
                jlong w = longValues[1];
                jlong h = longValues[2];
                if (size > 0 && size <= UINT32_MAX &&
                        w > 0 && w <= UINT32_MAX &&
                        h > 0 && h <= UINT32_MAX) {
                    info.mThumbCompressedSize = size;
                    info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
                    info.mImagePixWidth = w;
                    info.mImagePixHeight = h;
                }
                env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
            }
            break;
        }

        // Except DNG, all supported RAW image formats are not defined in PTP 1.2 specification.
        // Most of RAW image formats are based on TIFF or TIFF/EP. To render Fuji's RAF format,
        // it checks MTP_FORMAT_DEFINED case since it's designed as a custom format.
        case MTP_FORMAT_DNG:
        case MTP_FORMAT_TIFF:
        case MTP_FORMAT_TIFF_EP:
        case MTP_FORMAT_DEFINED: {
            String8 temp(path);
            std::unique_ptr<FileStream> stream(new FileStream(temp));
            piex::PreviewImageData image_data;
            if (!GetExifFromRawImage(stream.get(), temp, image_data)) {
                // Couldn't parse EXIF data from a image file via piex.
                break;
            }

            info.mThumbCompressedSize = image_data.thumbnail.length;
            info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
            info.mImagePixWidth = image_data.full_width;
            info.mImagePixHeight = image_data.full_height;

            break;
        }
    }

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return MTP_RESPONSE_OK;
}

void* MtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
    MtpStringBuffer path;
    int64_t length;
    MtpObjectFormat format;
    void* result = NULL;
    outThumbSize = 0;

    if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK) {
        switch (format) {
            case MTP_FORMAT_EXIF_JPEG:
            case MTP_FORMAT_HEIF:
            case MTP_FORMAT_JFIF:
            case MTP_FORMAT_PNG:
            case MTP_FORMAT_BMP:
            case MTP_FORMAT_GIF: {
                JNIEnv* env = AndroidRuntime::getJNIEnv();
                jbyteArray thumbData = (jbyteArray) env->CallObjectMethod(
                        mDatabase, method_getThumbnailData, (jint)handle);
                if (thumbData == NULL) {
                    return nullptr;
                }
                jsize thumbSize = env->GetArrayLength(thumbData);
                result = malloc(thumbSize);
                if (result) {
                    env->GetByteArrayRegion(thumbData, 0, thumbSize, (jbyte*)result);
                    outThumbSize = thumbSize;
                }
                env->DeleteLocalRef(thumbData);
                break;
            }

            // See the above comment on getObjectInfo() method.
            case MTP_FORMAT_DNG:
            case MTP_FORMAT_TIFF:
            case MTP_FORMAT_TIFF_EP:
            case MTP_FORMAT_DEFINED: {
                String8 temp(path);
                std::unique_ptr<FileStream> stream(new FileStream(temp));
                piex::PreviewImageData image_data;
                if (!GetExifFromRawImage(stream.get(), temp, image_data)) {
                    // Couldn't parse EXIF data from a image file via piex.
                    break;
                }

                if (image_data.thumbnail.length == 0
                        || image_data.thumbnail.format != ::piex::Image::kJpegCompressed) {
                    // No thumbnail or non jpeg thumbnail.
                    break;
                }

                result = malloc(image_data.thumbnail.length);
                if (result) {
                    piex::Error err = stream.get()->GetData(
                            image_data.thumbnail.offset,
                            image_data.thumbnail.length,
                            (std::uint8_t *)result);
                    if (err == piex::Error::kOk) {
                        outThumbSize = image_data.thumbnail.length;
                    } else {
                        free(result);
                        result = NULL;
                    }
                }
                break;
            }
        }
    }

    return result;
}

MtpResponseCode MtpDatabase::getObjectFilePath(MtpObjectHandle handle,
                                                 MtpStringBuffer& outFilePath,
                                                 int64_t& outFileLength,
                                                 MtpObjectFormat& outFormat) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
                (jint)handle, mStringBuffer, mLongBuffer);
    if (result != MTP_RESPONSE_OK) {
        checkAndClearExceptionFromCallback(env, __FUNCTION__);
        return result;
    }

    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
    outFilePath.set(str);
    env->ReleaseCharArrayElements(mStringBuffer, str, 0);

    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
    outFileLength = longValues[0];
    outFormat = longValues[1];
    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

int MtpDatabase::openFilePath(const char* path, bool transcode) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jstring pathStr = env->NewStringUTF(path);
    jint result = env->CallIntMethod(mDatabase, method_openFilePath, pathStr, transcode);

    if (result < 0) {
        checkAndClearExceptionFromCallback(env, __FUNCTION__);
    }
    return result;
}

MtpResponseCode MtpDatabase::beginDeleteObject(MtpObjectHandle handle) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    MtpResponseCode result = env->CallIntMethod(mDatabase, method_beginDeleteObject, (jint)handle);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

void MtpDatabase::endDeleteObject(MtpObjectHandle handle, bool succeeded) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    env->CallVoidMethod(mDatabase, method_endDeleteObject, (jint)handle, (jboolean) succeeded);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

MtpResponseCode MtpDatabase::beginMoveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
        MtpStorageID newStorage) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    MtpResponseCode result = env->CallIntMethod(mDatabase, method_beginMoveObject,
                (jint)handle, (jint)newParent, (jint) newStorage);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

void MtpDatabase::endMoveObject(MtpObjectHandle oldParent, MtpObjectHandle newParent,
                                            MtpStorageID oldStorage, MtpStorageID newStorage,
                                             MtpObjectHandle handle, bool succeeded) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    env->CallVoidMethod(mDatabase, method_endMoveObject,
                (jint)oldParent, (jint) newParent, (jint) oldStorage, (jint) newStorage,
                (jint) handle, (jboolean) succeeded);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

MtpResponseCode MtpDatabase::beginCopyObject(MtpObjectHandle handle, MtpObjectHandle newParent,
        MtpStorageID newStorage) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    MtpResponseCode result = env->CallIntMethod(mDatabase, method_beginCopyObject,
                (jint)handle, (jint)newParent, (jint) newStorage);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

void MtpDatabase::endCopyObject(MtpObjectHandle handle, bool succeeded) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    env->CallVoidMethod(mDatabase, method_endCopyObject, (jint)handle, (jboolean)succeeded);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}


struct PropertyTableEntry {
    MtpObjectProperty   property;
    int                 type;
};

static const PropertyTableEntry   kObjectPropertyTable[] = {
    {   MTP_PROPERTY_STORAGE_ID,        MTP_TYPE_UINT32     },
    {   MTP_PROPERTY_OBJECT_FORMAT,     MTP_TYPE_UINT16     },
    {   MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16     },
    {   MTP_PROPERTY_OBJECT_SIZE,       MTP_TYPE_UINT64     },
    {   MTP_PROPERTY_OBJECT_FILE_NAME,  MTP_TYPE_STR        },
    {   MTP_PROPERTY_DATE_MODIFIED,     MTP_TYPE_STR        },
    {   MTP_PROPERTY_PARENT_OBJECT,     MTP_TYPE_UINT32     },
    {   MTP_PROPERTY_PERSISTENT_UID,    MTP_TYPE_UINT128    },
    {   MTP_PROPERTY_NAME,              MTP_TYPE_STR        },
    {   MTP_PROPERTY_DISPLAY_NAME,      MTP_TYPE_STR        },
    {   MTP_PROPERTY_DATE_ADDED,        MTP_TYPE_STR        },
    {   MTP_PROPERTY_ARTIST,            MTP_TYPE_STR        },
    {   MTP_PROPERTY_ALBUM_NAME,        MTP_TYPE_STR        },
    {   MTP_PROPERTY_ALBUM_ARTIST,      MTP_TYPE_STR        },
    {   MTP_PROPERTY_TRACK,             MTP_TYPE_UINT16     },
    {   MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR    },
    {   MTP_PROPERTY_GENRE,             MTP_TYPE_STR        },
    {   MTP_PROPERTY_COMPOSER,          MTP_TYPE_STR        },
    {   MTP_PROPERTY_DURATION,          MTP_TYPE_UINT32     },
    {   MTP_PROPERTY_DESCRIPTION,       MTP_TYPE_STR        },
    {   MTP_PROPERTY_AUDIO_WAVE_CODEC,  MTP_TYPE_UINT32     },
    {   MTP_PROPERTY_BITRATE_TYPE,      MTP_TYPE_UINT16     },
    {   MTP_PROPERTY_AUDIO_BITRATE,     MTP_TYPE_UINT32     },
    {   MTP_PROPERTY_NUMBER_OF_CHANNELS,MTP_TYPE_UINT16     },
    {   MTP_PROPERTY_SAMPLE_RATE,       MTP_TYPE_UINT32     },
};

static const PropertyTableEntry   kDevicePropertyTable[] = {
    {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,    MTP_TYPE_STR },
    {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,       MTP_TYPE_STR },
    {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
    {   MTP_DEVICE_PROPERTY_BATTERY_LEVEL,              MTP_TYPE_UINT8 },
    {   MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE,      MTP_TYPE_UINT32 },
    {   MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO,     MTP_TYPE_STR },
};

bool MtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
    int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
    const PropertyTableEntry* entry = kObjectPropertyTable;
    for (int i = 0; i < count; i++, entry++) {
        if (entry->property == property) {
            type = entry->type;
            return true;
        }
    }
    return false;
}

bool MtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
    int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
    const PropertyTableEntry* entry = kDevicePropertyTable;
    for (int i = 0; i < count; i++, entry++) {
        if (entry->property == property) {
            type = entry->type;
            return true;
        }
    }
    return false;
}

MtpObjectHandleList* MtpDatabase::getObjectReferences(MtpObjectHandle handle) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
                (jint)handle);
    if (!array)
        return NULL;
    MtpObjectHandleList* list = new MtpObjectHandleList();
    jint* handles = env->GetIntArrayElements(array, 0);
    jsize length = env->GetArrayLength(array);
    for (int i = 0; i < length; i++)
        list->push_back(handles[i]);
    env->ReleaseIntArrayElements(array, handles, 0);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return list;
}

MtpResponseCode MtpDatabase::setObjectReferences(MtpObjectHandle handle,
                                                   MtpObjectHandleList* references) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    int count = references->size();
    jintArray array = env->NewIntArray(count);
    if (!array) {
        ALOGE("out of memory in setObjectReferences");
        return false;
    }
    jint* handles = env->GetIntArrayElements(array, 0);
     for (int i = 0; i < count; i++)
        handles[i] = (*references)[i];
    env->ReleaseIntArrayElements(array, handles, 0);
    MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
                (jint)handle, array);
    env->DeleteLocalRef(array);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

MtpProperty* MtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
                                                  MtpObjectFormat format) {
    static const int channelEnum[] = {
                                        1,  // mono
                                        2,  // stereo
                                        3,  // 2.1
                                        4,  // 3
                                        5,  // 3.1
                                        6,  // 4
                                        7,  // 4.1
                                        8,  // 5
                                        9,  // 5.1
                                    };
    static const int bitrateEnum[] = {
                                        1,  // fixed rate
                                        2,  // variable rate
                                     };

    MtpProperty* result = NULL;
    switch (property) {
        case MTP_PROPERTY_OBJECT_FORMAT:
            // use format as default value
            result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
            break;
        case MTP_PROPERTY_PROTECTION_STATUS:
        case MTP_PROPERTY_TRACK:
            result = new MtpProperty(property, MTP_TYPE_UINT16);
            break;
        case MTP_PROPERTY_STORAGE_ID:
        case MTP_PROPERTY_PARENT_OBJECT:
        case MTP_PROPERTY_DURATION:
        case MTP_PROPERTY_AUDIO_WAVE_CODEC:
            result = new MtpProperty(property, MTP_TYPE_UINT32);
            break;
        case MTP_PROPERTY_OBJECT_SIZE:
            result = new MtpProperty(property, MTP_TYPE_UINT64);
            break;
        case MTP_PROPERTY_PERSISTENT_UID:
            result = new MtpProperty(property, MTP_TYPE_UINT128);
            break;
        case MTP_PROPERTY_NAME:
        case MTP_PROPERTY_DISPLAY_NAME:
        case MTP_PROPERTY_ARTIST:
        case MTP_PROPERTY_ALBUM_NAME:
        case MTP_PROPERTY_ALBUM_ARTIST:
        case MTP_PROPERTY_GENRE:
        case MTP_PROPERTY_COMPOSER:
        case MTP_PROPERTY_DESCRIPTION:
            result = new MtpProperty(property, MTP_TYPE_STR);
            break;
        case MTP_PROPERTY_DATE_MODIFIED:
        case MTP_PROPERTY_DATE_ADDED:
        case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
            result = new MtpProperty(property, MTP_TYPE_STR);
            result->setFormDateTime();
            break;
        case MTP_PROPERTY_OBJECT_FILE_NAME:
            // We allow renaming files and folders
            result = new MtpProperty(property, MTP_TYPE_STR, true);
            break;
        case MTP_PROPERTY_BITRATE_TYPE:
             result = new MtpProperty(property, MTP_TYPE_UINT16);
            result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
            break;
        case MTP_PROPERTY_AUDIO_BITRATE:
            result = new MtpProperty(property, MTP_TYPE_UINT32);
            result->setFormRange(1, 1536000, 1);
            break;
        case MTP_PROPERTY_NUMBER_OF_CHANNELS:
            result = new MtpProperty(property, MTP_TYPE_UINT16);
            result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
            break;
        case MTP_PROPERTY_SAMPLE_RATE:
            result = new MtpProperty(property, MTP_TYPE_UINT32);
            result->setFormRange(8000, 48000, 1);
            break;
    }

    return result;
}

MtpProperty* MtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    MtpProperty* result = NULL;
    bool writable = false;

    // get current value
    jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
        (jint)property, mLongBuffer, mStringBuffer);
    if (ret == MTP_RESPONSE_OK) {
        switch (property) {
            case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
            case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
            case MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO:
                writable = true;
                // fall through
                FALLTHROUGH_INTENDED;
            case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
            {
                result = new MtpProperty(property, MTP_TYPE_STR, writable);
                jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
                result->setCurrentValue(str);
                // for read-only properties it is safe to assume current value is default value
                if (!writable)
                    result->setDefaultValue(str);
                env->ReleaseCharArrayElements(mStringBuffer, str, 0);
                break;
            }
            case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
            {
                result = new MtpProperty(property, MTP_TYPE_UINT8);
                jlong* arr = env->GetLongArrayElements(mLongBuffer, 0);
                result->setFormRange(0, arr[1], 1);
                result->mCurrentValue.u.u8 = (uint8_t) arr[0];
                env->ReleaseLongArrayElements(mLongBuffer, arr, 0);
                break;
            }
            case MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE:
            {
                jlong* arr = env->GetLongArrayElements(mLongBuffer, 0);
                result = new MtpProperty(property, MTP_TYPE_UINT32);
                result->mCurrentValue.u.u32 = (uint32_t) arr[0];
                env->ReleaseLongArrayElements(mLongBuffer, arr, 0);
                break;
            }
            default:
                ALOGE("Unrecognized property %x", property);
        }
    } else {
        ALOGE("unable to read device property, response: %04X", ret);
    }

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}

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

static void
android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
{
    initializeJavaIDs(env);
    MtpDatabase* database = new MtpDatabase(env, thiz);
    env->SetLongField(thiz, field_context, (jlong)database);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

static void
android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
{
    MtpDatabase* database = (MtpDatabase *)env->GetLongField(thiz, field_context);
    database->cleanup(env);
    delete database;
    env->SetLongField(thiz, field_context, 0);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

static jstring
android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject /*thiz*/, jlong seconds)
{
    char    date[20];
    formatDateTime(seconds, date, sizeof(date));
    return env->NewStringUTF(date);
}

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

static const JNINativeMethod gMtpDatabaseMethods[] = {
    {"native_setup",            "()V",  (void *)android_mtp_MtpDatabase_setup},
    {"native_finalize",         "()V",  (void *)android_mtp_MtpDatabase_finalize},
};

static const JNINativeMethod gMtpPropertyGroupMethods[] = {
    {"format_date_time",        "(J)Ljava/lang/String;",
                                        (void *)android_mtp_MtpPropertyGroup_format_date_time},
};
                                                                   \
int register_android_mtp_MtpDatabase(JNIEnv *env)
{
    if (AndroidRuntime::registerNativeMethods(env,
                "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
        return -1;

    return AndroidRuntime::registerNativeMethods(env,
                "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
}
