Merge "Change requestWait API according to request" into oc-dev

am: ca687ac39a

Change-Id: I19a3ca83efc1934448e1044b9be74087f89dd030
This commit is contained in:
Philip P. Moltmann
2017-04-07 13:27:33 +00:00
committed by android-build-merger
6 changed files with 62 additions and 23 deletions

View File

@@ -15950,7 +15950,7 @@ package android.hardware.usb {
method public java.lang.String getSerial(); method public java.lang.String getSerial();
method public boolean releaseInterface(android.hardware.usb.UsbInterface); method public boolean releaseInterface(android.hardware.usb.UsbInterface);
method public android.hardware.usb.UsbRequest requestWait(); method public android.hardware.usb.UsbRequest requestWait();
method public android.hardware.usb.UsbRequest requestWait(int); method public android.hardware.usb.UsbRequest requestWait(long) throws java.util.concurrent.TimeoutException;
method public boolean setConfiguration(android.hardware.usb.UsbConfiguration); method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
method public boolean setInterface(android.hardware.usb.UsbInterface); method public boolean setInterface(android.hardware.usb.UsbInterface);
} }

View File

@@ -17440,7 +17440,7 @@ package android.hardware.usb {
method public java.lang.String getSerial(); method public java.lang.String getSerial();
method public boolean releaseInterface(android.hardware.usb.UsbInterface); method public boolean releaseInterface(android.hardware.usb.UsbInterface);
method public android.hardware.usb.UsbRequest requestWait(); method public android.hardware.usb.UsbRequest requestWait();
method public android.hardware.usb.UsbRequest requestWait(int); method public android.hardware.usb.UsbRequest requestWait(long) throws java.util.concurrent.TimeoutException;
method public boolean resetDevice(); method public boolean resetDevice();
method public boolean setConfiguration(android.hardware.usb.UsbConfiguration); method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
method public boolean setInterface(android.hardware.usb.UsbInterface); method public boolean setInterface(android.hardware.usb.UsbInterface);

View File

@@ -16005,7 +16005,7 @@ package android.hardware.usb {
method public java.lang.String getSerial(); method public java.lang.String getSerial();
method public boolean releaseInterface(android.hardware.usb.UsbInterface); method public boolean releaseInterface(android.hardware.usb.UsbInterface);
method public android.hardware.usb.UsbRequest requestWait(); method public android.hardware.usb.UsbRequest requestWait();
method public android.hardware.usb.UsbRequest requestWait(int); method public android.hardware.usb.UsbRequest requestWait(long) throws java.util.concurrent.TimeoutException;
method public boolean setConfiguration(android.hardware.usb.UsbConfiguration); method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
method public boolean setInterface(android.hardware.usb.UsbInterface); method public boolean setInterface(android.hardware.usb.UsbInterface);
} }

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
@@ -27,7 +28,9 @@ import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard; import dalvik.system.CloseGuard;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.concurrent.TimeoutException;
/** /**
* This class is used for sending and receiving data and control messages to a USB device. * This class is used for sending and receiving data and control messages to a USB device.
@@ -268,16 +271,29 @@ public class UsbDeviceConnection {
* *
* @return a completed USB request, or null if an error occurred * @return a completed USB request, or null if an error occurred
* *
* @throws IllegalArgumentException if the number of bytes read or written is more than the * @throws IllegalArgumentException Before API {@value Build.VERSION_CODES#O}: if the number of
* limit of the request's buffer. The number of bytes is * bytes read or written is more than the limit of the
* determined by the {@code length} parameter of * request's buffer. The number of bytes is determined by the
* {@code length} parameter of
* {@link UsbRequest#queue(ByteBuffer, int)} * {@link UsbRequest#queue(ByteBuffer, int)}
* @throws BufferOverflowException In API {@value Build.VERSION_CODES#O} and after: if the
* number of bytes read or written is more than the limit of the
* request's buffer. The number of bytes is determined by the
* {@code length} parameter of
* {@link UsbRequest#queue(ByteBuffer, int)}
*/ */
public UsbRequest requestWait() { public UsbRequest requestWait() {
// -1 is special value indicating infinite wait UsbRequest request = null;
UsbRequest request = native_request_wait(-1); try {
// -1 is special value indicating infinite wait
request = native_request_wait(-1);
} catch (TimeoutException e) {
// Does not happen, infinite timeout
}
if (request != null) { if (request != null) {
request.dequeue(); request.dequeue(
mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O);
} }
return request; return request;
} }
@@ -290,24 +306,25 @@ public class UsbDeviceConnection {
* android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process * android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process
* the result of this function.</p> * the result of this function.</p>
* <p>Android processes {@link UsbRequest UsbRequests} asynchronously. Hence it is not * <p>Android processes {@link UsbRequest UsbRequests} asynchronously. Hence it is not
* guaranteed that {@link #requestWait(int) requestWait(0)} returns a request that has been * guaranteed that {@link #requestWait(long) requestWait(0)} returns a request that has been
* queued right before even if the request could have been processed immediately.</p> * queued right before even if the request could have been processed immediately.</p>
* *
* @param timeout timeout in milliseconds. If 0 this method does not wait. * @param timeout timeout in milliseconds. If 0 this method does not wait.
* *
* @return a completed USB request, or {@code null} if an error or time out occurred * @return a completed USB request, or {@code null} if an error occurred
* *
* @throws IllegalArgumentException if the number of bytes read or written is more than the * @throws BufferOverflowException if the number of bytes read or written is more than the
* limit of the request's buffer. The number of bytes is * limit of the request's buffer. The number of bytes is
* determined by the {@code length} parameter of * determined by the {@code length} parameter of
* {@link UsbRequest#queue(ByteBuffer, int)} * {@link UsbRequest#queue(ByteBuffer, int)}
* @throws TimeoutException if no request was received in {@code timeout} milliseconds.
*/ */
public UsbRequest requestWait(int timeout) { public UsbRequest requestWait(long timeout) throws TimeoutException {
timeout = Preconditions.checkArgumentNonnegative(timeout, "timeout"); timeout = Preconditions.checkArgumentNonnegative(timeout, "timeout");
UsbRequest request = native_request_wait(timeout); UsbRequest request = native_request_wait(timeout);
if (request != null) { if (request != null) {
request.dequeue(); request.dequeue(true);
} }
return request; return request;
} }
@@ -350,7 +367,7 @@ public class UsbDeviceConnection {
int index, byte[] buffer, int offset, int length, int timeout); int index, byte[] buffer, int offset, int length, int timeout);
private native int native_bulk_request(int endpoint, byte[] buffer, private native int native_bulk_request(int endpoint, byte[] buffer,
int offset, int length, int timeout); int offset, int length, int timeout);
private native UsbRequest native_request_wait(int timeout); private native UsbRequest native_request_wait(long timeout) throws TimeoutException;
private native String native_get_serial(); private native String native_get_serial();
private native boolean native_reset_device(); private native boolean native_reset_device();
} }

