diff options
| -rw-r--r-- | media/java/android/media/MtpDatabase.java | 78 | ||||
| -rw-r--r-- | media/jni/android_media_MtpDatabase.cpp | 6 |
2 files changed, 82 insertions, 2 deletions
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java index fa015cc67b2d..a12ab3888758 100644 --- a/media/java/android/media/MtpDatabase.java +++ b/media/java/android/media/MtpDatabase.java @@ -31,6 +31,8 @@ import android.provider.MediaStore.MediaColumns; import android.provider.Mtp; import android.util.Log; +import java.io.File; + /** * {@hide} */ @@ -57,6 +59,11 @@ public class MtpDatabase { private static final String[] ID_PROJECTION = new String[] { Files.FileColumns._ID, // 0 }; + private static final String[] PATH_FORMAT_PROJECTION = new String[] { + Files.FileColumns._ID, // 0 + Files.FileColumns.DATA, // 1 + Files.FileColumns.FORMAT, // 2 + }; private static final String[] PATH_SIZE_PROJECTION = new String[] { Files.FileColumns._ID, // 0 Files.FileColumns.DATA, // 1 @@ -467,6 +474,68 @@ public class MtpDatabase { return path.substring(start, end); } + private int renameFile(int handle, String newName) { + Cursor c = null; + + // first compute current path + String path = null; + int format = 0; + String[] whereArgs = new String[] { Integer.toString(handle) }; + try { + c = mMediaProvider.query(mObjectsUri, PATH_FORMAT_PROJECTION, ID_WHERE, whereArgs, null); + if (c != null && c.moveToNext()) { + path = c.getString(1); + format = c.getInt(2); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in getObjectFilePath", e); + return MtpConstants.RESPONSE_GENERAL_ERROR; + } finally { + if (c != null) { + c.close(); + } + } + if (path == null) { + return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; + } + if (format == MtpConstants.FORMAT_ASSOCIATION) { + // Only files can be renamed + return MtpConstants.RESPONSE_ACCESS_DENIED; + } + + // now rename the file. make sure this succeeds before updating database + File oldFile = new File(path); + int lastSlash = path.lastIndexOf('/'); + if (lastSlash <= 1) { + return MtpConstants.RESPONSE_GENERAL_ERROR; + } + String newPath = path.substring(0, lastSlash + 1) + newName; + File newFile = new File(newPath); + boolean success = oldFile.renameTo(newFile); + Log.d(TAG, "renaming "+ path + " to " + newPath + (success ? " succeeded" : " failed")); + if (!success) { + return MtpConstants.RESPONSE_GENERAL_ERROR; + } + + // finally update database + ContentValues values = new ContentValues(); + values.put(Files.FileColumns.DATA, newPath); + int updated = 0; + try { + updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in mMediaProvider.update", e); + } + if (updated != 1) { + Log.e(TAG, "Unable to update path for " + path + " to " + newPath); + // this shouldn't happen, but if it does we need to rename the file to its original name + newFile.renameTo(oldFile); + return MtpConstants.RESPONSE_GENERAL_ERROR; + } + + return MtpConstants.RESPONSE_OK; + } + private int getObjectProperty(int handle, int property, long[] outIntValue, char[] outStringValue) { Log.d(TAG, "getObjectProperty: " + property); @@ -605,7 +674,14 @@ public class MtpDatabase { private int setObjectProperty(int handle, int property, long intValue, String stringValue) { Log.d(TAG, "setObjectProperty: " + property); - return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; + + switch (property) { + case MtpConstants.PROPERTY_OBJECT_FILE_NAME: + return renameFile(handle, stringValue); + + default: + return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; + } } private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp index d6bf6094bc7b..8ae7984e9870 100644 --- a/media/jni/android_media_MtpDatabase.cpp +++ b/media/jni/android_media_MtpDatabase.cpp @@ -804,7 +804,6 @@ MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, result = new MtpProperty(property, MTP_TYPE_UINT128); break; case MTP_PROPERTY_NAME: - case MTP_PROPERTY_OBJECT_FILE_NAME: case MTP_PROPERTY_DATE_MODIFIED: case MTP_PROPERTY_DISPLAY_NAME: case MTP_PROPERTY_DATE_ADDED: @@ -817,6 +816,11 @@ MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, case MTP_PROPERTY_DESCRIPTION: result = new MtpProperty(property, MTP_TYPE_STR); break; + case MTP_PROPERTY_OBJECT_FILE_NAME: + // We allow renaming files but not folders + result = new MtpProperty(property, MTP_TYPE_STR, + format != MTP_FORMAT_ASSOCIATION); + break; } return result; |