Merge "Fix doc flag for device having multiple storages" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
adfefc39e1
@@ -200,10 +200,7 @@ class MtpDatabase {
|
|||||||
storageCursor.close();
|
storageCursor.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
final RowBuilder row = result.newRow();
|
putValuesToCursor(values, result);
|
||||||
for (final String key : values.keySet()) {
|
|
||||||
row.add(key, values.get(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -760,7 +757,9 @@ class MtpDatabase {
|
|||||||
Document.MIME_TYPE_DIR,
|
Document.MIME_TYPE_DIR,
|
||||||
0,
|
0,
|
||||||
MtpConstants.PROTECTION_STATUS_NONE,
|
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);
|
values.putNull(Document.COLUMN_SIZE);
|
||||||
|
|
||||||
extraValues.clear();
|
extraValues.clear();
|
||||||
@@ -915,6 +914,13 @@ class MtpDatabase {
|
|||||||
return results;
|
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) {
|
private static String getIdList(Set<String> ids) {
|
||||||
String result = "(";
|
String result = "(";
|
||||||
for (final String id : ids) {
|
for (final String id : ids) {
|
||||||
|
|||||||
@@ -17,11 +17,13 @@
|
|||||||
package com.android.mtp;
|
package com.android.mtp;
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.UriPermission;
|
import android.content.UriPermission;
|
||||||
import android.content.res.AssetFileDescriptor;
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.database.DatabaseUtils;
|
||||||
import android.database.MatrixCursor;
|
import android.database.MatrixCursor;
|
||||||
import android.database.sqlite.SQLiteDiskIOException;
|
import android.database.sqlite.SQLiteDiskIOException;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
@@ -55,7 +57,6 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
import libcore.io.IoUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +178,57 @@ public class MtpDocumentsProvider extends DocumentsProvider {
|
|||||||
if (projection == null) {
|
if (projection == null) {
|
||||||
projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION;
|
projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION;
|
||||||
}
|
}
|
||||||
return mDatabase.queryDocument(documentId, 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
|
@Override
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
|
|||||||
assertEquals(0, cursor.getInt(5));
|
assertEquals(0, cursor.getInt(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQueryDocument_forRoot()
|
public void testQueryDocument_forStorage()
|
||||||
throws IOException, InterruptedException, TimeoutException {
|
throws IOException, InterruptedException, TimeoutException {
|
||||||
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
|
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
|
||||||
setupRoots(0, new MtpRoot[] {
|
setupRoots(0, new MtpRoot[] {
|
||||||
@@ -392,6 +392,61 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
|
|||||||
assertEquals(3072, cursor.getInt(5));
|
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 {
|
public void testQueryChildDocuments() throws Exception {
|
||||||
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
|
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
|
||||||
setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
|
setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
|
||||||
|
|||||||
Reference in New Issue
Block a user