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

Commit 5fecc6cf authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Implement MtpDocumentsProvider#deleteDocument.

BUG=20274999

Change-Id: I6d07280ddbb0809d3c1334aec5fcbc0c67c4c2aa
parent f86f6fef
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -201,6 +201,20 @@ public class MtpDocumentsProvider extends DocumentsProvider {
        }
    }

    @Override
    public void deleteDocument(String documentId) throws FileNotFoundException {
        try {
            final Identifier identifier = Identifier.createFromDocumentId(documentId);
            final int parentHandle =
                    mMtpManager.getParent(identifier.mDeviceId, identifier.mObjectHandle);
            mMtpManager.deleteDocument(identifier.mDeviceId, identifier.mObjectHandle);
            notifyChildDocumentsChange(new Identifier(
                    identifier.mDeviceId, identifier.mStorageId, parentHandle).toDocumentId());
        } catch (IOException error) {
            throw new FileNotFoundException(error.getMessage());
        }
    }

    boolean hasOpenedDevices() {
        return mMtpManager.getOpenedDeviceIds().length != 0;
    }
@@ -209,4 +223,11 @@ public class MtpDocumentsProvider extends DocumentsProvider {
        mResolver.notifyChange(
                DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY), null, false);
    }

    private void notifyChildDocumentsChange(String parentDocumentId) {
        mResolver.notifyChange(
                DocumentsContract.buildChildDocumentsUri(AUTHORITY, parentDocumentId),
                null,
                false);
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.hardware.usb.UsbManager;
import android.mtp.MtpDevice;
import android.util.SparseArray;

import java.io.FileNotFoundException;
import java.io.IOException;

/**
@@ -109,6 +110,22 @@ class MtpManager {
        return device.getObject(objectHandle, expectedSize);
    }

    synchronized void deleteDocument(int deviceId, int objectHandle) throws IOException {
        final MtpDevice device = getDevice(deviceId);
        if (!device.deleteObject(objectHandle)) {
            throw new IOException("Failed to delete document");
        }
    }

    synchronized int getParent(int deviceId, int objectHandle) throws IOException {
        final MtpDevice device = getDevice(deviceId);
        final int result = (int) device.getParent(objectHandle);
        if (result < 0) {
            throw new FileNotFoundException("Not found parent object");
        }
        return result;
    }

    private MtpDevice getDevice(int deviceId) throws IOException {
        final MtpDevice device = mDevices.get(deviceId);
        if (device == null) {
+53 −10
Original line number Diff line number Diff line
@@ -25,8 +25,11 @@ import android.test.AndroidTestCase;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.SmallTest;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@SmallTest
public class MtpDocumentsProviderTest extends AndroidTestCase {
@@ -43,14 +46,16 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
    }

    public void testOpenAndCloseDevice() throws Exception {
        final Uri uri = DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);

        mMtpManager.addValidDevice(0);
        assertEquals(0, mResolver.changeCount);
        assertEquals(0, mResolver.getChangeCount(uri));

        mProvider.openDevice(0);
        assertEquals(1, mResolver.changeCount);
        assertEquals(1, mResolver.getChangeCount(uri));

        mProvider.closeDevice(0);
        assertEquals(2, mResolver.changeCount);
        assertEquals(2, mResolver.getChangeCount(uri));

        int exceptionCounter = 0;
        try {
@@ -58,27 +63,29 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
        } catch (IOException error) {
            exceptionCounter++;
        }
        assertEquals(2, mResolver.changeCount);
        assertEquals(2, mResolver.getChangeCount(uri));
        try {
            mProvider.closeDevice(1);
        } catch (IOException error) {
            exceptionCounter++;
        }
        assertEquals(2, mResolver.changeCount);
        assertEquals(2, mResolver.getChangeCount(uri));
        assertEquals(2, exceptionCounter);
    }

    public void testCloseAllDevices() throws IOException {
        final Uri uri = DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);

        mMtpManager.addValidDevice(0);

        mProvider.closeAllDevices();
        assertEquals(0, mResolver.changeCount);
        assertEquals(0, mResolver.getChangeCount(uri));

        mProvider.openDevice(0);
        assertEquals(1, mResolver.changeCount);
        assertEquals(1, mResolver.getChangeCount(uri));

        mProvider.closeAllDevices();
        assertEquals(2, mResolver.changeCount);
        assertEquals(2, mResolver.getChangeCount(uri));
    }

    public void testQueryRoots() throws Exception {
@@ -210,12 +217,48 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
        assertEquals(3072, cursor.getInt(5));
    }

    public void testDeleteDocument() throws FileNotFoundException {
        mMtpManager.setDocument(0, 1, new MtpDocument(
                1 /* object handle */,
                0x3801 /* JPEG */,
                "image.jpg" /* display name */,
                new Date(1422716400000L) /* modified date */,
                1024 * 1024 * 5 /* file size */,
                1024 * 50 /* thumbnail size */));
        mMtpManager.setParent(0, 1, 2);
        mProvider.deleteDocument("0_0_1");
        assertEquals(1, mResolver.getChangeCount(
                DocumentsContract.buildChildDocumentsUri(
                        MtpDocumentsProvider.AUTHORITY, "0_0_2")));
    }

    public void testDeleteDocument_error() throws FileNotFoundException {
        mMtpManager.setParent(0, 1, 2);
        try {
            mProvider.deleteDocument("0_0_1");
            fail();
        } catch (Throwable e) {
            assertTrue(e instanceof IOException);
        }
        assertEquals(0, mResolver.getChangeCount(
                DocumentsContract.buildChildDocumentsUri(
                        MtpDocumentsProvider.AUTHORITY, "0_0_2")));
    }

    private static class ContentResolver extends MockContentResolver {
        int changeCount = 0;
        final Map<Uri, Integer> mChangeCounts = new HashMap<Uri, Integer>();

        @Override
        public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
            changeCount++;
            mChangeCounts.put(uri, getChangeCount(uri) + 1);
        }

        int getChangeCount(Uri uri) {
            if (mChangeCounts.containsKey(uri)) {
                return mChangeCounts.get(uri);
            } else {
                return 0;
            }
        }
    }
}
+25 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ public class TestMtpManager extends MtpManager {
    private final Map<Integer, MtpRoot[]> mRoots = new HashMap<Integer, MtpRoot[]>();
    private final Map<String, MtpDocument> mDocuments = new HashMap<String, MtpDocument>();
    private final Map<String, byte[]> mObjectBytes = new HashMap<String, byte[]>();
    private final Map<String, Integer> mParents = new HashMap<String, Integer>();

    TestMtpManager(Context context) {
        super(context);
@@ -57,6 +58,10 @@ public class TestMtpManager extends MtpManager {
        mObjectBytes.put(pack(deviceId, objectHandle, expectedSize), bytes);
    }

    void setParent(int deviceId, int objectHandle, int parentObjectHandle) {
        mParents.put(pack(deviceId, objectHandle), parentObjectHandle);
    }

    @Override
    void openDevice(int deviceId) throws IOException {
        if (!mValidDevices.contains(deviceId) || mOpenedDevices.contains(deviceId)) {
@@ -97,6 +102,26 @@ public class TestMtpManager extends MtpManager {
        }
    }

    @Override
    void deleteDocument(int deviceId, int objectHandle) throws IOException {
        final String key = pack(deviceId, objectHandle);
        if (mDocuments.containsKey(key)) {
            mDocuments.remove(key);
        } else {
            throw new IOException();
        }
    }

    @Override
    synchronized int getParent(int deviceId, int objectHandle) throws IOException {
        final String key = pack(deviceId, objectHandle);
        if (mParents.containsKey(key)) {
            return mParents.get(key);
        } else {
            throw new IOException();
        }
    }

    @Override
    int[] getOpenedDeviceIds() {
        int i = 0;