summaryrefslogtreecommitdiffstats
path: root/media/jni/android_media_MtpDatabase.cpp
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@google.com>2010-10-14 18:03:25 -0400
committerMike Lockwood <lockwood@android.com>2010-11-15 11:46:51 -0500
commite2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a (patch)
tree0f7de42a1ed233d704558830643e73acd954b940 /media/jni/android_media_MtpDatabase.cpp
parent44d47ad56502a1ccb308a9ec2cd05120a53fac3d (diff)
downloadframeworks_base-e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a.zip
frameworks_base-e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a.tar.gz
frameworks_base-e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a.tar.bz2
MTP: Partial implementation of the GetObjectPropList command
In this initial implementation we only support fetching one property at a time. Support depth = 0 (single object) or depth = 1 (all objects in a directory) Reimplemented GetObjectPropValue on top of GetObjectPropList, since the former is a special case of the latter. Change-Id: Ia76ee61741d6ee3902b5c5d9fc094cf86dfaf650 Signed-off-by: Mike Lockwood <lockwood@google.com>
Diffstat (limited to 'media/jni/android_media_MtpDatabase.cpp')
-rw-r--r--media/jni/android_media_MtpDatabase.cpp344
1 files changed, 265 insertions, 79 deletions
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index 87cb82e..aa29de8 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -46,10 +46,10 @@ static jmethodID method_getSupportedPlaybackFormats;
static jmethodID method_getSupportedCaptureFormats;
static jmethodID method_getSupportedObjectProperties;
static jmethodID method_getSupportedDeviceProperties;
-static jmethodID method_getObjectProperty;
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_deleteFile;
@@ -60,6 +60,16 @@ static jmethodID method_sessionEnded;
static jfieldID field_context;
+// 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->GetIntField(database, field_context);
}
@@ -122,6 +132,12 @@ public:
virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
+ virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle handle,
+ MtpObjectFormat format,
+ MtpObjectProperty property,
+ int groupCode, int depth,
+ MtpDataPacket& packet);
+
virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet);
@@ -336,84 +352,111 @@ MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) {
- int type;
-
- if (!getObjectPropertyInfo(property, type))
- return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
-
JNIEnv* env = AndroidRuntime::getJNIEnv();
- jint result = env->CallIntMethod(mDatabase, method_getObjectProperty,
- (jint)handle, (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);
-
- // 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);
- return MTP_RESPONSE_OK;
- }
- // release date is stored internally as just the year
- if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
- char date[20];
- snprintf(date, sizeof(date), "%04lld0101T000000", longValue);
- packet.putString(date);
- return MTP_RESPONSE_OK;
- }
+ jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
+ (jint)handle, 0, (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)
+ 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);
+
+ 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);
+
+ 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), "%04lld0101T000000", longValue);
+ packet.putString(date);
+ goto out;
+ }
- 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:
- LOGE("unsupported type in getObjectPropertyValue\n");
- return MTP_RESPONSE_INVALID_OBJECT_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:
+ {
+ jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
+ if (stringValue) {
+ const char* str = env->GetStringUTFChars(stringValue, NULL);
+ packet.putString(str);
+ env->ReleaseStringUTFChars(stringValue, str);
+ } else {
+ packet.putEmptyString();
+ }
+ break;
+ }
+ default:
+ LOGE("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->DeleteLocalRef(objectHandlesArray);
+ env->DeleteLocalRef(propertyCodesArray);
+ env->DeleteLocalRef(dataTypesArray);
+ if (longValuesArray)
+ env->DeleteLocalRef(longValuesArray);
+ if (stringValuesArray)
+ env->DeleteLocalRef(stringValuesArray);
}
+ env->DeleteLocalRef(list);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
- return MTP_RESPONSE_OK;
+ return result;
}
MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
@@ -601,6 +644,106 @@ MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
return -1;
}
+MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
+ MtpObjectFormat format,
+ MtpObjectProperty property,
+ int groupCode, int depth,
+ MtpDataPacket& packet) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
+ (jint)handle, (jint)format, (jint)property, (jint)groupCode, (jint)depth);
+ int count = env->GetIntField(list, field_mCount);
+ MtpResponseCode result = env->GetIntField(list, field_mResult);
+
+ 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);
+
+ 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);
+
+ 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;
+ case MTP_TYPE_STR: {
+ jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
+ const char *valueStr = env->GetStringUTFChars(value, NULL);
+ if (valueStr) {
+ packet.putString(valueStr);
+ env->ReleaseStringUTFChars(value, valueStr);
+ } else {
+ packet.putEmptyString();
+ }
+ env->DeleteLocalRef(value);
+ break;
+ }
+ default:
+ LOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
+ break;
+ }
+ }
+
+ env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
+ env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
+ env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
+ if (longValues)
+ 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(list);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return result;
+}
+
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet) {
char date[20];
@@ -954,11 +1097,6 @@ int register_android_media_MtpDatabase(JNIEnv *env)
LOGE("Can't find getSupportedDeviceProperties");
return -1;
}
- method_getObjectProperty = env->GetMethodID(clazz, "getObjectProperty", "(II[J[C)I");
- if (method_getObjectProperty == NULL) {
- LOGE("Can't find getObjectProperty");
- return -1;
- }
method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
if (method_setObjectProperty == NULL) {
LOGE("Can't find setObjectProperty");
@@ -974,6 +1112,12 @@ int register_android_media_MtpDatabase(JNIEnv *env)
LOGE("Can't find setDeviceProperty");
return -1;
}
+ method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
+ "(IIIII)Landroid/media/MtpPropertyList;");
+ if (method_getObjectPropertyList == NULL) {
+ LOGE("Can't find getObjectPropertyList");
+ return -1;
+ }
method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
if (method_getObjectInfo == NULL) {
LOGE("Can't find getObjectInfo");
@@ -1016,6 +1160,48 @@ int register_android_media_MtpDatabase(JNIEnv *env)
return -1;
}
+ // now set up fields for MtpPropertyList class
+ clazz = env->FindClass("android/media/MtpPropertyList");
+ if (clazz == NULL) {
+ LOGE("Can't find android/media/MtpPropertyList");
+ return -1;
+ }
+ field_mCount = env->GetFieldID(clazz, "mCount", "I");
+ if (field_mCount == NULL) {
+ LOGE("Can't find MtpPropertyList.mCount");
+ return -1;
+ }
+ field_mResult = env->GetFieldID(clazz, "mResult", "I");
+ if (field_mResult == NULL) {
+ LOGE("Can't find MtpPropertyList.mResult");
+ return -1;
+ }
+ field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
+ if (field_mObjectHandles == NULL) {
+ LOGE("Can't find MtpPropertyList.mObjectHandles");
+ return -1;
+ }
+ field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
+ if (field_mPropertyCodes == NULL) {
+ LOGE("Can't find MtpPropertyList.mPropertyCodes");
+ return -1;
+ }
+ field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
+ if (field_mDataTypes == NULL) {
+ LOGE("Can't find MtpPropertyList.mDataTypes");
+ return -1;
+ }
+ field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
+ if (field_mLongValues == NULL) {
+ LOGE("Can't find MtpPropertyList.mLongValues");
+ return -1;
+ }
+ field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
+ if (field_mStringValues == NULL) {
+ LOGE("Can't find MtpPropertyList.mStringValues");
+ return -1;
+ }
+
return AndroidRuntime::registerNativeMethods(env,
"android/media/MtpDatabase", gMethods, NELEM(gMethods));
}