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

Commit 952558d4 authored by Jerry Zhang's avatar Jerry Zhang
Browse files

Add moveObject method to change object's path and parent.

This is needed to implement the MTP MOVE_OBJECT operation.

Bug: 66679910
Test: Move objects and folders, verify mediastore is consistent
Change-Id: I2f4f0c43134fb3ff82745166c051712cc1736b7f
parent 1211941a
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -838,6 +838,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) {
+21 −0
Original line number Diff line number Diff line
@@ -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");