Loading media/java/android/media/MtpDatabase.java +91 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.ContentValues; import android.content.IContentProvider; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.RemoteException; import android.provider.MediaStore.Audio; Loading @@ -44,6 +45,10 @@ public class MtpDatabase { // true if the database has been modified in the current MTP session private boolean mDatabaseModified; // database for writable MTP device properties private SQLiteDatabase mDevicePropDb; private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1; // FIXME - this should be passed in via the constructor private final int mStorageID = 0x00010001; Loading @@ -69,6 +74,9 @@ public class MtpDatabase { private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " + MtpObjects.ObjectColumns.FORMAT + "=?"; private static final String[] DEVICE_PROPERTY_PROJECTION = new String[] { "_id", "value" }; private static final String DEVICE_PROPERTY_WHERE = "code=?"; private final MediaScanner mMediaScanner; static { Loading @@ -83,6 +91,7 @@ public class MtpDatabase { mVolumeName = volumeName; mObjectsUri = MtpObjects.getContentUri(volumeName); mMediaScanner = new MediaScanner(context); openDevicePropertiesDatabase(context); } @Override Loading @@ -94,6 +103,22 @@ public class MtpDatabase { } } private void openDevicePropertiesDatabase(Context context) { mDevicePropDb = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null); int version = mDevicePropDb.getVersion(); // initialize if necessary if (version != DEVICE_PROPERTIES_DATABASE_VERSION) { mDevicePropDb.execSQL("CREATE TABLE properties (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "code INTEGER UNIQUE ON CONFLICT REPLACE," + "value TEXT" + ");"); mDevicePropDb.execSQL("CREATE INDEX property_index ON properties (code);"); mDevicePropDb.setVersion(DEVICE_PROPERTIES_DATABASE_VERSION); } } private int beginSendObject(String path, int format, int parent, int storage, long size, long modified) { mDatabaseModified = true; Loading Loading @@ -257,8 +282,10 @@ public class MtpDatabase { } private int[] getSupportedDeviceProperties() { // no device properties yet return null; return new int[] { MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, }; } private int getObjectProperty(int handle, int property, Loading Loading @@ -342,6 +369,68 @@ public class MtpDatabase { return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; } private int setObjectProperty(int handle, int property, long intValue, String stringValue) { Log.d(TAG, "setObjectProperty: " + property); return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; } private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { Log.d(TAG, "getDeviceProperty: " + property); switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in our device property database Cursor c = null; try { c = mDevicePropDb.query("properties", DEVICE_PROPERTY_PROJECTION, DEVICE_PROPERTY_WHERE, new String[] { Integer.toString(property) }, null, null, null); if (c != null && c.moveToNext()) { String value = c.getString(1); int length = value.length(); if (length > 255) { length = 255; } value.getChars(0, length, outStringValue, 0); outStringValue[length] = 0; } else { outStringValue[0] = 0; } return MtpConstants.RESPONSE_OK; } finally { if (c != null) { c.close(); } } } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; } private int setDeviceProperty(int property, long intValue, String stringValue) { Log.d(TAG, "setDeviceProperty: " + property + " : " + stringValue); switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in our device property database try { ContentValues values = new ContentValues(); values.put("code", property); values.put("value", stringValue); mDevicePropDb.insert("properties", "code", values); return MtpConstants.RESPONSE_OK; } catch (Exception e) { return MtpConstants.RESPONSE_GENERAL_ERROR; } } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; } private boolean getObjectInfo(int handle, int[] outStorageFormatParent, char[] outName, long[] outSizeModified) { Log.d(TAG, "getObjectInfo: " + handle); Loading media/jni/android_media_MtpDatabase.cpp +226 −15 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "MtpDatabase.h" #include "MtpDataPacket.h" #include "MtpProperty.h" #include "MtpStringBuffer.h" #include "MtpUtils.h" #include "mtp.h" Loading @@ -47,6 +48,8 @@ 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_getObjectInfo; static jmethodID method_getObjectFilePath; static jmethodID method_deleteFile; Loading Loading @@ -127,7 +130,8 @@ public: int64_t& fileLength); virtual MtpResponseCode deleteFile(MtpObjectHandle handle); bool getPropertyInfo(MtpObjectProperty property, int& type); bool getObjectPropertyInfo(MtpObjectProperty property, int& type); bool getDevicePropertyInfo(MtpDeviceProperty property, int& type); virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle); Loading Loading @@ -323,14 +327,16 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, MtpDataPacket& packet) { int type; if (!getPropertyInfo(property, type)) return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE; 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) if (result != MTP_RESPONSE_OK) { checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0); jlong longValue = longValues[0]; Loading Loading @@ -384,8 +390,8 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, break; } default: LOGE("unsupported object type\n"); return MTP_RESPONSE_INVALID_OBJECT_HANDLE; LOGE("unsupported type in getObjectPropertyValue\n"); return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } checkAndClearExceptionFromCallback(env, __FUNCTION__); Loading @@ -395,17 +401,179 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, MtpDataPacket& packet) { return -1; int type; if (!getObjectPropertyInfo(property, type)) return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; JNIEnv* env = AndroidRuntime::getJNIEnv(); jlong longValue = 0; jstring stringValue = NULL; switch (type) { case MTP_TYPE_INT8: longValue = packet.getInt8(); break; case MTP_TYPE_UINT8: longValue = packet.getUInt8(); break; case MTP_TYPE_INT16: longValue = packet.getInt16(); break; case MTP_TYPE_UINT16: longValue = packet.getUInt16(); break; case MTP_TYPE_INT32: longValue = packet.getInt32(); break; case MTP_TYPE_UINT32: longValue = packet.getUInt32(); break; case MTP_TYPE_INT64: longValue = packet.getInt64(); break; case MTP_TYPE_UINT64: longValue = packet.getUInt64(); break; case MTP_TYPE_STR: { MtpStringBuffer buffer; packet.getString(buffer); stringValue = env->NewStringUTF((const char *)buffer); break; } default: LOGE("unsupported type in getObjectPropertyValue\n"); return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } jint result = env->CallIntMethod(mDatabase, method_setObjectProperty, (jint)handle, (jint)property, longValue, stringValue); checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) { return -1; int type; if (!getDevicePropertyInfo(property, type)) return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; JNIEnv* env = AndroidRuntime::getJNIEnv(); 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: LOGE("unsupported type in getDevicePropertyValue\n"); return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT; } checkAndClearExceptionFromCallback(env, __FUNCTION__); return MTP_RESPONSE_OK; } MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) { return -1; int type; if (!getDevicePropertyInfo(property, type)) return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; JNIEnv* env = AndroidRuntime::getJNIEnv(); jlong longValue = 0; jstring stringValue = NULL; switch (type) { case MTP_TYPE_INT8: longValue = packet.getInt8(); break; case MTP_TYPE_UINT8: longValue = packet.getUInt8(); break; case MTP_TYPE_INT16: longValue = packet.getInt16(); break; case MTP_TYPE_UINT16: longValue = packet.getUInt16(); break; case MTP_TYPE_INT32: longValue = packet.getInt32(); break; case MTP_TYPE_UINT32: longValue = packet.getUInt32(); break; case MTP_TYPE_INT64: longValue = packet.getInt64(); break; case MTP_TYPE_UINT64: longValue = packet.getUInt64(); break; case MTP_TYPE_STR: { MtpStringBuffer buffer; packet.getString(buffer); stringValue = env->NewStringUTF((const char *)buffer); break; } default: LOGE("unsupported type in setDevicePropertyValue\n"); return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty, (jint)property, longValue, stringValue); checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) { Loading Loading @@ -473,8 +641,10 @@ MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, JNIEnv* env = AndroidRuntime::getJNIEnv(); jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath, (jint)handle, mStringBuffer, mLongBuffer); if (result != MTP_RESPONSE_OK) if (result != MTP_RESPONSE_OK) { checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } jchar* str = env->GetCharArrayElements(mStringBuffer, 0); filePath.setTo(str, strlen16(str)); Loading @@ -501,7 +671,7 @@ struct PropertyTableEntry { int type; }; static const PropertyTableEntry kPropertyTable[] = { static const PropertyTableEntry kObjectPropertyTable[] = { { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 }, { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 }, { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 }, Loading @@ -510,9 +680,26 @@ static const PropertyTableEntry kPropertyTable[] = { { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR }, }; bool MyMtpDatabase::getPropertyInfo(MtpObjectProperty property, int& type) { int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]); const PropertyTableEntry* entry = kPropertyTable; static const PropertyTableEntry kDevicePropertyTable[] = { { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR }, { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR }, }; bool MyMtpDatabase::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 MyMtpDatabase::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; Loading Loading @@ -587,7 +774,16 @@ MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, } MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { return NULL; MtpProperty* result = NULL; switch (property) { case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writeable string properties result = new MtpProperty(property, MTP_TYPE_STR, true); break; } return result; } void MyMtpDatabase::sessionStarted() { Loading Loading @@ -695,6 +891,21 @@ int register_android_media_MtpDatabase(JNIEnv *env) 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"); return -1; } method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I"); if (method_getDeviceProperty == NULL) { LOGE("Can't find getDeviceProperty"); return -1; } method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I"); if (method_setDeviceProperty == NULL) { LOGE("Can't find setDeviceProperty"); return -1; } method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z"); if (method_getObjectInfo == NULL) { LOGE("Can't find getObjectInfo"); Loading media/mtp/MtpDevice.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -342,7 +342,7 @@ MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpProperty* property = new MtpProperty; property->read(mData, true); property->read(mData); return property; } return NULL; Loading media/mtp/MtpProperty.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -120,7 +120,7 @@ MtpProperty::~MtpProperty() { delete[] mEnumValues; } void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { void MtpProperty::read(MtpDataPacket& packet) { mCode = packet.getUInt16(); mType = packet.getUInt16(); Loading @@ -141,7 +141,7 @@ void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { break; default: readValue(packet, mDefaultValue); if (deviceProp) if (isDeviceProperty()) readValue(packet, mCurrentValue); } mGroupCode = packet.getUInt32(); Loading @@ -159,7 +159,6 @@ void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { } } // FIXME - only works for object properties void MtpProperty::write(MtpDataPacket& packet) { packet.putUInt16(mCode); packet.putUInt16(mType); Loading media/mtp/MtpProperty.h +8 −2 Original line number Diff line number Diff line Loading @@ -65,16 +65,22 @@ public: inline MtpPropertyCode getPropertyCode() const { return mCode; } void read(MtpDataPacket& packet, bool deviceProp); void read(MtpDataPacket& packet); void write(MtpDataPacket& packet); void print(); inline bool isDeviceProperty() const { return ( ((mCode & 0xF000) == 0x5000) || ((mCode & 0xF800) == 0xD000)); } private: void readValue(MtpDataPacket& packet, MtpPropertyValue& value); void writeValue(MtpDataPacket& packet, MtpPropertyValue& value); MtpPropertyValue* readArrayValues(MtpDataPacket& packet, int& length); void writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length); void writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length); }; }; // namespace android Loading Loading
media/java/android/media/MtpDatabase.java +91 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.ContentValues; import android.content.IContentProvider; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.RemoteException; import android.provider.MediaStore.Audio; Loading @@ -44,6 +45,10 @@ public class MtpDatabase { // true if the database has been modified in the current MTP session private boolean mDatabaseModified; // database for writable MTP device properties private SQLiteDatabase mDevicePropDb; private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1; // FIXME - this should be passed in via the constructor private final int mStorageID = 0x00010001; Loading @@ -69,6 +74,9 @@ public class MtpDatabase { private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " + MtpObjects.ObjectColumns.FORMAT + "=?"; private static final String[] DEVICE_PROPERTY_PROJECTION = new String[] { "_id", "value" }; private static final String DEVICE_PROPERTY_WHERE = "code=?"; private final MediaScanner mMediaScanner; static { Loading @@ -83,6 +91,7 @@ public class MtpDatabase { mVolumeName = volumeName; mObjectsUri = MtpObjects.getContentUri(volumeName); mMediaScanner = new MediaScanner(context); openDevicePropertiesDatabase(context); } @Override Loading @@ -94,6 +103,22 @@ public class MtpDatabase { } } private void openDevicePropertiesDatabase(Context context) { mDevicePropDb = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null); int version = mDevicePropDb.getVersion(); // initialize if necessary if (version != DEVICE_PROPERTIES_DATABASE_VERSION) { mDevicePropDb.execSQL("CREATE TABLE properties (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "code INTEGER UNIQUE ON CONFLICT REPLACE," + "value TEXT" + ");"); mDevicePropDb.execSQL("CREATE INDEX property_index ON properties (code);"); mDevicePropDb.setVersion(DEVICE_PROPERTIES_DATABASE_VERSION); } } private int beginSendObject(String path, int format, int parent, int storage, long size, long modified) { mDatabaseModified = true; Loading Loading @@ -257,8 +282,10 @@ public class MtpDatabase { } private int[] getSupportedDeviceProperties() { // no device properties yet return null; return new int[] { MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, }; } private int getObjectProperty(int handle, int property, Loading Loading @@ -342,6 +369,68 @@ public class MtpDatabase { return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; } private int setObjectProperty(int handle, int property, long intValue, String stringValue) { Log.d(TAG, "setObjectProperty: " + property); return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; } private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { Log.d(TAG, "getDeviceProperty: " + property); switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in our device property database Cursor c = null; try { c = mDevicePropDb.query("properties", DEVICE_PROPERTY_PROJECTION, DEVICE_PROPERTY_WHERE, new String[] { Integer.toString(property) }, null, null, null); if (c != null && c.moveToNext()) { String value = c.getString(1); int length = value.length(); if (length > 255) { length = 255; } value.getChars(0, length, outStringValue, 0); outStringValue[length] = 0; } else { outStringValue[0] = 0; } return MtpConstants.RESPONSE_OK; } finally { if (c != null) { c.close(); } } } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; } private int setDeviceProperty(int property, long intValue, String stringValue) { Log.d(TAG, "setDeviceProperty: " + property + " : " + stringValue); switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in our device property database try { ContentValues values = new ContentValues(); values.put("code", property); values.put("value", stringValue); mDevicePropDb.insert("properties", "code", values); return MtpConstants.RESPONSE_OK; } catch (Exception e) { return MtpConstants.RESPONSE_GENERAL_ERROR; } } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; } private boolean getObjectInfo(int handle, int[] outStorageFormatParent, char[] outName, long[] outSizeModified) { Log.d(TAG, "getObjectInfo: " + handle); Loading
media/jni/android_media_MtpDatabase.cpp +226 −15 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "MtpDatabase.h" #include "MtpDataPacket.h" #include "MtpProperty.h" #include "MtpStringBuffer.h" #include "MtpUtils.h" #include "mtp.h" Loading @@ -47,6 +48,8 @@ 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_getObjectInfo; static jmethodID method_getObjectFilePath; static jmethodID method_deleteFile; Loading Loading @@ -127,7 +130,8 @@ public: int64_t& fileLength); virtual MtpResponseCode deleteFile(MtpObjectHandle handle); bool getPropertyInfo(MtpObjectProperty property, int& type); bool getObjectPropertyInfo(MtpObjectProperty property, int& type); bool getDevicePropertyInfo(MtpDeviceProperty property, int& type); virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle); Loading Loading @@ -323,14 +327,16 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, MtpDataPacket& packet) { int type; if (!getPropertyInfo(property, type)) return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE; 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) if (result != MTP_RESPONSE_OK) { checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0); jlong longValue = longValues[0]; Loading Loading @@ -384,8 +390,8 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, break; } default: LOGE("unsupported object type\n"); return MTP_RESPONSE_INVALID_OBJECT_HANDLE; LOGE("unsupported type in getObjectPropertyValue\n"); return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } checkAndClearExceptionFromCallback(env, __FUNCTION__); Loading @@ -395,17 +401,179 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, MtpDataPacket& packet) { return -1; int type; if (!getObjectPropertyInfo(property, type)) return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; JNIEnv* env = AndroidRuntime::getJNIEnv(); jlong longValue = 0; jstring stringValue = NULL; switch (type) { case MTP_TYPE_INT8: longValue = packet.getInt8(); break; case MTP_TYPE_UINT8: longValue = packet.getUInt8(); break; case MTP_TYPE_INT16: longValue = packet.getInt16(); break; case MTP_TYPE_UINT16: longValue = packet.getUInt16(); break; case MTP_TYPE_INT32: longValue = packet.getInt32(); break; case MTP_TYPE_UINT32: longValue = packet.getUInt32(); break; case MTP_TYPE_INT64: longValue = packet.getInt64(); break; case MTP_TYPE_UINT64: longValue = packet.getUInt64(); break; case MTP_TYPE_STR: { MtpStringBuffer buffer; packet.getString(buffer); stringValue = env->NewStringUTF((const char *)buffer); break; } default: LOGE("unsupported type in getObjectPropertyValue\n"); return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } jint result = env->CallIntMethod(mDatabase, method_setObjectProperty, (jint)handle, (jint)property, longValue, stringValue); checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) { return -1; int type; if (!getDevicePropertyInfo(property, type)) return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; JNIEnv* env = AndroidRuntime::getJNIEnv(); 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: LOGE("unsupported type in getDevicePropertyValue\n"); return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT; } checkAndClearExceptionFromCallback(env, __FUNCTION__); return MTP_RESPONSE_OK; } MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) { return -1; int type; if (!getDevicePropertyInfo(property, type)) return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; JNIEnv* env = AndroidRuntime::getJNIEnv(); jlong longValue = 0; jstring stringValue = NULL; switch (type) { case MTP_TYPE_INT8: longValue = packet.getInt8(); break; case MTP_TYPE_UINT8: longValue = packet.getUInt8(); break; case MTP_TYPE_INT16: longValue = packet.getInt16(); break; case MTP_TYPE_UINT16: longValue = packet.getUInt16(); break; case MTP_TYPE_INT32: longValue = packet.getInt32(); break; case MTP_TYPE_UINT32: longValue = packet.getUInt32(); break; case MTP_TYPE_INT64: longValue = packet.getInt64(); break; case MTP_TYPE_UINT64: longValue = packet.getUInt64(); break; case MTP_TYPE_STR: { MtpStringBuffer buffer; packet.getString(buffer); stringValue = env->NewStringUTF((const char *)buffer); break; } default: LOGE("unsupported type in setDevicePropertyValue\n"); return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; } jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty, (jint)property, longValue, stringValue); checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) { Loading Loading @@ -473,8 +641,10 @@ MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, JNIEnv* env = AndroidRuntime::getJNIEnv(); jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath, (jint)handle, mStringBuffer, mLongBuffer); if (result != MTP_RESPONSE_OK) if (result != MTP_RESPONSE_OK) { checkAndClearExceptionFromCallback(env, __FUNCTION__); return result; } jchar* str = env->GetCharArrayElements(mStringBuffer, 0); filePath.setTo(str, strlen16(str)); Loading @@ -501,7 +671,7 @@ struct PropertyTableEntry { int type; }; static const PropertyTableEntry kPropertyTable[] = { static const PropertyTableEntry kObjectPropertyTable[] = { { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 }, { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 }, { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 }, Loading @@ -510,9 +680,26 @@ static const PropertyTableEntry kPropertyTable[] = { { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR }, }; bool MyMtpDatabase::getPropertyInfo(MtpObjectProperty property, int& type) { int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]); const PropertyTableEntry* entry = kPropertyTable; static const PropertyTableEntry kDevicePropertyTable[] = { { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR }, { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR }, }; bool MyMtpDatabase::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 MyMtpDatabase::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; Loading Loading @@ -587,7 +774,16 @@ MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, } MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { return NULL; MtpProperty* result = NULL; switch (property) { case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writeable string properties result = new MtpProperty(property, MTP_TYPE_STR, true); break; } return result; } void MyMtpDatabase::sessionStarted() { Loading Loading @@ -695,6 +891,21 @@ int register_android_media_MtpDatabase(JNIEnv *env) 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"); return -1; } method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I"); if (method_getDeviceProperty == NULL) { LOGE("Can't find getDeviceProperty"); return -1; } method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I"); if (method_setDeviceProperty == NULL) { LOGE("Can't find setDeviceProperty"); return -1; } method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z"); if (method_getObjectInfo == NULL) { LOGE("Can't find getObjectInfo"); Loading
media/mtp/MtpDevice.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -342,7 +342,7 @@ MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpProperty* property = new MtpProperty; property->read(mData, true); property->read(mData); return property; } return NULL; Loading
media/mtp/MtpProperty.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -120,7 +120,7 @@ MtpProperty::~MtpProperty() { delete[] mEnumValues; } void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { void MtpProperty::read(MtpDataPacket& packet) { mCode = packet.getUInt16(); mType = packet.getUInt16(); Loading @@ -141,7 +141,7 @@ void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { break; default: readValue(packet, mDefaultValue); if (deviceProp) if (isDeviceProperty()) readValue(packet, mCurrentValue); } mGroupCode = packet.getUInt32(); Loading @@ -159,7 +159,6 @@ void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { } } // FIXME - only works for object properties void MtpProperty::write(MtpDataPacket& packet) { packet.putUInt16(mCode); packet.putUInt16(mType); Loading
media/mtp/MtpProperty.h +8 −2 Original line number Diff line number Diff line Loading @@ -65,16 +65,22 @@ public: inline MtpPropertyCode getPropertyCode() const { return mCode; } void read(MtpDataPacket& packet, bool deviceProp); void read(MtpDataPacket& packet); void write(MtpDataPacket& packet); void print(); inline bool isDeviceProperty() const { return ( ((mCode & 0xF000) == 0x5000) || ((mCode & 0xF800) == 0xD000)); } private: void readValue(MtpDataPacket& packet, MtpPropertyValue& value); void writeValue(MtpDataPacket& packet, MtpPropertyValue& value); MtpPropertyValue* readArrayValues(MtpDataPacket& packet, int& length); void writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length); void writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length); }; }; // namespace android Loading