Fix uploading multiple files via MtpDocumentsProvider.

Uploading was breaking as SendObject request was not being sent directly
after SendObjectInfo which is assumed by the MTP stack in Android.

Change-Id: I36b94f56682e79dec38add9be5f70f55d07e22e7
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 4ba0c1f..028c18d 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -225,6 +225,8 @@
             throws FileNotFoundException {
         try {
             final Identifier parentId = Identifier.createFromDocumentId(parentDocumentId);
+            final ParcelFileDescriptor pipe[] = ParcelFileDescriptor.createReliablePipe();
+            pipe[0].close();  // 0 bytes for a new document.
             final int objectHandle = mMtpManager.createDocument(
                     parentId.mDeviceId,
                     new MtpObjectInfo.Builder()
@@ -232,7 +234,7 @@
                             .setParent(parentId.mObjectHandle)
                             .setFormat(CursorHelper.mimeTypeToFormatType(mimeType))
                             .setName(displayName)
-                            .build());
+                            .build(), pipe[1]);
             final String documentId =  new Identifier(parentId.mDeviceId, parentId.mStorageId,
                    objectHandle).toDocumentId();
             notifyChildDocumentsChange(parentDocumentId);
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 7cfc679..ca78a3e 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -20,6 +20,7 @@
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbDeviceConnection;
 import android.hardware.usb.UsbManager;
+import android.mtp.MtpConstants;
 import android.mtp.MtpDevice;
 import android.mtp.MtpObjectInfo;
 import android.os.ParcelFileDescriptor;
@@ -138,13 +139,20 @@
         }
     }
 
-    synchronized int createDocument(int deviceId, MtpObjectInfo objectInfo) throws IOException {
+    synchronized int createDocument(int deviceId, MtpObjectInfo objectInfo,
+            ParcelFileDescriptor source) throws IOException {
         final MtpDevice device = getDevice(deviceId);
-        final MtpObjectInfo result = device.sendObjectInfo(objectInfo);
-        if (result == null) {
+        final MtpObjectInfo sendObjectInfoResult = device.sendObjectInfo(objectInfo);
+        if (sendObjectInfoResult == null) {
             throw new IOException("Failed to create a document");
         }
-        return result.getObjectHandle();
+        if (objectInfo.getFormat() != MtpConstants.FORMAT_ASSOCIATION) {
+            if (!device.sendObject(sendObjectInfoResult.getObjectHandle(),
+                    sendObjectInfoResult.getCompressedSize(), source)) {
+                throw new IOException("Failed to send contents of a document");
+            }
+        }
+        return sendObjectInfoResult.getObjectHandle();
     }
 
     synchronized int getParent(int deviceId, int objectHandle) throws IOException {
@@ -162,13 +170,6 @@
         device.importFile(objectHandle, target);
     }
 
-    synchronized void sendObject(int deviceId, int objectHandle, int size,
-            ParcelFileDescriptor source) throws IOException {
-        final MtpDevice device = getDevice(deviceId);
-        if (!device.sendObject(objectHandle, size, source))
-            throw new IOException("Failed to send a document");
-    }
-
     private MtpDevice getDevice(int deviceId) throws IOException {
         final MtpDevice device = mDevices.get(deviceId);
         if (device == null) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
index 53f1b65..cd38f1e 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
@@ -139,20 +139,15 @@
                 // Delete the target object info if it already exists (as a placeholder).
                 mManager.deleteDocument(mIdentifier.mDeviceId, mIdentifier.mObjectHandle);
 
-                // Create the target object info with a correct file size.
-                final int targetObjectHandle =
-                        mManager.createDocument(
-                                mIdentifier.mDeviceId,
-                                new MtpObjectInfo.Builder(placeholderObjectInfo)
-                                        .setCompressedSize((int) tempFile.length())
-                                        .build());
-
-                // Upload the object.
+                // 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())
+                                .build();
                 final ParcelFileDescriptor tempInputDescriptor = ParcelFileDescriptor.open(
                         tempFile, ParcelFileDescriptor.MODE_READ_ONLY);
-                mManager.sendObject(mIdentifier.mDeviceId,
-                        targetObjectHandle, (int) tempFile.length(), tempInputDescriptor);
-
+                mManager.createDocument(mIdentifier.mDeviceId,
+                        targetObjectInfo, tempInputDescriptor);
             } 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/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index bbdcd10..5605388 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -137,35 +137,29 @@
     }
 
     @Override
-    int createDocument(int deviceId, MtpObjectInfo objectInfo) throws IOException {
+    int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
+            throws IOException {
         final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
-        if (!mObjectInfos.containsKey(key)) {
-            mObjectInfos.put(key, objectInfo);
-        } else {
+        if (mObjectInfos.containsKey(key)) {
             throw new IOException();
         }
+        mObjectInfos.put(key, objectInfo);
+        if (objectInfo.getFormat() != 0x3001) {
+            try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
+                    new ParcelFileDescriptor.AutoCloseInputStream(source)) {
+                final byte[] buffer = new byte[objectInfo.getCompressedSize()];
+                if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) !=
+                        objectInfo.getCompressedSize()) {
+                    throw new IOException();
+                }
+
+                mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
+            }
+        }
         return CREATED_DOCUMENT_HANDLE;
     }
 
     @Override
-    void sendObject(int deviceId, int objectHandle, int size, ParcelFileDescriptor source)
-            throws IOException {
-        final String key = pack(deviceId, objectHandle);
-        if (!mObjectInfos.containsKey(key)) {
-            throw new IOException();
-        }
-
-        ParcelFileDescriptor.AutoCloseInputStream inputStream =
-                new ParcelFileDescriptor.AutoCloseInputStream(source);
-        byte[] buffer = new byte[size];
-        if (inputStream.read(buffer, 0, size) != size) {
-            throw new IOException();
-        }
-
-        mImportFileBytes.put(pack(deviceId, objectHandle), buffer);
-    }
-
-    @Override
     byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
         final String key = pack(deviceId, objectHandle);
         if (mThumbnailBytes.containsKey(key)) {