Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35b2ec55 authored by Daichi Hirono's avatar Daichi Hirono
Browse files

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
parent 03c8e3f7
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -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();
+24 −1
Original line number Diff line number Diff line
@@ -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(
+4 −0
Original line number Diff line number Diff line
@@ -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();