Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ebac83e authored by Mike Lockwood's avatar Mike Lockwood
Browse files

MTP: Add support for renaming files



Change-Id: I679d674eb4dae88f60165ab2850cc20eec7ceee3
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 5684d464
Loading
Loading
Loading
Loading
+77 −1
Original line number Diff line number Diff line
@@ -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,8 +674,15 @@ public class MtpDatabase {
    private int setObjectProperty(int handle, int property,
                            long intValue, String stringValue) {
        Log.d(TAG, "setObjectProperty: " + property);

        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) {
        Log.d(TAG, "getDeviceProperty: " + property);
+5 −1
Original line number Diff line number Diff line
@@ -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;