Merge "Add moveObject method to change object's path and parent." am: 33a200e572 am: 0f09ac317d am: f9696617bd
am: 3a13ab1fd3
Change-Id: I58a1ca9b3b5e63e73eb4db58ac3588f6bf9e3249
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 80fd5c0..17b2326 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -845,6 +845,33 @@
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 5b874cd..7225f10 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -68,6 +68,7 @@
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 @@
virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
+ virtual MtpResponseCode moveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+ MtpString& newPath);
+
virtual void sessionStarted();
virtual void sessionEnded();
@@ -995,6 +999,18 @@
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;
@@ -1360,6 +1376,11 @@
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");