View File

@@ -17,11 +17,13 @@
package android.hardware.usb; package android.hardware.usb;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.util.Log;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard; import dalvik.system.CloseGuard;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
@@ -276,7 +278,7 @@ public class UsbRequest {
return wasQueued; return wasQueued;
} }
/* package */ void dequeue() { /* package */ void dequeue(boolean useBufferOverflowInsteadOfIllegalArg) {
boolean isSend = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT); boolean isSend = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
int bytesTransferred; int bytesTransferred;
@@ -313,7 +315,18 @@ public class UsbRequest {
bytesTransferred = native_dequeue_array(mBuffer.array(), mLength, isSend); bytesTransferred = native_dequeue_array(mBuffer.array(), mLength, isSend);
} }
if (bytesTransferred >= 0) { if (bytesTransferred >= 0) {
mBuffer.position(Math.min(bytesTransferred, mLength)); int bytesToStore = Math.min(bytesTransferred, mLength);
try {
mBuffer.position(bytesToStore);
} catch (IllegalArgumentException e) {
if (useBufferOverflowInsteadOfIllegalArg) {
Log.e(TAG, "Buffer " + mBuffer + " does not have enough space to read "
+ bytesToStore + " bytes", e);
throw new BufferOverflowException();
} else {
throw e;
}
}
} }
} }

View File

@@ -220,7 +220,7 @@ android_hardware_UsbDeviceConnection_bulk_request(JNIEnv *env, jobject thiz,
} }
static jobject static jobject
android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz, jint timeoutMillis) android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz, jlong timeoutMillis)
{ {
struct usb_device* device = get_device_from_object(env, thiz); struct usb_device* device = get_device_from_object(env, thiz);
if (!device) { if (!device) {
@@ -243,8 +243,17 @@ android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz, jin
- currentTime).count()); - currentTime).count());
int error = errno; int error = errno;
if (request != NULL) {
break;
}
currentTime = steady_clock::now(); currentTime = steady_clock::now();
if (request != NULL || error != EAGAIN || currentTime >= endTime) { if (currentTime >= endTime) {
jniThrowException(env, "java/util/concurrent/TimeoutException", "");
break;
}
if (error != EAGAIN) {
break; break;
} }
}; };
@@ -300,7 +309,7 @@ static const JNINativeMethod method_table[] = {
(void *)android_hardware_UsbDeviceConnection_control_request}, (void *)android_hardware_UsbDeviceConnection_control_request},
{"native_bulk_request", "(I[BIII)I", {"native_bulk_request", "(I[BIII)I",
(void *)android_hardware_UsbDeviceConnection_bulk_request}, (void *)android_hardware_UsbDeviceConnection_bulk_request},
{"native_request_wait", "(I)Landroid/hardware/usb/UsbRequest;", {"native_request_wait", "(J)Landroid/hardware/usb/UsbRequest;",
(void *)android_hardware_UsbDeviceConnection_request_wait}, (void *)android_hardware_UsbDeviceConnection_request_wait},
{ "native_get_serial", "()Ljava/lang/String;", { "native_get_serial", "()Ljava/lang/String;",
(void*)android_hardware_UsbDeviceConnection_get_serial }, (void*)android_hardware_UsbDeviceConnection_get_serial },