diff options
4 files changed, 116 insertions, 10 deletions
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java index bbb8063b4832..9a63642edd2a 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java @@ -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); + } } diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java index f803744d6ba8..5057451711a0 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java @@ -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) { diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java index 2a612cb643be..3fad63fa98e8 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java @@ -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; + } } } } diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java index 43f4bb2d8649..48bc3b59d3b0 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java @@ -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)) { @@ -98,6 +103,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; final int[] result = new int[mOpenedDevices.size()]; |