Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c81a93e authored by Jeff Brown's avatar Jeff Brown
Browse files

Support specifying buffer start offset for USB requests.

Deprecated existing API which only supported passing buffer
and length in favor of a new one that also supports passing
the start.

Being able to pass a start index is very important because
the kernel imposes size limits on how much data can be transferred
at a time so we often need to transmit large buffers in chunks.

Change-Id: I3484b5e68f1ece61d4645ea04be8ee6a3b79169d
parent cdee9727
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -10305,10 +10305,12 @@ package android.hardware.usb {
  }
  public class UsbDeviceConnection {
    method public int bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int);
    method public deprecated int bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int);
    method public int bulkTransfer(android.hardware.usb.UsbEndpoint, byte[], int, int, int);
    method public boolean claimInterface(android.hardware.usb.UsbInterface, boolean);
    method public void close();
    method public int controlTransfer(int, int, int, int, byte[], int, int);
    method public deprecated int controlTransfer(int, int, int, int, byte[], int, int);
    method public int controlTransfer(int, int, int, int, byte[], int, int, int);
    method public int getFileDescriptor();
    method public byte[] getRawDescriptors();
    method public java.lang.String getSerial();
+68 −7
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.hardware.usb;

import android.os.ParcelFileDescriptor;
import android.util.Log;

import java.io.FileDescriptor;

