diff options
5 files changed, 351 insertions, 214 deletions
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java index ef1e8e20aaff..90b5c096de20 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java @@ -18,7 +18,6 @@ package com.android.mtp; import android.content.ContentResolver; import android.database.Cursor; -import android.database.sqlite.SQLiteException; import android.mtp.MtpObjectInfo; import android.net.Uri; import android.os.Bundle; @@ -262,31 +261,39 @@ class DocumentLoader { if (objectInfoList.length == 0 || getState() != STATE_LOADING) { return; } - if (mNumLoaded == 0) { - mDatabase.getMapper().startAddingDocuments(mIdentifier.mDocumentId); - } - try { + try{ + if (mNumLoaded == 0) { + mDatabase.getMapper().startAddingDocuments(mIdentifier.mDocumentId); + } mDatabase.getMapper().putChildDocuments( mIdentifier.mDeviceId, mIdentifier.mDocumentId, objectInfoList); mNumLoaded += objectInfoList.length; - } catch (SQLiteException exp) { - mError = exp; - mNumLoaded = 0; - } - if (getState() != STATE_LOADING) { - mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId); + if (getState() != STATE_LOADING) { + mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId); + } + } catch (FileNotFoundException exception) { + setErrorInternal(exception); } } - void setError(Exception message) { + void setError(Exception error) { final int lastState = getState(); - mError = message; - mNumLoaded = 0; + setErrorInternal(error); if (lastState == STATE_LOADING) { - mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId); + try { + mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId); + } catch (FileNotFoundException exception) { + setErrorInternal(exception); + } } } + private void setErrorInternal(Exception error) { + Log.e(MtpDocumentsProvider.TAG, "Error in DocumentLoader thread", error); + mError = error; + mNumLoaded = 0; + } + private Uri createUri() { return DocumentsContract.buildChildDocumentsUri( MtpDocumentsProvider.AUTHORITY, mIdentifier.mDocumentId); diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java index 6af492c6cc09..cf1e1f61be02 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java @@ -27,9 +27,9 @@ import android.mtp.MtpObjectInfo; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; +import java.io.FileNotFoundException; import java.util.HashMap; import java.util.Map; @@ -56,11 +56,12 @@ class Mapper { /** * Puts device information to database. + * * @return If device is added to the database. + * @throws FileNotFoundException */ - synchronized boolean putDeviceDocument(MtpDeviceRecord device) { + synchronized boolean putDeviceDocument(MtpDeviceRecord device) throws FileNotFoundException { final SQLiteDatabase database = mDatabase.getSQLiteDatabase(); - Preconditions.checkState(mMappingMode.containsKey(/* no parent for root */ null)); database.beginTransaction(); try { final ContentValues[] valuesList = new ContentValues[1]; @@ -69,6 +70,7 @@ class Mapper { extraValuesList[0] = new ContentValues(); MtpDatabase.getDeviceDocumentValues(valuesList[0], extraValuesList[0], device); final boolean changed = putDocuments( + null, valuesList, extraValuesList, COLUMN_PARENT_DOCUMENT_ID + " IS NULL", @@ -83,11 +85,14 @@ class Mapper { /** * Puts root information to database. + * * @param parentDocumentId Document ID of device document. * @param roots List of root information. * @return If roots are added or removed from the database. + * @throws FileNotFoundException */ - synchronized boolean putStorageDocuments(String parentDocumentId, MtpRoot[] roots) { + synchronized boolean putStorageDocuments(String parentDocumentId, MtpRoot[] roots) + throws FileNotFoundException { final SQLiteDatabase database = mDatabase.getSQLiteDatabase(); database.beginTransaction(); try { @@ -112,6 +117,7 @@ class Mapper { valuesList[i], extraValuesList[i], parentDocumentId, roots[i]); } final boolean changed = putDocuments( + parentDocumentId, valuesList, extraValuesList, COLUMN_PARENT_DOCUMENT_ID + "=?", @@ -127,11 +133,14 @@ class Mapper { /** * Puts document information to database. + * * @param deviceId Device ID * @param parentId Parent document ID. * @param documents List of document information. + * @throws FileNotFoundException */ - synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) { + synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) + throws FileNotFoundException { final String mapColumn; Preconditions.checkState(mMappingMode.containsKey(parentId)); switch (mMappingMode.get(parentId)) { @@ -151,6 +160,7 @@ class Mapper { valuesList[i], deviceId, parentId, documents[i]); } putDocuments( + parentId, valuesList, null, COLUMN_PARENT_DOCUMENT_ID + "=?", @@ -181,9 +191,9 @@ class Mapper { * a corresponding existing row. Otherwise it does heuristic. * * @param parentDocumentId Parent document ID or NULL for root documents. + * @throws FileNotFoundException */ - void startAddingDocuments(@Nullable String parentDocumentId) { - Preconditions.checkState(!mMappingMode.containsKey(parentDocumentId)); + void startAddingDocuments(@Nullable String parentDocumentId) throws FileNotFoundException { final String selection; final String[] args; if (parentDocumentId != null) { @@ -197,6 +207,9 @@ class Mapper { final SQLiteDatabase database = mDatabase.getSQLiteDatabase(); database.beginTransaction(); try { + getParentOrHaltMapping(parentDocumentId); + Preconditions.checkState(!mMappingMode.containsKey(parentDocumentId)); + // Set all documents as invalidated. final ContentValues values = new ContentValues(); values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED); @@ -224,22 +237,27 @@ class Mapper { * {@link #stopAddingDocuments(String)} turns the pending rows into 'valid' * rows. If the methods adds rows to database, it updates valueList with correct document ID. * + * @param parentId Parent document ID. * @param valuesList Values for documents to be stored in the database. * @param rootExtraValuesList Values for root extra to be stored in the database. * @param selection SQL where closure to select rows that shares the same parent. * @param args Argument for selection SQL. - * @return Whether the method adds new rows. + * @return Whether it adds at least one new row that is not mapped with existing document ID. + * @throws FileNotFoundException When parentId is not registered in the database. */ private boolean putDocuments( + String parentId, ContentValues[] valuesList, @Nullable ContentValues[] rootExtraValuesList, String selection, String[] args, - String mappingKey) { + String mappingKey) throws FileNotFoundException { final SQLiteDatabase database = mDatabase.getSQLiteDatabase(); boolean added = false; database.beginTransaction(); try { + getParentOrHaltMapping(parentId); + Preconditions.checkState(mMappingMode.containsKey(parentId)); for (int i = 0; i < valuesList.length; i++) { final ContentValues values = valuesList[i]; final ContentValues rootExtraValues; @@ -298,11 +316,12 @@ class Mapper { * Maps 'pending' document and 'invalidated' document that shares the same column of groupKey. * If the database does not find corresponding 'invalidated' document, it just removes * 'invalidated' document from the database. + * * @param parentId Parent document ID or null for root documents. * @return Whether the methods adds or removed visible rows. + * @throws FileNotFoundException */ - boolean stopAddingDocuments(@Nullable String parentId) { - Preconditions.checkState(mMappingMode.containsKey(parentId)); + boolean stopAddingDocuments(@Nullable String parentId) throws FileNotFoundException { final String selection; final String[] args; if (parentId != null) { @@ -312,12 +331,15 @@ class Mapper { selection = COLUMN_PARENT_DOCUMENT_ID + " IS NULL"; args = EMPTY_ARGS; } - mMappingMode.remove(parentId); + final SQLiteDatabase database = mDatabase.getSQLiteDatabase(); database.beginTransaction(); try { - boolean changed = false; + getParentOrHaltMapping(parentId); + Preconditions.checkState(mMappingMode.containsKey(parentId)); + mMappingMode.remove(parentId); + boolean changed = false; // Delete all invalidated rows that cannot be mapped. if (mDatabase.deleteDocumentsAndRootsRecursively( COLUMN_ROW_STATE + " = ? AND " + selection, @@ -331,4 +353,25 @@ class Mapper { database.endTransaction(); } } + + /** + * Returns the parent identifier from parent document ID if the parent ID is found in the + * database. Otherwise it halts mapping and throws FileNotFoundException. + * + * @param parentId Parent document ID + * @return Parent identifier + * @throws FileNotFoundException + */ + private @Nullable Identifier getParentOrHaltMapping( + @Nullable String parentId) throws FileNotFoundException { + if (parentId == null) { + return null; + } + try { + return mDatabase.createIdentifier(parentId); + } catch (FileNotFoundException error) { + mMappingMode.remove(parentId); + throw error; + } + } } diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java index a4c3cf4fa5b4..cec2b4dba7b3 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java @@ -22,6 +22,7 @@ import android.os.Process; import android.provider.DocumentsContract; import android.util.Log; +import java.io.FileNotFoundException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -123,14 +124,22 @@ final class RootScanner { // Update devices. final MtpDeviceRecord[] devices = mManager.getDevices(); - mDatabase.getMapper().startAddingDocuments(null /* parentDocumentId */); - for (final MtpDeviceRecord device : devices) { - if (mDatabase.getMapper().putDeviceDocument(device)) { + try { + mDatabase.getMapper().startAddingDocuments(null /* parentDocumentId */); + for (final MtpDeviceRecord device : devices) { + if (mDatabase.getMapper().putDeviceDocument(device)) { + changed = true; + } + } + if (mDatabase.getMapper().stopAddingDocuments( + null /* parentDocumentId */)) { changed = true; } - } - if (mDatabase.getMapper().stopAddingDocuments(null /* parentDocumentId */)) { - changed = true; + } catch (FileNotFoundException exception) { + // The top root (ID is null) must exist always. + // FileNotFoundException is unexpected. + Log.e(MtpDocumentsProvider.TAG, "Unexpected FileNotFoundException", exception); + throw new AssertionError("Unexpected exception for the top parent", exception); } // Update roots. @@ -139,12 +148,17 @@ final class RootScanner { if (documentId == null) { continue; } - mDatabase.getMapper().startAddingDocuments(documentId); - if (mDatabase.getMapper().putStorageDocuments(documentId, device.roots)) { - changed = true; - } - if (mDatabase.getMapper().stopAddingDocuments(documentId)) { - changed = true; + try { + mDatabase.getMapper().startAddingDocuments(documentId); + if (mDatabase.getMapper().putStorageDocuments(documentId, device.roots)) { + changed = true; + } + if (mDatabase.getMapper().stopAddingDocuments(documentId)) { + changed = true; + } + } catch (FileNotFoundException exception) { + Log.e(MtpDocumentsProvider.TAG, "Parent document is gone.", exception); + continue; } } diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java index af1fed49f272..6e28e33e8520 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java @@ -36,16 +36,23 @@ public class DocumentLoaderTest extends AndroidTestCase { private TestContentResolver mResolver; private DocumentLoader mLoader; final private Identifier mParentIdentifier = new Identifier( - 0, 0, 0, "1", MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE); + 0, 0, 0, "2", MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE); @Override - public void setUp() { + public void setUp() throws Exception { mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { + + mDatabase.getMapper().startAddingDocuments(null); + mDatabase.getMapper().putDeviceDocument( + new MtpDeviceRecord(1, "Device", true, new MtpRoot[0], null, null)); + mDatabase.getMapper().stopAddingDocuments(null); + + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") }); - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + mDatabase.getMapper().stopAddingDocuments("1"); + mManager = new BlockableTestMtpManager(getContext()); mResolver = new TestContentResolver(); mLoader = new DocumentLoader(mManager, mResolver, mDatabase); diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java index a75012e53da2..ea52957771ec 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java @@ -138,8 +138,10 @@ public class MtpDatabaseTest extends AndroidTestCase { } public void testPutStorageDocuments() throws Exception { - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { + addTestDevice(); + + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 1, "Storage", 1000, 2000, ""), new MtpRoot(0, 2, "Storage", 2000, 4000, ""), new MtpRoot(0, 3, "/@#%&<>Storage", 3000, 6000,"") @@ -150,7 +152,7 @@ public class MtpDatabaseTest extends AndroidTestCase { assertEquals(3, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID)); assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID)); assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE)); @@ -165,11 +167,11 @@ public class MtpDatabaseTest extends AndroidTestCase { MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE, getInt(cursor, COLUMN_DOCUMENT_TYPE)); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals("/@#%&<>Storage", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.close(); @@ -186,18 +188,21 @@ public class MtpDatabaseTest extends AndroidTestCase { } public void testPutChildDocuments() throws Exception { - mDatabase.getMapper().startAddingDocuments("parentId"); - mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] { + addTestDevice(); + addTestStorage("1"); + + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024), createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024), createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024) }); - final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "parentId"); + final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "2"); assertEquals(3, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID)); assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals(100, getInt(cursor, COLUMN_OBJECT_HANDLE)); @@ -216,7 +221,7 @@ public class MtpDatabaseTest extends AndroidTestCase { MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE)); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID)); assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals(101, getInt(cursor, COLUMN_OBJECT_HANDLE)); @@ -235,7 +240,7 @@ public class MtpDatabaseTest extends AndroidTestCase { MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE)); cursor.moveToNext(); - assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID)); assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals(102, getInt(cursor, COLUMN_OBJECT_HANDLE)); @@ -263,8 +268,10 @@ public class MtpDatabaseTest extends AndroidTestCase { DocumentsContract.Document.COLUMN_DISPLAY_NAME }; - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { + // Add device and two storages. + addTestDevice(); + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 100, "Storage A", 1000, 0, ""), new MtpRoot(0, 101, "Storage B", 1001, 0, "") }); @@ -273,34 +280,37 @@ public class MtpDatabaseTest extends AndroidTestCase { final Cursor cursor = mDatabase.queryRootDocuments(columns); assertEquals(2, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(101, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.close(); } + // Clear mapping and add a device. mDatabase.getMapper().clearMapping(); + addTestDevice(); { final Cursor cursor = mDatabase.queryRootDocuments(columns); assertEquals(2, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); assertTrue(isNull(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertTrue(isNull(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.close(); } - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { + // Add two storages, but one's name is different from previous one. + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 200, "Storage A", 2000, 0, ""), new MtpRoot(0, 202, "Storage C", 2002, 0, "") }); @@ -309,31 +319,31 @@ public class MtpDatabaseTest extends AndroidTestCase { final Cursor cursor = mDatabase.queryRootDocuments(columns); assertEquals(3, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertTrue(isNull(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(202, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage C", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.close(); } - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + mDatabase.getMapper().stopAddingDocuments("1"); { final Cursor cursor = mDatabase.queryRootDocuments(columns); assertEquals(2, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(202, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage C", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.close(); @@ -346,69 +356,64 @@ public class MtpDatabaseTest extends AndroidTestCase { MtpDatabaseConstants.COLUMN_OBJECT_HANDLE, DocumentsContract.Document.COLUMN_DISPLAY_NAME }; - mDatabase.getMapper().startAddingDocuments("parentId"); - mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] { + + addTestDevice(); + addTestStorage("1"); + + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024), createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024), createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024) }); mDatabase.getMapper().clearMapping(); + addTestDevice(); + addTestStorage("1"); + { - final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId"); + final Cursor cursor = mDatabase.queryChildDocuments(columns, "2"); assertEquals(3, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE)); assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE)); assertEquals("image.jpg", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID)); assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE)); assertEquals("music.mp3", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.close(); } - mDatabase.getMapper().startAddingDocuments("parentId"); - mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] { + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024), createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024), }); + mDatabase.getMapper().stopAddingDocuments("2"); { - final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId"); - assertEquals(4, cursor.getCount()); - - cursor.moveToPosition(3); - assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); - assertEquals(203, getInt(cursor, COLUMN_OBJECT_HANDLE)); - assertEquals("video.mp4", getString(cursor, COLUMN_DISPLAY_NAME)); - - cursor.close(); - } - - mDatabase.getMapper().stopAddingDocuments("parentId"); - - { - final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId"); + final Cursor cursor = mDatabase.queryChildDocuments(columns, "2"); assertEquals(2, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE)); assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME)); cursor.moveToNext(); - assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(203, getInt(cursor, COLUMN_OBJECT_HANDLE)); assertEquals("video.mp4", getString(cursor, COLUMN_DISPLAY_NAME)); + cursor.close(); } } @@ -424,10 +429,10 @@ public class MtpDatabaseTest extends AndroidTestCase { Root.COLUMN_AVAILABLE_BYTES }; mDatabase.getMapper().startAddingDocuments(null); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(0, "Device A", true, new MtpRoot[0], null, null)); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(1, "Device B", true, new MtpRoot[0], null, null)); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device A", true, new MtpRoot[0], null, null)); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 1, "Device B", true, new MtpRoot[0], null, null)); mDatabase.getMapper().stopAddingDocuments(null); mDatabase.getMapper().startAddingDocuments("1"); @@ -467,6 +472,13 @@ public class MtpDatabaseTest extends AndroidTestCase { mDatabase.getMapper().clearMapping(); + mDatabase.getMapper().startAddingDocuments(null); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device A", true, new MtpRoot[0], null, null)); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 1, "Device B", true, new MtpRoot[0], null, null)); + mDatabase.getMapper().stopAddingDocuments(null); + mDatabase.getMapper().startAddingDocuments("1"); mDatabase.getMapper().startAddingDocuments("2"); mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { @@ -511,45 +523,71 @@ public class MtpDatabaseTest extends AndroidTestCase { MtpDatabaseConstants.COLUMN_OBJECT_HANDLE }; - mDatabase.getMapper().startAddingDocuments("parentId1"); - mDatabase.getMapper().startAddingDocuments("parentId2"); - mDatabase.getMapper().putChildDocuments(0, "parentId1", new MtpObjectInfo[] { + // Add device, storage, and two directories. + addTestDevice(); + addTestStorage("1"); + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { + createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0), + createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0), + }); + mDatabase.getMapper().stopAddingDocuments("2"); + + // Put note.txt in each directory. + mDatabase.getMapper().startAddingDocuments("3"); + mDatabase.getMapper().startAddingDocuments("4"); + mDatabase.getMapper().putChildDocuments(0, "3", new MtpObjectInfo[] { createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024), }); - mDatabase.getMapper().putChildDocuments(0, "parentId2", new MtpObjectInfo[] { + mDatabase.getMapper().putChildDocuments(0, "4", new MtpObjectInfo[] { createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024), }); + + // Clear mapping. mDatabase.getMapper().clearMapping(); - mDatabase.getMapper().startAddingDocuments("parentId1"); - mDatabase.getMapper().startAddingDocuments("parentId2"); - mDatabase.getMapper().putChildDocuments(0, "parentId1", new MtpObjectInfo[] { + // Add device, storage, and two directories again. + addTestDevice(); + addTestStorage("1"); + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { + createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0), + createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0), + }); + mDatabase.getMapper().stopAddingDocuments("2"); + + // Add note.txt in each directory again. + mDatabase.getMapper().startAddingDocuments("3"); + mDatabase.getMapper().startAddingDocuments("4"); + mDatabase.getMapper().putChildDocuments(0, "3", new MtpObjectInfo[] { createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024), }); - mDatabase.getMapper().putChildDocuments(0, "parentId2", new MtpObjectInfo[] { + mDatabase.getMapper().putChildDocuments(0, "4", new MtpObjectInfo[] { createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024), }); - mDatabase.getMapper().stopAddingDocuments("parentId1"); + mDatabase.getMapper().stopAddingDocuments("3"); + mDatabase.getMapper().stopAddingDocuments("4"); + // Check if the two note.txt are mapped correctly. { - final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId1"); + final Cursor cursor = mDatabase.queryChildDocuments(columns, "3"); assertEquals(1, cursor.getCount()); cursor.moveToNext(); - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE)); cursor.close(); } { - final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId2"); + final Cursor cursor = mDatabase.queryChildDocuments(columns, "4"); assertEquals(1, cursor.getCount()); cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(201, getInt(cursor, COLUMN_OBJECT_HANDLE)); cursor.close(); } } - public void testClearMtpIdentifierBeforeResolveRootDocuments() { + public void testClearMtpIdentifierBeforeResolveRootDocuments() throws Exception { final String[] columns = new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID, MtpDatabaseConstants.COLUMN_STORAGE_ID, @@ -561,8 +599,8 @@ public class MtpDatabaseTest extends AndroidTestCase { }; mDatabase.getMapper().startAddingDocuments(null); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], null, null)); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", false, new MtpRoot[0], null, null)); mDatabase.getMapper().stopAddingDocuments(null); mDatabase.getMapper().startAddingDocuments("1"); @@ -571,12 +609,28 @@ public class MtpDatabaseTest extends AndroidTestCase { }); mDatabase.getMapper().clearMapping(); + mDatabase.getMapper().startAddingDocuments(null); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", false, new MtpRoot[0], null, null)); + mDatabase.getMapper().stopAddingDocuments(null); + + try (final Cursor cursor = mDatabase.queryRoots(resources, rootColumns)) { + assertEquals(1, cursor.getCount()); + cursor.moveToNext(); + assertEquals("1", getString(cursor, Root.COLUMN_ROOT_ID)); + } + mDatabase.getMapper().startAddingDocuments("1"); mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 200, "Storage", 2000, 0, ""), }); mDatabase.getMapper().clearMapping(); + mDatabase.getMapper().startAddingDocuments(null); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", false, new MtpRoot[0], null, null)); + mDatabase.getMapper().stopAddingDocuments(null); + mDatabase.getMapper().startAddingDocuments("1"); mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 300, "Storage", 3000, 0, ""), @@ -609,39 +663,47 @@ public class MtpDatabaseTest extends AndroidTestCase { DocumentsContract.Document.COLUMN_DISPLAY_NAME }; - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { - new MtpRoot(0, 100, "Storage", 0, 0, ""), - }); + // Add a device and a storage. + addTestDevice(); + addTestStorage("1"); + + // Disconnect devices. mDatabase.getMapper().clearMapping(); - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { + // Add a device and two storages that has same name. + addTestDevice(); + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 200, "Storage", 2000, 0, ""), new MtpRoot(0, 201, "Storage", 2001, 0, ""), }); - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + mDatabase.getMapper().stopAddingDocuments("1"); { final Cursor cursor = mDatabase.queryRootDocuments(columns); assertEquals(2, cursor.getCount()); + + // First storage reuse document ID of previous storage. cursor.moveToNext(); // One reuses exisitng document ID 1. - assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME)); + + // Second one has new document ID. cursor.moveToNext(); - assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID)); + assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID)); assertEquals(201, getInt(cursor, COLUMN_STORAGE_ID)); assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME)); + cursor.close(); } } - public void testReplaceExistingRoots() { + public void testReplaceExistingRoots() throws Exception { mDatabase.getMapper().startAddingDocuments(null); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null)); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", true, new MtpRoot[0], null, null)); mDatabase.getMapper().stopAddingDocuments(null); // The client code should be able to replace existing rows with new information. @@ -687,66 +749,62 @@ public class MtpDatabaseTest extends AndroidTestCase { } } - public void testFailToReplaceExisitingUnmappedRoots() { + public void testFailToReplaceExisitingUnmappedRoots() throws Exception { // The client code should not be able to replace rows before resolving 'unmapped' rows. // Add one. - mDatabase.getMapper().startAddingDocuments(null); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null)); - mDatabase.getMapper().stopAddingDocuments(null); - + addTestDevice(); mDatabase.getMapper().startAddingDocuments("1"); mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 100, "Storage A", 0, 0, ""), }); mDatabase.getMapper().clearMapping(); - final Cursor oldCursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_ROOT_ID)); - assertEquals(1, oldCursor.getCount()); - - // Add one. - mDatabase.getMapper().startAddingDocuments("1"); - mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { - new MtpRoot(0, 101, "Storage B", 1000, 1000, ""), - }); - // Add one more before resolving unmapped documents. - mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { - new MtpRoot(0, 102, "Storage B", 1000, 1000, ""), - }); - mDatabase.getMapper().stopAddingDocuments("1"); - // Because the roots shares the same name, the roots should have new IDs. - final Cursor newCursor = mDatabase.queryChildDocuments( - strings(Document.COLUMN_DOCUMENT_ID), "1"); - assertEquals(2, newCursor.getCount()); - oldCursor.moveToNext(); - newCursor.moveToNext(); - assertFalse(oldCursor.getString(0).equals(newCursor.getString(0))); - newCursor.moveToNext(); - assertFalse(oldCursor.getString(0).equals(newCursor.getString(0))); - - oldCursor.close(); - newCursor.close(); + addTestDevice(); + try (final Cursor oldCursor = + mDatabase.queryRoots(resources, strings(Root.COLUMN_ROOT_ID))) { + assertEquals(1, oldCursor.getCount()); + oldCursor.moveToNext(); + assertEquals("1", getString(oldCursor, Root.COLUMN_ROOT_ID)); + + // Add one. + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { + new MtpRoot(0, 101, "Storage B", 1000, 1000, ""), + }); + // Add one more before resolving unmapped documents. + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { + new MtpRoot(0, 102, "Storage B", 1000, 1000, ""), + }); + mDatabase.getMapper().stopAddingDocuments("1"); + + // Because the roots shares the same name, the roots should have new IDs. + try (final Cursor newCursor = mDatabase.queryChildDocuments( + strings(Document.COLUMN_DOCUMENT_ID), "1")) { + assertEquals(2, newCursor.getCount()); + newCursor.moveToNext(); + assertFalse(oldCursor.getString(0).equals(newCursor.getString(0))); + newCursor.moveToNext(); + assertFalse(oldCursor.getString(0).equals(newCursor.getString(0))); + } + } } - public void testQueryDocuments() { - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { - new MtpRoot(0, 100, "Storage A", 0, 0, ""), - }); - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + public void testQueryDocuments() throws Exception { + addTestDevice(); + addTestStorage("1"); - final Cursor cursor = mDatabase.queryDocument("1", strings(Document.COLUMN_DISPLAY_NAME)); + final Cursor cursor = mDatabase.queryDocument("2", strings(Document.COLUMN_DISPLAY_NAME)); assertEquals(1, cursor.getCount()); cursor.moveToNext(); - assertEquals("Storage A", getString(cursor, Document.COLUMN_DISPLAY_NAME)); + assertEquals("Storage", getString(cursor, Document.COLUMN_DISPLAY_NAME)); cursor.close(); } - public void testQueryRoots() { + public void testQueryRoots() throws Exception { // Add device document. mDatabase.getMapper().startAddingDocuments(null); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], null, null)); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", false, new MtpRoot[0], null, null)); mDatabase.getMapper().stopAddingDocuments(null); // It the device does not have storages, it shows a device root. @@ -791,55 +849,54 @@ public class MtpDatabaseTest extends AndroidTestCase { } public void testGetParentId() throws FileNotFoundException { - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { + addTestDevice(); + + mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] { new MtpRoot(0, 100, "Storage A", 0, 0, ""), }); - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + mDatabase.getMapper().stopAddingDocuments("1"); - mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().startAddingDocuments("2"); mDatabase.getMapper().putChildDocuments( 0, - "1", + "2", new MtpObjectInfo[] { createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024), }); - mDatabase.getMapper().stopAddingDocuments("1"); + mDatabase.getMapper().stopAddingDocuments("2"); - assertEquals("1", mDatabase.getParentIdentifier("2").mDocumentId); + assertEquals("2", mDatabase.getParentIdentifier("3").mDocumentId); } - public void testDeleteDocument() { - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { - new MtpRoot(0, 100, "Storage A", 0, 0, ""), - }); - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + public void testDeleteDocument() throws Exception { + addTestDevice(); + addTestStorage("1"); - mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().startAddingDocuments("2"); mDatabase.getMapper().putChildDocuments( 0, - "1", + "2", new MtpObjectInfo[] { createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024), }); - mDatabase.getMapper().stopAddingDocuments("1"); + mDatabase.getMapper().stopAddingDocuments("2"); - mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().startAddingDocuments("3"); mDatabase.getMapper().putChildDocuments( 0, - "2", + "3", new MtpObjectInfo[] { createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024), }); - mDatabase.getMapper().stopAddingDocuments("2"); + mDatabase.getMapper().stopAddingDocuments("3"); - mDatabase.deleteDocument("2"); + mDatabase.deleteDocument("3"); { // Do not query deleted documents. final Cursor cursor = - mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1"); + mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2"); assertEquals(0, cursor.getCount()); cursor.close(); } @@ -847,64 +904,58 @@ public class MtpDatabaseTest extends AndroidTestCase { { // Child document should be deleted also. final Cursor cursor = - mDatabase.queryDocument("3", strings(Document.COLUMN_DOCUMENT_ID)); + mDatabase.queryDocument("4", strings(Document.COLUMN_DOCUMENT_ID)); assertEquals(0, cursor.getCount()); cursor.close(); } } - public void testPutNewDocument() { - mDatabase.getMapper().startAddingDocuments("deviceDocId"); - mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] { - new MtpRoot(0, 100, "Storage A", 0, 0, ""), - }); - mDatabase.getMapper().stopAddingDocuments("deviceDocId"); + public void testPutNewDocument() throws Exception { + addTestDevice(); + addTestStorage("1"); assertEquals( - "2", + "3", mDatabase.putNewDocument( - 0, "1", createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024))); + 0, "2", createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024))); { final Cursor cursor = - mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1"); + mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2"); assertEquals(1, cursor.getCount()); cursor.moveToNext(); - assertEquals("2", cursor.getString(0)); + assertEquals("3", cursor.getString(0)); cursor.close(); } // The new document should not be mapped with existing invalidated document. mDatabase.getMapper().clearMapping(); - mDatabase.getMapper().startAddingDocuments("1"); + mDatabase.getMapper().startAddingDocuments("2"); mDatabase.putNewDocument( 0, - "1", + "2", createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024)); - mDatabase.getMapper().stopAddingDocuments("1"); + mDatabase.getMapper().stopAddingDocuments("2"); { final Cursor cursor = - mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1"); + mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2"); assertEquals(1, cursor.getCount()); cursor.moveToNext(); - assertEquals("3", cursor.getString(0)); + assertEquals("4", cursor.getString(0)); cursor.close(); } } - public void testGetDocumentIdForDevice() { - mDatabase.getMapper().startAddingDocuments(null); - mDatabase.getMapper().putDeviceDocument( - new MtpDeviceRecord(100, "Device", true, new MtpRoot[0], null, null)); - mDatabase.getMapper().stopAddingDocuments(null); - assertEquals("1", mDatabase.getDocumentIdForDevice(100)); + public void testGetDocumentIdForDevice() throws Exception { + addTestDevice(); + assertEquals("1", mDatabase.getDocumentIdForDevice(0)); } - public void testGetClosedDevice() { + public void testGetClosedDevice() throws Exception { mDatabase.getMapper().startAddingDocuments(null); mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( - 0, "Device", /* opened is */ false , new MtpRoot[0], null, null)); + 0, "Device", /* opened is */ false, new MtpRoot[0], null, null)); mDatabase.getMapper().stopAddingDocuments(null); final String[] columns = new String [] { @@ -920,4 +971,19 @@ public class MtpDatabaseTest extends AndroidTestCase { assertTrue(cursor.isNull(2)); } } + + private void addTestDevice() throws FileNotFoundException { + mDatabase.getMapper().startAddingDocuments(null); + mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", /* opened is */ true, new MtpRoot[0], null, null)); + mDatabase.getMapper().stopAddingDocuments(null); + } + + private void addTestStorage(String parentId) throws FileNotFoundException { + mDatabase.getMapper().startAddingDocuments(parentId); + mDatabase.getMapper().putStorageDocuments(parentId, new MtpRoot[] { + new MtpRoot(0, 100, "Storage", 1024, 1024, ""), + }); + mDatabase.getMapper().stopAddingDocuments(parentId); + } } |