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:
@@ -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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user