diff options
7 files changed, 94 insertions, 32 deletions
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java index 441b9a774ac3..ca5c79974d4d 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java @@ -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, diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java index db1671d6296a..d329e3cdd375 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java @@ -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); } } diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java index 16523bca454c..645bfcd3eeb4 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java @@ -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()); diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java index 1df7351a8446..05c9c57e2409 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java @@ -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); } } diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java index 4dfc785a54ec..94f87ffe55ad 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java @@ -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(); diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java index 43781520aec5..1b46f3c62aa1 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java @@ -149,7 +149,9 @@ public class TestMtpManager extends MtpManager { if (mObjectInfos.containsKey(key)) { throw new IOException(); } - mObjectInfos.put(key, objectInfo); + final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo). + setObjectHandle(CREATED_DOCUMENT_HANDLE).build(); + mObjectInfos.put(key, newInfo); if (objectInfo.getFormat() != 0x3001) { try (final ParcelFileDescriptor.AutoCloseInputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(source)) { diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java index ffcc0882e019..34dd77bd3747 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java @@ -21,12 +21,11 @@ import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbManager; import android.os.SystemClock; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Objects; -import junit.framework.Assert; - /** * Static utility methods for testing. */ @@ -57,6 +56,22 @@ final class TestUtil { } } + static void addTestDevice(MtpDatabase database) throws FileNotFoundException { + database.getMapper().startAddingDocuments(null); + database.getMapper().putDeviceDocument(new MtpDeviceRecord( + 0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null, + null)); + database.getMapper().stopAddingDocuments(null); + } + + static void addTestStorage(MtpDatabase database, String parentId) throws FileNotFoundException { + database.getMapper().startAddingDocuments(parentId); + database.getMapper().putStorageDocuments(parentId, new MtpRoot[] { + new MtpRoot(0, 100, "Storage", 1024, 1024, ""), + }); + database.getMapper().stopAddingDocuments(parentId); + } + private static UsbDevice findMtpDevice( UsbManager usbManager, MtpManager manager) throws IOException { |