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

Commit 073f5aae authored by Daichi Hirono's avatar Daichi Hirono Committed by Android (Google) Code Review
Browse files

Merge "Update object info when writing a file." into nyc-dev

parents 25410b13 f578fa27
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -581,6 +581,23 @@ class MtpDatabase {
        }
    }

    void updateObject(String documentId, int deviceId, String parentId, MtpObjectInfo info) {
        final ContentValues values = new ContentValues();
        getObjectDocumentValues(values, deviceId, parentId, info);

        mDatabase.beginTransaction();
        try {
            mDatabase.update(
                    TABLE_DOCUMENTS,
                    values,
                    Document.COLUMN_DOCUMENT_ID + " = ?",
                    strings(documentId));
            mDatabase.setTransactionSuccessful();
        } finally {
            mDatabase.endTransaction();
        }
    }

    private static class OpenHelper extends SQLiteOpenHelper {
        public OpenHelper(Context context, int flags) {
            super(context,
+1 −1
Original line number Diff line number Diff line
@@ -486,7 +486,7 @@ public class MtpDocumentsProvider extends DocumentsProvider {
        public final DocumentLoader mDocumentLoader;

        public DeviceToolkit(MtpManager manager, ContentResolver resolver, MtpDatabase database) {
            mPipeManager = new PipeManager();
            mPipeManager = new PipeManager(database);
            mDocumentLoader = new DocumentLoader(manager, resolver, database);
        }
    }
+24 −9
Original line number Diff line number Diff line
@@ -29,12 +29,14 @@ import java.util.concurrent.Executors;

class PipeManager {
    final ExecutorService mExecutor;
    final MtpDatabase mDatabase;

    PipeManager() {
        this(Executors.newSingleThreadExecutor());
    PipeManager(MtpDatabase database) {
        this(database, Executors.newSingleThreadExecutor());
    }

    PipeManager(ExecutorService executor) {
    PipeManager(MtpDatabase database, ExecutorService executor) {
        this.mDatabase = database;
        this.mExecutor = executor;
    }

@@ -46,7 +48,7 @@ class PipeManager {

    ParcelFileDescriptor writeDocument(Context context, MtpManager model, Identifier identifier)
            throws IOException {
        final Task task = new WriteDocumentTask(context, model, identifier);
        final Task task = new WriteDocumentTask(context, model, identifier, mDatabase);
        mExecutor.execute(task);
        return task.getWritingFileDescriptor();
    }
@@ -100,11 +102,14 @@ class PipeManager {

    private static class WriteDocumentTask extends Task {
        private final Context mContext;
        private final MtpDatabase mDatabase;

        WriteDocumentTask(Context context, MtpManager model, Identifier identifier)
        WriteDocumentTask(
                Context context, MtpManager model, Identifier identifier, MtpDatabase database)
                throws IOException {
            super(model, identifier);
            mContext = context;
            mDatabase = database;
        }

        @Override
@@ -112,7 +117,7 @@ class PipeManager {
            File tempFile = null;
            try {
                // Obtain a temporary file and copy the data to it.
                tempFile = mContext.getCacheDir().createTempFile("mtp", "tmp");
                tempFile = File.createTempFile("mtp", "tmp", mContext.getCacheDir());
                try (
                    final FileOutputStream tempOutputStream =
                            new ParcelFileDescriptor.AutoCloseOutputStream(
@@ -140,12 +145,22 @@ class PipeManager {
                // Create the target object info with a correct file size and upload the file.
                final MtpObjectInfo targetObjectInfo =
                        new MtpObjectInfo.Builder(placeholderObjectInfo)
                                .setCompressedSize((int) tempFile.length())
                                .setCompressedSize(tempFile.length())
                                .build();
                final ParcelFileDescriptor tempInputDescriptor = ParcelFileDescriptor.open(
                        tempFile, ParcelFileDescriptor.MODE_READ_ONLY);
                mManager.createDocument(mIdentifier.mDeviceId,
                        targetObjectInfo, tempInputDescriptor);
                final int newObjectHandle = mManager.createDocument(
                        mIdentifier.mDeviceId, targetObjectInfo, tempInputDescriptor);

                final MtpObjectInfo newObjectInfo = mManager.getObjectInfo(
                        mIdentifier.mDeviceId, newObjectHandle);
                final Identifier parentIdentifier =
                        mDatabase.getParentIdentifier(mIdentifier.mDocumentId);
                mDatabase.updateObject(
                        mIdentifier.mDocumentId,
                        mIdentifier.mDeviceId,
                        parentIdentifier.mDocumentId,
                        newObjectInfo);
            } catch (IOException error) {
                Log.w(MtpDocumentsProvider.TAG,
                        "Failed to send a file because of: " + error.getMessage());
+2 −10
Original line number Diff line number Diff line
@@ -983,18 +983,10 @@ public class MtpDatabaseTest extends AndroidTestCase {
    }

    private void addTestDevice() throws FileNotFoundException {
        mDatabase.getMapper().startAddingDocuments(null);
        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
                null));
        mDatabase.getMapper().stopAddingDocuments(null);
        TestUtil.addTestDevice(mDatabase);
    }

    private void addTestStorage(String parentId) throws FileNotFoundException {
        mDatabase.getMapper().startAddingDocuments(parentId);
        mDatabase.getMapper().putStorageDocuments(parentId, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage", 1024, 1024, ""),
        });
        mDatabase.getMapper().stopAddingDocuments(parentId);
        TestUtil.addTestStorage(mDatabase, parentId);
    }
}
+30 −9
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.mtp;

import android.database.Cursor;
import android.mtp.MtpObjectInfo;
import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract.Document;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;

@@ -33,12 +35,14 @@ public class PipeManagerTest extends AndroidTestCase {
    private TestMtpManager mtpManager;
    private ExecutorService mExecutor;
    private PipeManager mPipeManager;
    private MtpDatabase mDatabase;

    @Override
    public void setUp() {
        mtpManager = new TestMtpManager(getContext());
        mExecutor = Executors.newSingleThreadExecutor();
        mPipeManager = new PipeManager(mExecutor);
        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
        mPipeManager = new PipeManager(mDatabase, mExecutor);
    }

    public void testReadDocument_basic() throws Exception {
@@ -57,25 +61,32 @@ public class PipeManagerTest extends AndroidTestCase {
    }

    public void testWriteDocument_basic() throws Exception {
        TestUtil.addTestDevice(mDatabase);
        TestUtil.addTestStorage(mDatabase, "1");

        final MtpObjectInfo info =
                new MtpObjectInfo.Builder().setObjectHandle(1).setName("note.txt").build();
        mDatabase.getMapper().startAddingDocuments("2");
        mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { info });
        mDatabase.getMapper().stopAddingDocuments("2");
        // Create a placeholder file which should be replaced by a real file later.
        mtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
                .setObjectHandle(1)
                .build());
        mtpManager.setObjectInfo(0, info);

        // Upload testing bytes.
        final ParcelFileDescriptor descriptor = mPipeManager.writeDocument(
                getContext(),
                mtpManager,
                new Identifier(0, 0, 1, null, MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT));
                new Identifier(0, 0, 1, "2", MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT));
        final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
                new ParcelFileDescriptor.AutoCloseOutputStream(descriptor);
        outputStream.write(HELLO_BYTES, 0, HELLO_BYTES.length);
        outputStream.close();
        mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
        mExecutor.shutdown();
        assertTrue(mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS));

        // Check if the placeholder file is removed.
        try {
            final MtpObjectInfo placeholderDocument = mtpManager.getObjectInfo(0, 1);
            mtpManager.getObjectInfo(0, 1);
            fail();  // The placeholder file has not been deleted.
        } catch (IOException e) {
            // Expected error, as the file is gone.
@@ -86,6 +97,14 @@ public class PipeManagerTest extends AndroidTestCase {
                0, TestMtpManager.CREATED_DOCUMENT_HANDLE);
        assertTrue(targetDocument != null);

        // Confirm the object handle is updated.
        try (final Cursor cursor = mDatabase.queryDocument(
                "2", new String[] { MtpDatabaseConstants.COLUMN_OBJECT_HANDLE })) {
            assertEquals(1, cursor.getCount());
            cursor.moveToNext();
            assertEquals(TestMtpManager.CREATED_DOCUMENT_HANDLE, cursor.getInt(0));
        }

        // Verify uploaded bytes.
        final byte[] uploadedBytes = mtpManager.getImportFileBytes(
                0, TestMtpManager.CREATED_DOCUMENT_HANDLE);
@@ -112,7 +131,8 @@ public class PipeManagerTest extends AndroidTestCase {

    private void assertDescriptor(ParcelFileDescriptor descriptor, byte[] expectedBytes)
            throws IOException, InterruptedException {
        mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
        mExecutor.shutdown();
        assertTrue(mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS));
        try (final ParcelFileDescriptor.AutoCloseInputStream stream =
                new ParcelFileDescriptor.AutoCloseInputStream(descriptor)) {
            byte[] results = new byte[100];
@@ -125,7 +145,8 @@ public class PipeManagerTest extends AndroidTestCase {

    private void assertDescriptorError(ParcelFileDescriptor descriptor)
            throws InterruptedException {
        mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
        mExecutor.shutdown();
        assertTrue(mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS));
        try {
            descriptor.checkError();
            fail();
Loading