Not create document under the device.

The structure of files in MtpDocumentsProvider looks like
/device/storage/files. But MtpDocumentsProvider shows files
just under the device if the device has only single storage.

It causes a problem that MtpDocumentsProvider tries to create a file
under the device. Previously it tries to create a file with storageId =
0, which means MTP device choose a storage to store the file.

Because it only happens when the device has a single storage, the file
is properly written to the device. But the database in
MtpDocumentsProvider goes into the illegal state where the file is
placed just under the device.

Bug: 32561572
Test: adb shell am instrument -w -e class com.android.mtp.MtpDocumentsProviderTest com.android.mtp.tests/com.android.mtp.TestResultInstrumentation
Change-Id: I47a373ceee8a64ba9995934317693e79d2497ee0
This commit is contained in:
Daichi Hirono
2016-11-02 14:51:26 +09:00
parent 03c8e3f771
commit 35b2ec551f
3 changed files with 58 additions and 3 deletions

View File

@@ -349,6 +349,34 @@ public class MtpDocumentsProvider extends DocumentsProvider {
throw new UnsupportedOperationException(
"Writing operation is not supported by the device.");
}
final int parentObjectHandle;
final int storageId;
switch (parentId.mDocumentType) {
case MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE:
final String[] storageDocumentIds =
mDatabase.getStorageDocumentIds(parentId.mDocumentId);
if (storageDocumentIds.length == 1) {
final String newDocumentId =
createDocument(storageDocumentIds[0], mimeType, displayName);
notifyChildDocumentsChange(parentDocumentId);
return newDocumentId;
} else {
throw new UnsupportedOperationException(
"Cannot create a file under the device.");
}
case MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE:
storageId = parentId.mStorageId;
parentObjectHandle = -1;
break;
case MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT:
storageId = parentId.mStorageId;
parentObjectHandle = parentId.mObjectHandle;
break;
default:
throw new IllegalArgumentException("Unexpected document type.");
}
pipe = ParcelFileDescriptor.createReliablePipe();
int objectHandle = -1;
MtpObjectInfo info = null;
@@ -359,8 +387,8 @@ public class MtpDocumentsProvider extends DocumentsProvider {
MtpConstants.FORMAT_ASSOCIATION :
MediaFile.getFormatCode(displayName, mimeType);
info = new MtpObjectInfo.Builder()
.setStorageId(parentId.mStorageId)
.setParent(parentId.mObjectHandle)
.setStorageId(storageId)
.setParent(parentObjectHandle)
.setFormat(formatCode)
.setName(displayName)
.build();

View File

@@ -546,7 +546,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
public void testOpenDocument_writing() throws Exception {
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
setupRoots(0, new MtpRoot[] {
new MtpRoot(0, 0, "Storage", 0, 0, "")
new MtpRoot(0, 100, "Storage", 0, 0, "")
});
final String documentId = mProvider.createDocument("2", "text/plain", "test.txt");
{
@@ -689,6 +689,29 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
}
}
public void testCreateDocument() throws Exception {
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
setupRoots(0, new MtpRoot[] {
new MtpRoot(0, 100, "Storage A", 100, 100, null)
});
final String documentId = mProvider.createDocument("1", "text/plain", "note.txt");
final Uri deviceUri = DocumentsContract.buildChildDocumentsUri(
MtpDocumentsProvider.AUTHORITY, "1");
final Uri storageUri = DocumentsContract.buildChildDocumentsUri(
MtpDocumentsProvider.AUTHORITY, "2");
mResolver.waitForNotification(storageUri, 1);
mResolver.waitForNotification(deviceUri, 1);
try (final Cursor cursor = mProvider.queryDocument(documentId, null)) {
assertTrue(cursor.moveToNext());
assertEquals(
"note.txt",
cursor.getString(cursor.getColumnIndex(Document.COLUMN_DISPLAY_NAME)));
assertEquals(
"text/plain",
cursor.getString(cursor.getColumnIndex(Document.COLUMN_MIME_TYPE)));
}
}
public void testCreateDocument_noWritingSupport() throws Exception {
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
mMtpManager.addValidDevice(new MtpDeviceRecord(

View File

@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Assert;
public class TestMtpManager extends MtpManager {
public static final int CREATED_DOCUMENT_HANDLE = 1000;
@@ -151,6 +152,9 @@ public class TestMtpManager extends MtpManager {
@Override
int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
throws IOException {
Assert.assertNotSame(0, objectInfo.getStorageId());
Assert.assertNotSame(-1, objectInfo.getStorageId());
Assert.assertNotSame(0, objectInfo.getParent());
final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
if (mObjectInfos.containsKey(key)) {
throw new IOException();