UsbRequest: set ByteBuffer.position() upon success.

Also clears allocated buffer before copying.

Closes http://b.android.com/28023

Bug: 5385026
Bug: 6766413
Change-Id: Icf2c1d45db4fb2a9bd1fcfdb29aa7308034faaf0
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index 2252248..3646715 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -152,10 +152,14 @@
 
     /* package */ void dequeue() {
         boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
+        int bytesRead;
         if (mBuffer.isDirect()) {
-            native_dequeue_direct();
+            bytesRead = native_dequeue_direct();
         } else {
-            native_dequeue_array(mBuffer.array(), mLength, out);
+            bytesRead = native_dequeue_array(mBuffer.array(), mLength, out);
+        }
+        if (bytesRead >= 0) {
+            mBuffer.position(Math.min(bytesRead, mLength));
         }
         mBuffer = null;
         mLength = 0;
@@ -174,8 +178,8 @@
             int ep_attributes, int ep_max_packet_size, int ep_interval);
     private native void native_close();
     private native boolean native_queue_array(byte[] buffer, int length, boolean out);
-    private native void native_dequeue_array(byte[] buffer, int length, boolean out);
+    private native int native_dequeue_array(byte[] buffer, int length, boolean out);
     private native boolean native_queue_direct(ByteBuffer buffer, int length, boolean out);
-    private native void native_dequeue_direct();
+    private native int native_dequeue_direct();
     private native boolean native_cancel();
 }
diff --git a/core/jni/android_hardware_UsbRequest.cpp b/core/jni/android_hardware_UsbRequest.cpp
index 1398968..32d5135 100644
--- a/core/jni/android_hardware_UsbRequest.cpp
+++ b/core/jni/android_hardware_UsbRequest.cpp
@@ -90,6 +90,7 @@
         request->buffer = malloc(length);
         if (!request->buffer)
             return false;
+        memset(request->buffer, 0, length);
         if (out) {
             // copy data from Java buffer to native buffer
             env->GetByteArrayRegion(buffer, 0, length, (jbyte *)request->buffer);
@@ -113,14 +114,14 @@
     }
 }
 
-static void
+static int
 android_hardware_UsbRequest_dequeue_array(JNIEnv *env, jobject thiz,
         jbyteArray buffer, jint length, jboolean out)
 {
     struct usb_request* request = get_request_from_object(env, thiz);
     if (!request) {
         ALOGE("request is closed in native_dequeue");
-        return;
+        return -1;
     }
 
     if (buffer && length && request->buffer && !out) {
@@ -129,7 +130,7 @@
     }
     free(request->buffer);
     env->DeleteGlobalRef((jobject)request->client_data);
-
+    return request->actual_length;
 }
 
 static jboolean
@@ -163,16 +164,17 @@
     }
 }
 
-static void
+static int
 android_hardware_UsbRequest_dequeue_direct(JNIEnv *env, jobject thiz)
 {
     struct usb_request* request = get_request_from_object(env, thiz);
     if (!request) {
         ALOGE("request is closed in native_dequeue");
-        return;
+        return -1;
     }
     // all we need to do is delete our global ref
     env->DeleteGlobalRef((jobject)request->client_data);
+    return request->actual_length;
 }
 
 static jboolean
@@ -191,10 +193,10 @@
                                             (void *)android_hardware_UsbRequest_init},
     {"native_close",            "()V",      (void *)android_hardware_UsbRequest_close},
     {"native_queue_array",      "([BIZ)Z",  (void *)android_hardware_UsbRequest_queue_array},
-    {"native_dequeue_array",    "([BIZ)V",  (void *)android_hardware_UsbRequest_dequeue_array},
+    {"native_dequeue_array",    "([BIZ)I",  (void *)android_hardware_UsbRequest_dequeue_array},
     {"native_queue_direct",     "(Ljava/nio/ByteBuffer;IZ)Z",
                                             (void *)android_hardware_UsbRequest_queue_direct},
-    {"native_dequeue_direct",   "()V",      (void *)android_hardware_UsbRequest_dequeue_direct},
+    {"native_dequeue_direct",   "()I",      (void *)android_hardware_UsbRequest_dequeue_direct},
     {"native_cancel",           "()Z",      (void *)android_hardware_UsbRequest_cancel},
 };