diff options
Diffstat (limited to 'media/jni/android_mtp_MtpDatabase.cpp')
-rw-r--r-- | media/jni/android_mtp_MtpDatabase.cpp | 654 |
1 files changed, 266 insertions, 388 deletions
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index 4e8c72bae9b9..23ef84f6ad90 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -19,7 +19,7 @@ #include "android_media_Utils.h" #include "mtp.h" -#include "MtpDatabase.h" +#include "IMtpDatabase.h" #include "MtpDataPacket.h" #include "MtpObjectInfo.h" #include "MtpProperty.h" @@ -55,7 +55,7 @@ using namespace android; static jmethodID method_beginSendObject; static jmethodID method_endSendObject; -static jmethodID method_doScanDirectory; +static jmethodID method_rescanFile; static jmethodID method_getObjectList; static jmethodID method_getNumObjects; static jmethodID method_getSupportedPlaybackFormats; @@ -68,35 +68,34 @@ static jmethodID method_setDeviceProperty; static jmethodID method_getObjectPropertyList; static jmethodID method_getObjectInfo; static jmethodID method_getObjectFilePath; -static jmethodID method_deleteFile; -static jmethodID method_moveObject; +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; -static jmethodID method_sessionStarted; -static jmethodID method_sessionEnded; static jfieldID field_context; -static jfieldID field_batteryLevel; -static jfieldID field_batteryScale; -static jfieldID field_deviceType; - -// MtpPropertyList fields -static jfieldID field_mCount; -static jfieldID field_mResult; -static jfieldID field_mObjectHandles; -static jfieldID field_mPropertyCodes; -static jfieldID field_mDataTypes; -static jfieldID field_mLongValues; -static jfieldID field_mStringValues; - - -MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) { - return (MtpDatabase *)env->GetLongField(database, 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; + + +IMtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) { + return (IMtpDatabase *)env->GetLongField(database, field_context); } // ---------------------------------------------------------------------------- -class MyMtpDatabase : public MtpDatabase { +class MtpDatabase : public IMtpDatabase { private: jobject mDatabase; jintArray mIntBuffer; @@ -104,23 +103,20 @@ private: jcharArray mStringBuffer; public: - MyMtpDatabase(JNIEnv *env, jobject client); - virtual ~MyMtpDatabase(); + MtpDatabase(JNIEnv *env, jobject client); + virtual ~MtpDatabase(); void cleanup(JNIEnv *env); virtual MtpObjectHandle beginSendObject(const char* path, MtpObjectFormat format, MtpObjectHandle parent, - MtpStorageID storage, - uint64_t size, - time_t modified); + MtpStorageID storage); - virtual void endSendObject(const char* path, - MtpObjectHandle handle, - MtpObjectFormat format, - bool succeeded); + virtual void endSendObject(MtpObjectHandle handle, bool succeeded); - virtual void doScanDirectory(const char* path); + virtual void rescanFile(const char* path, + MtpObjectHandle handle, + MtpObjectFormat format); virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID, MtpObjectFormat format, @@ -167,7 +163,8 @@ public: MtpString& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat); - virtual MtpResponseCode deleteFile(MtpObjectHandle handle); + virtual MtpResponseCode beginDeleteObject(MtpObjectHandle handle); + virtual void endDeleteObject(MtpObjectHandle handle, bool succeeded); bool getObjectPropertyInfo(MtpObjectProperty property, int& type); bool getDevicePropertyInfo(MtpDeviceProperty property, int& type); @@ -182,12 +179,17 @@ public: virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property); - virtual MtpResponseCode moveObject(MtpObjectHandle handle, MtpObjectHandle newParent, - MtpStorageID newStorage, MtpString& newPath); + 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 void sessionStarted(); + virtual MtpResponseCode beginCopyObject(MtpObjectHandle handle, MtpObjectHandle newParent, + MtpStorageID newStorage); + virtual void endCopyObject(MtpObjectHandle handle, bool succeeded); - virtual void sessionEnded(); }; // ---------------------------------------------------------------------------- @@ -202,7 +204,7 @@ static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa // ---------------------------------------------------------------------------- -MyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client) +MtpDatabase::MtpDatabase(JNIEnv *env, jobject client) : mDatabase(env->NewGlobalRef(client)), mIntBuffer(NULL), mLongBuffer(NULL), @@ -228,27 +230,24 @@ MyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client) mStringBuffer = (jcharArray)env->NewGlobalRef(charArray); } -void MyMtpDatabase::cleanup(JNIEnv *env) { +void MtpDatabase::cleanup(JNIEnv *env) { env->DeleteGlobalRef(mDatabase); env->DeleteGlobalRef(mIntBuffer); env->DeleteGlobalRef(mLongBuffer); env->DeleteGlobalRef(mStringBuffer); } -MyMtpDatabase::~MyMtpDatabase() { +MtpDatabase::~MtpDatabase() { } -MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path, +MtpObjectHandle MtpDatabase::beginSendObject(const char* path, MtpObjectFormat format, MtpObjectHandle parent, - MtpStorageID storage, - uint64_t size, - time_t modified) { + 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, - (jlong)size, (jlong)modified); + pathStr, (jint)format, (jint)parent, (jint)storage); if (pathStr) env->DeleteLocalRef(pathStr); @@ -256,29 +255,26 @@ MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path, return result; } -void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle, - MtpObjectFormat format, bool succeeded) { +void MtpDatabase::endSendObject(MtpObjectHandle handle, bool succeeded) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - jstring pathStr = env->NewStringUTF(path); - env->CallVoidMethod(mDatabase, method_endSendObject, pathStr, - (jint)handle, (jint)format, (jboolean)succeeded); + env->CallVoidMethod(mDatabase, method_endSendObject, (jint)handle, (jboolean)succeeded); - if (pathStr) - env->DeleteLocalRef(pathStr); checkAndClearExceptionFromCallback(env, __FUNCTION__); } -void MyMtpDatabase::doScanDirectory(const char* path) { +void MtpDatabase::rescanFile(const char* path, MtpObjectHandle handle, + MtpObjectFormat format) { JNIEnv* env = AndroidRuntime::getJNIEnv(); jstring pathStr = env->NewStringUTF(path); - env->CallVoidMethod(mDatabase, method_doScanDirectory, pathStr); + env->CallVoidMethod(mDatabase, method_rescanFile, pathStr, + (jint)handle, (jint)format); if (pathStr) env->DeleteLocalRef(pathStr); checkAndClearExceptionFromCallback(env, __FUNCTION__); } -MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID, +MtpObjectHandleList* MtpDatabase::getObjectList(MtpStorageID storageID, MtpObjectFormat format, MtpObjectHandle parent) { JNIEnv* env = AndroidRuntime::getJNIEnv(); @@ -298,7 +294,7 @@ MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID, return list; } -int MyMtpDatabase::getNumObjects(MtpStorageID storageID, +int MtpDatabase::getNumObjects(MtpStorageID storageID, MtpObjectFormat format, MtpObjectHandle parent) { JNIEnv* env = AndroidRuntime::getJNIEnv(); @@ -309,7 +305,7 @@ int MyMtpDatabase::getNumObjects(MtpStorageID storageID, return result; } -MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() { +MtpObjectFormatList* MtpDatabase::getSupportedPlaybackFormats() { JNIEnv* env = AndroidRuntime::getJNIEnv(); jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getSupportedPlaybackFormats); @@ -327,7 +323,7 @@ MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() { return list; } -MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() { +MtpObjectFormatList* MtpDatabase::getSupportedCaptureFormats() { JNIEnv* env = AndroidRuntime::getJNIEnv(); jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getSupportedCaptureFormats); @@ -345,7 +341,7 @@ MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() { return list; } -MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) { +MtpObjectPropertyList* MtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) { JNIEnv* env = AndroidRuntime::getJNIEnv(); jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getSupportedObjectProperties, (jint)format); @@ -363,7 +359,7 @@ MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectForm return list; } -MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() { +MtpDevicePropertyList* MtpDatabase::getSupportedDeviceProperties() { JNIEnv* env = AndroidRuntime::getJNIEnv(); jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getSupportedDeviceProperties); @@ -381,7 +377,7 @@ MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() { return list; } -MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, +MtpResponseCode MtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, MtpDataPacket& packet) { static_assert(sizeof(jint) >= sizeof(MtpObjectHandle), @@ -397,42 +393,26 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, static_cast<jint>(property), 0, 0); - MtpResponseCode result = env->GetIntField(list, field_mResult); - int count = env->GetIntField(list, field_mCount); - if (result == MTP_RESPONSE_OK && count != 1) + 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->GetObjectField(list, field_mObjectHandles); - jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes); - jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes); - jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues); - jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues); + 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); + jlong* longValues = env->GetLongArrayElements(longValuesArray, 0); int type = dataTypes[0]; jlong longValue = (longValues ? longValues[0] : 0); - // special case date properties, which are strings to MTP - // but stored internally as a uint64 - if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) { - char date[20]; - formatDateTime(longValue, date, sizeof(date)); - packet.putString(date); - goto out; - } - // release date is stored internally as just the year - if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) { - char date[20]; - snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue); - packet.putString(date); - goto out; - } - switch (type) { case MTP_TYPE_INT8: packet.putInt8(longValue); @@ -481,20 +461,16 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, ALOGE("unsupported type in getObjectPropertyValue\n"); result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } -out: env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0); env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0); env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0); - if (longValues) - env->ReleaseLongArrayElements(longValuesArray, longValues, 0); + env->ReleaseLongArrayElements(longValuesArray, longValues, 0); env->DeleteLocalRef(objectHandlesArray); env->DeleteLocalRef(propertyCodesArray); env->DeleteLocalRef(dataTypesArray); - if (longValuesArray) - env->DeleteLocalRef(longValuesArray); - if (stringValuesArray) - env->DeleteLocalRef(stringValuesArray); + env->DeleteLocalRef(longValuesArray); + env->DeleteLocalRef(stringValuesArray); } env->DeleteLocalRef(list); @@ -559,7 +535,7 @@ static bool readLongValue(int type, MtpDataPacket& packet, jlong& longValue) { return true; } -MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle, +MtpResponseCode MtpDatabase::setObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, MtpDataPacket& packet) { int type; @@ -590,80 +566,73 @@ fail: return result; } -MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property, +MtpResponseCode MtpDatabase::getDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) { JNIEnv* env = AndroidRuntime::getJNIEnv(); + int type; - if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) { - // special case - implemented here instead of Java - packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel)); - return MTP_RESPONSE_OK; - } else { - int type; - - if (!getDevicePropertyInfo(property, type)) - return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; + 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; - } + 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); + 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; + 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; } - - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return MTP_RESPONSE_OK; + default: + ALOGE("unsupported type in getDevicePropertyValue\n"); + return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT; } + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return MTP_RESPONSE_OK; } -MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property, +MtpResponseCode MtpDatabase::setDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) { int type; @@ -693,11 +662,11 @@ fail: return result; } -MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) { +MtpResponseCode MtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) { return -1; } -MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, +MtpResponseCode MtpDatabase::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, int depth, MtpDataPacket& packet) { @@ -715,16 +684,16 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, checkAndClearExceptionFromCallback(env, __FUNCTION__); if (!list) return MTP_RESPONSE_GENERAL_ERROR; - int count = env->GetIntField(list, field_mCount); - MtpResponseCode result = env->GetIntField(list, field_mResult); + int count = env->CallIntMethod(list, method_getCount); + MtpResponseCode result = env->CallIntMethod(list, method_getCode); packet.putUInt32(count); if (count > 0) { - jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles); - jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes); - jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes); - jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues); - jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues); + 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); @@ -781,7 +750,7 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, break; } default: - ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList"); + ALOGE("bad or unsupported data type in MtpDatabase::getObjectPropertyList"); break; } } @@ -789,16 +758,13 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0); env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0); env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0); - if (longValues) - env->ReleaseLongArrayElements(longValuesArray, longValues, 0); + env->ReleaseLongArrayElements(longValuesArray, longValues, 0); env->DeleteLocalRef(objectHandlesArray); env->DeleteLocalRef(propertyCodesArray); env->DeleteLocalRef(dataTypesArray); - if (longValuesArray) - env->DeleteLocalRef(longValuesArray); - if (stringValuesArray) - env->DeleteLocalRef(stringValuesArray); + env->DeleteLocalRef(longValuesArray); + env->DeleteLocalRef(stringValuesArray); } env->DeleteLocalRef(list); @@ -822,7 +788,7 @@ static long getLongFromExifEntry(ExifEntry *e) { return exif_get_long(e->data, o); } -MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, +MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) { MtpString path; int64_t length; @@ -914,7 +880,7 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, return MTP_RESPONSE_OK; } -void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) { +void* MtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) { MtpString path; int64_t length; MtpObjectFormat format; @@ -979,7 +945,7 @@ void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) return result; } -MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, +MtpResponseCode MtpDatabase::getObjectFilePath(MtpObjectHandle handle, MtpString& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat) { @@ -1005,26 +971,60 @@ MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, return result; } -MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) { +MtpResponseCode MtpDatabase::beginDeleteObject(MtpObjectHandle handle) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle); + MtpResponseCode result = env->CallIntMethod(mDatabase, method_beginDeleteObject, (jint)handle); checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } -MtpResponseCode MyMtpDatabase::moveObject(MtpObjectHandle handle, MtpObjectHandle newParent, - MtpStorageID newStorage, MtpString &newPath) { +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(); - jstring stringValue = env->NewStringUTF((const char *) newPath); - MtpResponseCode result = env->CallIntMethod(mDatabase, method_moveObject, - (jint)handle, (jint)newParent, (jint) newStorage, stringValue); + MtpResponseCode result = env->CallIntMethod(mDatabase, method_beginCopyObject, + (jint)handle, (jint)newParent, (jint) newStorage); checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(stringValue); 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; @@ -1066,7 +1066,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = { { MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MTP_TYPE_UINT32 }, }; -bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) { +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++) { @@ -1078,7 +1078,7 @@ bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) return false; } -bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) { +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++) { @@ -1090,7 +1090,7 @@ bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) return false; } -MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) { +MtpObjectHandleList* MtpDatabase::getObjectReferences(MtpObjectHandle handle) { JNIEnv* env = AndroidRuntime::getJNIEnv(); jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences, (jint)handle); @@ -1108,7 +1108,7 @@ MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) return list; } -MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle, +MtpResponseCode MtpDatabase::setObjectReferences(MtpObjectHandle handle, MtpObjectHandleList* references) { JNIEnv* env = AndroidRuntime::getJNIEnv(); int count = references->size(); @@ -1129,7 +1129,7 @@ MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle, return result; } -MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, +MtpProperty* MtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, MtpObjectFormat format) { static const int channelEnum[] = { 1, // mono @@ -1210,67 +1210,65 @@ MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, return result; } -MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { +MtpProperty* MtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { JNIEnv* env = AndroidRuntime::getJNIEnv(); MtpProperty* result = NULL; bool writable = false; - switch (property) { - case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: - case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: - writable = true; - // fall through - case MTP_DEVICE_PROPERTY_IMAGE_SIZE: { - result = new MtpProperty(property, MTP_TYPE_STR, writable); - - // get current value - jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty, - (jint)property, mLongBuffer, mStringBuffer); - if (ret == MTP_RESPONSE_OK) { + // 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: + writable = true; + // fall through + 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); - } else { - ALOGE("unable to read device property, response: %04X", ret); + break; } - 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); } - case MTP_DEVICE_PROPERTY_BATTERY_LEVEL: - result = new MtpProperty(property, MTP_TYPE_UINT8); - result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1); - result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel); - break; - case MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE: - result = new MtpProperty(property, MTP_TYPE_UINT32); - result->mCurrentValue.u.u32 = (uint32_t)env->GetIntField(mDatabase, field_deviceType); - break; + } else { + ALOGE("unable to read device property, response: %04X", ret); } checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } -void MyMtpDatabase::sessionStarted() { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mDatabase, method_sessionStarted); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - -void MyMtpDatabase::sessionEnded() { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - env->CallVoidMethod(mDatabase, method_sessionEnded); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - // ---------------------------------------------------------------------------- static void android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz) { - MyMtpDatabase* database = new MyMtpDatabase(env, thiz); + MtpDatabase* database = new MtpDatabase(env, thiz); env->SetLongField(thiz, field_context, (jlong)database); checkAndClearExceptionFromCallback(env, __FUNCTION__); } @@ -1278,7 +1276,7 @@ android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz) static void android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz) { - MyMtpDatabase* database = (MyMtpDatabase *)env->GetLongField(thiz, field_context); + MtpDatabase* database = (MtpDatabase *)env->GetLongField(thiz, field_context); database->cleanup(env); delete database; env->SetLongField(thiz, field_context, 0); @@ -1305,6 +1303,13 @@ static const JNINativeMethod gMtpPropertyGroupMethods[] = { (void *)android_mtp_MtpPropertyGroup_format_date_time}, }; +#define GET_METHOD_ID(name, jclass, signature) \ + method_##name = env->GetMethodID(jclass, #name, signature); \ + if (method_##name == NULL) { \ + ALOGE("Can't find " #name); \ + return -1; \ + } \ + int register_android_mtp_MtpDatabase(JNIEnv *env) { jclass clazz; @@ -1314,175 +1319,48 @@ int register_android_mtp_MtpDatabase(JNIEnv *env) ALOGE("Can't find android/mtp/MtpDatabase"); return -1; } - method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I"); - if (method_beginSendObject == NULL) { - ALOGE("Can't find beginSendObject"); - return -1; - } - method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V"); - if (method_endSendObject == NULL) { - ALOGE("Can't find endSendObject"); - return -1; - } - method_doScanDirectory = env->GetMethodID(clazz, "doScanDirectory", "(Ljava/lang/String;)V"); - if (method_doScanDirectory == NULL) { - ALOGE("Can't find doScanDirectory"); - return -1; - } - method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I"); - if (method_getObjectList == NULL) { - ALOGE("Can't find getObjectList"); - return -1; - } - method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I"); - if (method_getNumObjects == NULL) { - ALOGE("Can't find getNumObjects"); - return -1; - } - method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I"); - if (method_getSupportedPlaybackFormats == NULL) { - ALOGE("Can't find getSupportedPlaybackFormats"); - return -1; - } - method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I"); - if (method_getSupportedCaptureFormats == NULL) { - ALOGE("Can't find getSupportedCaptureFormats"); - return -1; - } - method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I"); - if (method_getSupportedObjectProperties == NULL) { - ALOGE("Can't find getSupportedObjectProperties"); - return -1; - } - method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I"); - if (method_getSupportedDeviceProperties == NULL) { - ALOGE("Can't find getSupportedDeviceProperties"); - return -1; - } - method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I"); - if (method_setObjectProperty == NULL) { - ALOGE("Can't find setObjectProperty"); - return -1; - } - method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I"); - if (method_getDeviceProperty == NULL) { - ALOGE("Can't find getDeviceProperty"); - return -1; - } - method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I"); - if (method_setDeviceProperty == NULL) { - ALOGE("Can't find setDeviceProperty"); - return -1; - } - method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList", - "(IIIII)Landroid/mtp/MtpPropertyList;"); - if (method_getObjectPropertyList == NULL) { - ALOGE("Can't find getObjectPropertyList"); - return -1; - } - method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z"); - if (method_getObjectInfo == NULL) { - ALOGE("Can't find getObjectInfo"); - return -1; - } - method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I"); - if (method_getObjectFilePath == NULL) { - ALOGE("Can't find getObjectFilePath"); - return -1; - } - method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I"); - if (method_deleteFile == NULL) { - ALOGE("Can't find deleteFile"); - return -1; - } - method_moveObject = env->GetMethodID(clazz, "moveObject", "(IIILjava/lang/String;)I"); - if (method_moveObject == NULL) { - ALOGE("Can't find moveObject"); - return -1; - } - method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I"); - if (method_getObjectReferences == NULL) { - ALOGE("Can't find getObjectReferences"); - return -1; - } - method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I"); - if (method_setObjectReferences == NULL) { - ALOGE("Can't find setObjectReferences"); - return -1; - } - method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V"); - if (method_sessionStarted == NULL) { - ALOGE("Can't find sessionStarted"); - return -1; - } - method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V"); - if (method_sessionEnded == NULL) { - ALOGE("Can't find sessionEnded"); - return -1; - } + GET_METHOD_ID(beginSendObject, clazz, "(Ljava/lang/String;III)I"); + GET_METHOD_ID(endSendObject, clazz, "(IZ)V"); + GET_METHOD_ID(rescanFile, clazz, "(Ljava/lang/String;II)V"); + GET_METHOD_ID(getObjectList, clazz, "(III)[I"); + GET_METHOD_ID(getNumObjects, clazz, "(III)I"); + GET_METHOD_ID(getSupportedPlaybackFormats, clazz, "()[I"); + GET_METHOD_ID(getSupportedCaptureFormats, clazz, "()[I"); + GET_METHOD_ID(getSupportedObjectProperties, clazz, "(I)[I"); + GET_METHOD_ID(getSupportedDeviceProperties, clazz, "()[I"); + GET_METHOD_ID(setObjectProperty, clazz, "(IIJLjava/lang/String;)I"); + GET_METHOD_ID(getDeviceProperty, clazz, "(I[J[C)I"); + GET_METHOD_ID(setDeviceProperty, clazz, "(IJLjava/lang/String;)I"); + GET_METHOD_ID(getObjectPropertyList, clazz, "(IIIII)Landroid/mtp/MtpPropertyList;"); + GET_METHOD_ID(getObjectInfo, clazz, "(I[I[C[J)Z"); + GET_METHOD_ID(getObjectFilePath, clazz, "(I[C[J)I"); + GET_METHOD_ID(beginDeleteObject, clazz, "(I)I"); + GET_METHOD_ID(endDeleteObject, clazz, "(IZ)V"); + GET_METHOD_ID(beginMoveObject, clazz, "(III)I"); + GET_METHOD_ID(endMoveObject, clazz, "(IIIIIZ)V"); + GET_METHOD_ID(beginCopyObject, clazz, "(III)I"); + GET_METHOD_ID(endCopyObject, clazz, "(IZ)V"); + GET_METHOD_ID(getObjectReferences, clazz, "(I)[I"); + GET_METHOD_ID(setObjectReferences, clazz, "(I[I)I"); field_context = env->GetFieldID(clazz, "mNativeContext", "J"); if (field_context == NULL) { ALOGE("Can't find MtpDatabase.mNativeContext"); return -1; } - field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I"); - if (field_batteryLevel == NULL) { - ALOGE("Can't find MtpDatabase.mBatteryLevel"); - return -1; - } - field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I"); - if (field_batteryScale == NULL) { - ALOGE("Can't find MtpDatabase.mBatteryScale"); - return -1; - } - field_deviceType = env->GetFieldID(clazz, "mDeviceType", "I"); - if (field_deviceType == NULL) { - ALOGE("Can't find MtpDatabase.mDeviceType"); - return -1; - } - // now set up fields for MtpPropertyList class clazz = env->FindClass("android/mtp/MtpPropertyList"); if (clazz == NULL) { ALOGE("Can't find android/mtp/MtpPropertyList"); return -1; } - field_mCount = env->GetFieldID(clazz, "mCount", "I"); - if (field_mCount == NULL) { - ALOGE("Can't find MtpPropertyList.mCount"); - return -1; - } - field_mResult = env->GetFieldID(clazz, "mResult", "I"); - if (field_mResult == NULL) { - ALOGE("Can't find MtpPropertyList.mResult"); - return -1; - } - field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I"); - if (field_mObjectHandles == NULL) { - ALOGE("Can't find MtpPropertyList.mObjectHandles"); - return -1; - } - field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I"); - if (field_mPropertyCodes == NULL) { - ALOGE("Can't find MtpPropertyList.mPropertyCodes"); - return -1; - } - field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I"); - if (field_mDataTypes == NULL) { - ALOGE("Can't find MtpPropertyList.mDataTypes"); - return -1; - } - field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J"); - if (field_mLongValues == NULL) { - ALOGE("Can't find MtpPropertyList.mLongValues"); - return -1; - } - field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;"); - if (field_mStringValues == NULL) { - ALOGE("Can't find MtpPropertyList.mStringValues"); - return -1; - } + GET_METHOD_ID(getCode, clazz, "()I"); + GET_METHOD_ID(getCount, clazz, "()I"); + GET_METHOD_ID(getObjectHandles, clazz, "()[I"); + GET_METHOD_ID(getPropertyCodes, clazz, "()[I"); + GET_METHOD_ID(getDataTypes, clazz, "()[I"); + GET_METHOD_ID(getLongValues, clazz, "()[J"); + GET_METHOD_ID(getStringValues, clazz, "()[Ljava/lang/String;"); if (AndroidRuntime::registerNativeMethods(env, "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods))) |