@@ -119,10 +118,41 @@ public class UsbDeviceConnection {
     * @param timeout in milliseconds
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     *
     * @deprecate Use {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}
     * which accepts a buffer start index.
     */
    @Deprecated
    public int controlTransfer(int requestType, int request, int value,
            int index, byte[] buffer, int length, int timeout) {
        return native_control_request(requestType, request, value, index, buffer, length, timeout);
        return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout);
    }

    /**
     * Performs a control transaction on endpoint zero for this device.
     * The direction of the transfer is determined by the request type.
     * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
     * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write,
     * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer
     * is a read.
     *
     * @param requestType request type for this transaction
     * @param request request ID for this transaction
     * @param value value field for this transaction
     * @param index index field for this transaction
     * @param buffer buffer for data portion of transaction,
     * or null if no data needs to be sent or received
     * @param start the index of the first byte in the buffer to send or receive
     * @param length the length of the data to send or receive
     * @param timeout in milliseconds
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     */
    public int controlTransfer(int requestType, int request, int value, int index,
            byte[] buffer, int start, int length, int timeout) {
        checkBounds(buffer, start, length);
        return native_control_request(requestType, request, value, index,
                buffer, start, length, timeout);
    }

    /**
@@ -130,14 +160,37 @@ public class UsbDeviceConnection {
     * The direction of the transfer is determined by the direction of the endpoint
     *
     * @param endpoint the endpoint for this transaction
     * @param buffer buffer for data to send or receive,
     * @param buffer buffer for data to send or receive
     * @param length the length of the data to send or receive
     * @param timeout in milliseconds
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     *
     * @deprecate Use {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}
     * which accepts a buffer start index.
     */
    public int bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout) {
        return native_bulk_request(endpoint.getAddress(), buffer, length, timeout);
    @Deprecated
    public int bulkTransfer(UsbEndpoint endpoint,
            byte[] buffer, int length, int timeout) {
        return bulkTransfer(endpoint, buffer, 0, length, timeout);
    }

    /**
     * Performs a bulk transaction on the given endpoint.
     * The direction of the transfer is determined by the direction of the endpoint
     *
     * @param endpoint the endpoint for this transaction
     * @param buffer buffer for data to send or receive
     * @param start the index of the first byte in the buffer to send or receive
     * @param length the length of the data to send or receive
     * @param timeout in milliseconds
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     */
    public int bulkTransfer(UsbEndpoint endpoint,
            byte[] buffer, int start, int length, int timeout) {
        checkBounds(buffer, start, length);
        return native_bulk_request(endpoint.getAddress(), buffer, start, length, timeout);
    }

    /**
@@ -168,6 +221,13 @@ public class UsbDeviceConnection {
        return native_get_serial();
    }

    private static void checkBounds(byte[] buffer, int start, int length) {
        final int bufferLength = (buffer != null ? buffer.length : 0);
        if (start < 0 || start + length > bufferLength) {
            throw new IllegalArgumentException("Buffer start or length out of bounds.");
        }
    }

    private native boolean native_open(String deviceName, FileDescriptor pfd);
    private native void native_close();
    private native int native_get_fd();
@@ -175,8 +235,9 @@ public class UsbDeviceConnection {
    private native boolean native_claim_interface(int interfaceID, boolean force);
    private native boolean native_release_interface(int interfaceID);
    private native int native_control_request(int requestType, int request, int value,
            int index, byte[] buffer, int length, int timeout);
    private native int native_bulk_request(int endpoint, byte[] buffer, int length, int timeout);
            int index, byte[] buffer, int start, int length, int timeout);
    private native int native_bulk_request(int endpoint, byte[] buffer,
            int start, int length, int timeout);
    private native UsbRequest native_request_wait();
    private native String native_get_serial();
}
+14 −20
Original line number Diff line number Diff line
@@ -142,7 +142,7 @@ android_hardware_UsbDeviceConnection_release_interface(JNIEnv *env, jobject thiz
static jint
android_hardware_UsbDeviceConnection_control_request(JNIEnv *env, jobject thiz,
        jint requestType, jint request, jint value, jint index,
        jbyteArray buffer, jint length, jint timeout)
        jbyteArray buffer, jint start, jint length, jint timeout)
{
    struct usb_device* device = get_device_from_object(env, thiz);
    if (!device) {
@@ -152,25 +152,22 @@ android_hardware_UsbDeviceConnection_control_request(JNIEnv *env, jobject thiz,

    jbyte* bufferBytes = NULL;
    if (buffer) {
        if (env->GetArrayLength(buffer) < length) {
            jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
            return -1;
        }
        bufferBytes = env->GetByteArrayElements(buffer, 0);
        bufferBytes = (jbyte*)env->GetPrimitiveArrayCritical(buffer, NULL);
    }

    jint result = usb_device_control_transfer(device, requestType, request,
            value, index, bufferBytes, length, timeout);
            value, index, bufferBytes + start, length, timeout);

    if (bufferBytes)
        env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
    if (bufferBytes) {
        env->ReleasePrimitiveArrayCritical(buffer, bufferBytes, 0);
    }

    return result;
}

static jint
android_hardware_UsbDeviceConnection_bulk_request(JNIEnv *env, jobject thiz,
        jint endpoint, jbyteArray buffer, jint length, jint timeout)
        jint endpoint, jbyteArray buffer, jint start, jint length, jint timeout)
{
    struct usb_device* device = get_device_from_object(env, thiz);
    if (!device) {
@@ -180,17 +177,14 @@ android_hardware_UsbDeviceConnection_bulk_request(JNIEnv *env, jobject thiz,

    jbyte* bufferBytes = NULL;
    if (buffer) {
        if (env->GetArrayLength(buffer) < length) {
            jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
            return -1;
        }
        bufferBytes = env->GetByteArrayElements(buffer, 0);
        bufferBytes = (jbyte*)env->GetPrimitiveArrayCritical(buffer, NULL);
    }

    jint result = usb_device_bulk_transfer(device, endpoint, bufferBytes, length, timeout);
    jint result = usb_device_bulk_transfer(device, endpoint, bufferBytes + start, length, timeout);

    if (bufferBytes)
        env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
    if (bufferBytes) {
        env->ReleasePrimitiveArrayCritical(buffer, bufferBytes, 0);
    }

    return result;
}
@@ -235,9 +229,9 @@ static JNINativeMethod method_table[] = {
    {"native_get_desc",         "()[B", (void *)android_hardware_UsbDeviceConnection_get_desc},
    {"native_claim_interface",  "(IZ)Z",(void *)android_hardware_UsbDeviceConnection_claim_interface},
    {"native_release_interface","(I)Z", (void *)android_hardware_UsbDeviceConnection_release_interface},
    {"native_control_request",  "(IIII[BII)I",
    {"native_control_request",  "(IIII[BIII)I",
                                        (void *)android_hardware_UsbDeviceConnection_control_request},
    {"native_bulk_request",     "(I[BII)I",
    {"native_bulk_request",     "(I[BIII)I",
                                        (void *)android_hardware_UsbDeviceConnection_bulk_request},
    {"native_request_wait",             "()Landroid/hardware/usb/UsbRequest;",
                                        (void *)android_hardware_UsbDeviceConnection_request_wait},