Fix file transfer corner cases.

Fix zero packet read/write in corner cases
with initial read/writes. This affects transfers
of 16372 bytes to the device and transfers of
1012 bytes (or packet size - 12) from the device.

Test: Transfer various length files
Bug: 37175601
Change-Id: Ic1281e8757d1a33d78c66d2c57319b5ee38d6a46
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index c78002c..c50af2f 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -516,7 +516,7 @@
 }
 
 /* Read from USB and write to a local file. */
-int MtpFfsHandle::receiveFile(mtp_file_range mfr) {
+int MtpFfsHandle::receiveFile(mtp_file_range mfr, bool zero_packet) {
     // When receiving files, the incoming length is given in 32 bits.
     // A >4G file is given as 0xFFFFFFFF
     uint32_t file_length = mfr.length;
@@ -538,7 +538,7 @@
     aio.aio_fildes = mfr.fd;
     aio.aio_buf = nullptr;
     struct aiocb *aiol[] = {&aio};
-    int ret;
+    int ret = -1;
     size_t length;
     bool read = false;
     bool write = false;
@@ -590,11 +590,6 @@
             } else {
                 // Receive an empty packet if size is a multiple of the endpoint size.
                 file_length -= ret;
-                if (file_length == 0 && ret % packet_size == 0) {
-                    if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
-                        return -1;
-                    }
-                }
             }
             // Enqueue a new write request
             aio.aio_buf = data;
@@ -610,6 +605,11 @@
             read = false;
         }
     }
+    if (ret % packet_size == 0 || zero_packet) {
+        if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
+            return -1;
+        }
+    }
     return 0;
 }
 
@@ -660,10 +660,9 @@
                     sizeof(mtp_data_header), init_read_len, offset))
             != init_read_len) return -1;
     if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1;
-    if (file_length == static_cast<unsigned>(init_read_len)) return 0;
     file_length -= init_read_len;
     offset += init_read_len;
-    ret = 0;
+    ret = init_read_len + sizeof(mtp_data_header);
 
     // Break down the file into pieces that fit in buffers
     while(file_length > 0) {