diff options
| -rwxr-xr-x | media/java/android/mtp/MtpDatabase.java | 27 | ||||
| -rw-r--r-- | media/jni/android_mtp_MtpDatabase.cpp | 21 |
2 files changed, 48 insertions, 0 deletions
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index 698c9c96fe01..9f00828a48f3 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -841,6 +841,33 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_OK; } + private int moveObject(int handle, int newParent, String newPath) { + String[] whereArgs = new String[] { Integer.toString(handle) }; + + // do not allow renaming any of the special subdirectories + if (isStorageSubDirectory(newPath)) { + return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED; + } + + // update database + ContentValues values = new ContentValues(); + values.put(Files.FileColumns.DATA, newPath); + values.put(Files.FileColumns.PARENT, newParent); + int updated = 0; + try { + // note - we are relying on a special case in MediaProvider.update() to update + // the paths for all children in the case where this is a directory. + updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in mMediaProvider.update", e); + } + if (updated == 0) { + Log.e(TAG, "Unable to update path for " + handle + " to " + newPath); + return MtpConstants.RESPONSE_GENERAL_ERROR; + } + return MtpConstants.RESPONSE_OK; + } + private int setObjectProperty(int handle, int property, long intValue, String stringValue) { switch (property) { diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index cf4458a6fd49..b9d3d8ffd398 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -68,6 +68,7 @@ static jmethodID method_getObjectPropertyList; static jmethodID method_getObjectInfo; static jmethodID method_getObjectFilePath; static jmethodID method_deleteFile; +static jmethodID method_moveObject; static jmethodID method_getObjectReferences; static jmethodID method_setObjectReferences; static jmethodID method_sessionStarted; @@ -178,6 +179,9 @@ public: virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property); + virtual MtpResponseCode moveObject(MtpObjectHandle handle, MtpObjectHandle newParent, + MtpString& newPath); + virtual void sessionStarted(); virtual void sessionEnded(); @@ -993,6 +997,18 @@ MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) { return result; } +MtpResponseCode MyMtpDatabase::moveObject(MtpObjectHandle handle, MtpObjectHandle newParent, + MtpString &newPath) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + jstring stringValue = env->NewStringUTF((const char *) newPath); + MtpResponseCode result = env->CallIntMethod(mDatabase, method_moveObject, + (jint)handle, (jint)newParent, stringValue); + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(stringValue); + return result; +} + struct PropertyTableEntry { MtpObjectProperty property; int type; @@ -1358,6 +1374,11 @@ int register_android_mtp_MtpDatabase(JNIEnv *env) ALOGE("Can't find deleteFile"); return -1; } + method_moveObject = env->GetMethodID(clazz, "moveObject", "(IILjava/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"); |