MTP: add a new parameter for cancelEvents function

Currently, cancelEvents in MTP will cancel the requests
one by one, and it will check each response to confirm
success or failure. However, if kernel usb controller
driver got the cancel request, the driver will handle
all requests in the same endpoint so that the second
io_cancel in cancelEvents will be useless. This behavior
change start from kernel 5.x.

This patch will add a parameter to check whether kernel
usb controller driver uses the new behavior so that MTP
could cancel the requests correctly.

Bug: 181729410
Test: cancel a transmitting file and then check the MTP operation
Change-Id: I8a2097e40feaa880de1d57921f5363eb98dbeb44
Merged-In: I4e172fa62c297ac33b0c97c67f3f7baa817fd8bf
(cherry picked from commit 305e62ec197f65ebf29d79e8d03ea3b296b4e690)
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index c8b4a03..4d50d66 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -74,6 +74,7 @@
 
 MtpFfsHandle::MtpFfsHandle(int controlFd) {
     mControl.reset(controlFd);
+    mBatchCancel = android::base::GetBoolProperty("sys.usb.mtp.batchcancel", false);
 }
 
 MtpFfsHandle::~MtpFfsHandle() {}
@@ -370,7 +371,7 @@
 }
 
 int MtpFfsHandle::cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start,
-        unsigned end) {
+        unsigned end, bool is_batch_cancel) {
     // Some manpages for io_cancel are out of date and incorrect.
     // io_cancel will return -EINPROGRESS on success and does
     // not place the event in the given memory. We have to use
@@ -386,6 +387,10 @@
         } else {
             num_events++;
         }
+        if (is_batch_cancel && num_events == 1) {
+            num_events = end - start;
+            break;
+        }
     }
     if (num_events != end - start) {
         ret = -1;
@@ -495,7 +500,8 @@
                 num_events += this_events;
 
                 if (event_ret == -1) {
-                    cancelEvents(mIobuf[i].iocb.data(), ioevs, num_events, mIobuf[i].actual);
+                    cancelEvents(mIobuf[i].iocb.data(), ioevs, num_events, mIobuf[i].actual,
+                            mBatchCancel);
                     return -1;
                 }
                 ret += event_ret;
@@ -512,7 +518,7 @@
                 }
             }
             if (short_packet) {
-                if (cancelEvents(mIobuf[i].iocb.data(), ioevs, short_i, mIobuf[i].actual)) {
+                if (cancelEvents(mIobuf[i].iocb.data(), ioevs, short_i, mIobuf[i].actual, false)) {
                     write_error = true;
                 }
             }
@@ -613,7 +619,7 @@
                         &num_events) != ret) {
                 error = true;
                 cancelEvents(mIobuf[(i-1)%NUM_IO_BUFS].iocb.data(), ioevs, num_events,
-                        mIobuf[(i-1)%NUM_IO_BUFS].actual);
+                        mIobuf[(i-1)%NUM_IO_BUFS].actual, false);
             }
             has_write = false;
         }
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index fe343f7..e552e03 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -17,6 +17,7 @@
 #ifndef _MTP_FFS_HANDLE_H
 #define _MTP_FFS_HANDLE_H
 
+#include <android-base/properties.h>
 #include <android-base/unique_fd.h>
 #include <linux/aio_abi.h>
 #include <mutex>
@@ -57,6 +58,7 @@
     static int getPacketSize(int ffs_fd);
 
     bool mCanceled;
+    bool mBatchCancel;
 
     android::base::unique_fd mControl;
     // "in" from the host's perspective => sink for mtp server
@@ -76,7 +78,8 @@
     int iobufSubmit(struct io_buffer *buf, int fd, unsigned length, bool read);
 
     // Cancel submitted requests from start to end in the given array. Return 0 or -1.
-    int cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start, unsigned end);
+    int cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start, unsigned end,
+		     bool is_batch_cancel);
 
     // Wait for at minimum the given number of events. Returns the amount of data in the returned
     // events. Increments counter by the number of events returned.