Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +11 −5 Original line number Diff line number Diff line Loading @@ -200,10 +200,7 @@ class MtpDatabase { storageCursor.close(); } final RowBuilder row = result.newRow(); for (final String key : values.keySet()) { row.add(key, values.get(key)); } putValuesToCursor(values, result); } return result; Loading Loading @@ -760,7 +757,9 @@ class MtpDatabase { Document.MIME_TYPE_DIR, 0, MtpConstants.PROTECTION_STATUS_NONE, DOCUMENT_TYPE_DEVICE)); // Storages are placed under device so we cannot create a document just under // device. DOCUMENT_TYPE_DEVICE) & ~Document.FLAG_DIR_SUPPORTS_CREATE); values.putNull(Document.COLUMN_SIZE); extraValues.clear(); Loading Loading @@ -915,6 +914,13 @@ class MtpDatabase { return results; } static void putValuesToCursor(ContentValues values, MatrixCursor cursor) { final RowBuilder row = cursor.newRow(); for (final String name : cursor.getColumnNames()) { row.add(values.get(name)); } } private static String getIdList(Set<String> ids) { String result = "("; for (final String id : ids) { Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +53 −2 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ package com.android.mtp; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.UriPermission; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.MatrixCursor; import android.database.sqlite.SQLiteDiskIOException; import android.graphics.Point; Loading Loading @@ -55,7 +57,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeoutException; import libcore.io.IoUtils; /** Loading Loading @@ -177,9 +178,59 @@ public class MtpDocumentsProvider extends DocumentsProvider { if (projection == null) { projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION; } final Cursor cursor = mDatabase.queryDocument(documentId, projection); final int cursorCount = cursor.getCount(); if (cursorCount == 0) { cursor.close(); throw new FileNotFoundException(); } else if (cursorCount != 1) { cursor.close(); Log.wtf(TAG, "Unexpected cursor size: " + cursorCount); return null; } final Identifier identifier = mDatabase.createIdentifier(documentId); if (identifier.mDocumentType != MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE) { return cursor; } final String[] storageDocIds = mDatabase.getStorageDocumentIds(documentId); if (storageDocIds.length != 1) { return mDatabase.queryDocument(documentId, projection); } // If the documentId specifies a device having exact one storage, we repalce some device // attributes with the storage attributes. try { final String storageName; final int storageFlags; try (final Cursor storageCursor = mDatabase.queryDocument( storageDocIds[0], MtpDatabase.strings(Document.COLUMN_DISPLAY_NAME, Document.COLUMN_FLAGS))) { if (!storageCursor.moveToNext()) { throw new FileNotFoundException(); } storageName = storageCursor.getString(0); storageFlags = storageCursor.getInt(1); } cursor.moveToNext(); final ContentValues values = new ContentValues(); DatabaseUtils.cursorRowToContentValues(cursor, values); if (values.containsKey(Document.COLUMN_DISPLAY_NAME)) { values.put(Document.COLUMN_DISPLAY_NAME, mResources.getString( R.string.root_name, values.getAsString(Document.COLUMN_DISPLAY_NAME), storageName)); } values.put(Document.COLUMN_FLAGS, storageFlags); final MatrixCursor output = new MatrixCursor(projection, 1); MtpDatabase.putValuesToCursor(values, output); return output; } finally { cursor.close(); } } @Override public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { Loading packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +56 −1 Original line number Diff line number Diff line Loading @@ -368,7 +368,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { assertEquals(0, cursor.getInt(5)); } public void testQueryDocument_forRoot() public void testQueryDocument_forStorage() throws IOException, InterruptedException, TimeoutException { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { Loading @@ -392,6 +392,61 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { assertEquals(3072, cursor.getInt(5)); } public void testQueryDocument_forDeviceWithSingleStorage() throws IOException, InterruptedException, TimeoutException { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { new MtpRoot( 0 /* deviceId */, 1 /* storageId */, "Storage A" /* volume description */, 1024 /* free space */, 4096 /* total space */, "" /* no volume identifier */) }); final Cursor cursor = mProvider.queryDocument("1", null); assertEquals(1, cursor.getCount()); cursor.moveToNext(); assertEquals("1", cursor.getString(0)); assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1)); assertEquals("Device Storage A", cursor.getString(2)); assertTrue(cursor.isNull(3)); assertEquals(DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE, cursor.getInt(4)); assertTrue(cursor.isNull(5)); } public void testQueryDocument_forDeviceWithTwoStorages() throws IOException, InterruptedException, TimeoutException { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { new MtpRoot( 0 /* deviceId */, 1 /* storageId */, "Storage A" /* volume description */, 1024 /* free space */, 4096 /* total space */, "" /* no volume identifier */), new MtpRoot( 0 /* deviceId */, 2 /* storageId */, "Storage B" /* volume description */, 1024 /* free space */, 4096 /* total space */, "" /* no volume identifier */) }); final Cursor cursor = mProvider.queryDocument("1", null); assertEquals(1, cursor.getCount()); cursor.moveToNext(); assertEquals("1", cursor.getString(0)); assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1)); assertEquals("Device", cursor.getString(2)); assertTrue(cursor.isNull(3)); assertEquals(0, cursor.getInt(4)); assertTrue(cursor.isNull(5)); } public void testQueryChildDocuments() throws Exception { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") }); Loading Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +11 −5 Original line number Diff line number Diff line Loading @@ -200,10 +200,7 @@ class MtpDatabase { storageCursor.close(); } final RowBuilder row = result.newRow(); for (final String key : values.keySet()) { row.add(key, values.get(key)); } putValuesToCursor(values, result); } return result; Loading Loading @@ -760,7 +757,9 @@ class MtpDatabase { Document.MIME_TYPE_DIR, 0, MtpConstants.PROTECTION_STATUS_NONE, DOCUMENT_TYPE_DEVICE)); // Storages are placed under device so we cannot create a document just under // device. DOCUMENT_TYPE_DEVICE) & ~Document.FLAG_DIR_SUPPORTS_CREATE); values.putNull(Document.COLUMN_SIZE); extraValues.clear(); Loading Loading @@ -915,6 +914,13 @@ class MtpDatabase { return results; } static void putValuesToCursor(ContentValues values, MatrixCursor cursor) { final RowBuilder row = cursor.newRow(); for (final String name : cursor.getColumnNames()) { row.add(values.get(name)); } } private static String getIdList(Set<String> ids) { String result = "("; for (final String id : ids) { Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +53 −2 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ package com.android.mtp; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.UriPermission; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.MatrixCursor; import android.database.sqlite.SQLiteDiskIOException; import android.graphics.Point; Loading Loading @@ -55,7 +57,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeoutException; import libcore.io.IoUtils; /** Loading Loading @@ -177,9 +178,59 @@ public class MtpDocumentsProvider extends DocumentsProvider { if (projection == null) { projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION; } final Cursor cursor = mDatabase.queryDocument(documentId, projection); final int cursorCount = cursor.getCount(); if (cursorCount == 0) { cursor.close(); throw new FileNotFoundException(); } else if (cursorCount != 1) { cursor.close(); Log.wtf(TAG, "Unexpected cursor size: " + cursorCount); return null; } final Identifier identifier = mDatabase.createIdentifier(documentId); if (identifier.mDocumentType != MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE) { return cursor; } final String[] storageDocIds = mDatabase.getStorageDocumentIds(documentId); if (storageDocIds.length != 1) { return mDatabase.queryDocument(documentId, projection); } // If the documentId specifies a device having exact one storage, we repalce some device // attributes with the storage attributes. try { final String storageName; final int storageFlags; try (final Cursor storageCursor = mDatabase.queryDocument( storageDocIds[0], MtpDatabase.strings(Document.COLUMN_DISPLAY_NAME, Document.COLUMN_FLAGS))) { if (!storageCursor.moveToNext()) { throw new FileNotFoundException(); } storageName = storageCursor.getString(0); storageFlags = storageCursor.getInt(1); } cursor.moveToNext(); final ContentValues values = new ContentValues(); DatabaseUtils.cursorRowToContentValues(cursor, values); if (values.containsKey(Document.COLUMN_DISPLAY_NAME)) { values.put(Document.COLUMN_DISPLAY_NAME, mResources.getString( R.string.root_name, values.getAsString(Document.COLUMN_DISPLAY_NAME), storageName)); } values.put(Document.COLUMN_FLAGS, storageFlags); final MatrixCursor output = new MatrixCursor(projection, 1); MtpDatabase.putValuesToCursor(values, output); return output; } finally { cursor.close(); } } @Override public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { Loading
packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +56 −1 Original line number Diff line number Diff line Loading @@ -368,7 +368,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { assertEquals(0, cursor.getInt(5)); } public void testQueryDocument_forRoot() public void testQueryDocument_forStorage() throws IOException, InterruptedException, TimeoutException { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { Loading @@ -392,6 +392,61 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { assertEquals(3072, cursor.getInt(5)); } public void testQueryDocument_forDeviceWithSingleStorage() throws IOException, InterruptedException, TimeoutException { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { new MtpRoot( 0 /* deviceId */, 1 /* storageId */, "Storage A" /* volume description */, 1024 /* free space */, 4096 /* total space */, "" /* no volume identifier */) }); final Cursor cursor = mProvider.queryDocument("1", null); assertEquals(1, cursor.getCount()); cursor.moveToNext(); assertEquals("1", cursor.getString(0)); assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1)); assertEquals("Device Storage A", cursor.getString(2)); assertTrue(cursor.isNull(3)); assertEquals(DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE, cursor.getInt(4)); assertTrue(cursor.isNull(5)); } public void testQueryDocument_forDeviceWithTwoStorages() throws IOException, InterruptedException, TimeoutException { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { new MtpRoot( 0 /* deviceId */, 1 /* storageId */, "Storage A" /* volume description */, 1024 /* free space */, 4096 /* total space */, "" /* no volume identifier */), new MtpRoot( 0 /* deviceId */, 2 /* storageId */, "Storage B" /* volume description */, 1024 /* free space */, 4096 /* total space */, "" /* no volume identifier */) }); final Cursor cursor = mProvider.queryDocument("1", null); assertEquals(1, cursor.getCount()); cursor.moveToNext(); assertEquals("1", cursor.getString(0)); assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1)); assertEquals("Device", cursor.getString(2)); assertTrue(cursor.isNull(3)); assertEquals(0, cursor.getInt(4)); assertTrue(cursor.isNull(5)); } public void testQueryChildDocuments() throws Exception { setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") }); Loading