Merge "Add UsbDeviceConnection.requestWait with a timeout"
This commit is contained in:
committed by
Android (Google) Code Review
commit
411f8215fc
@@ -14781,6 +14781,7 @@ package android.hardware.usb {
|
||||
method public java.lang.String getSerial();
|
||||
method public boolean releaseInterface(android.hardware.usb.UsbInterface);
|
||||
method public android.hardware.usb.UsbRequest requestWait();
|
||||
method public android.hardware.usb.UsbRequest requestWait(int);
|
||||
method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
|
||||
method public boolean setInterface(android.hardware.usb.UsbInterface);
|
||||
}
|
||||
|
||||
@@ -15990,6 +15990,7 @@ package android.hardware.usb {
|
||||
method public java.lang.String getSerial();
|
||||
method public boolean releaseInterface(android.hardware.usb.UsbInterface);
|
||||
method public android.hardware.usb.UsbRequest requestWait();
|
||||
method public android.hardware.usb.UsbRequest requestWait(int);
|
||||
method public boolean resetDevice();
|
||||
method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
|
||||
method public boolean setInterface(android.hardware.usb.UsbInterface);
|
||||
|
||||
@@ -14798,6 +14798,7 @@ package android.hardware.usb {
|
||||
method public java.lang.String getSerial();
|
||||
method public boolean releaseInterface(android.hardware.usb.UsbInterface);
|
||||
method public android.hardware.usb.UsbRequest requestWait();
|
||||
method public android.hardware.usb.UsbRequest requestWait(int);
|
||||
method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
|
||||
method public boolean setInterface(android.hardware.usb.UsbInterface);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import dalvik.system.CloseGuard;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -273,7 +276,40 @@ public class UsbDeviceConnection {
|
||||
* {@link UsbRequest#queue(ByteBuffer, int)}
|
||||
*/
|
||||
public UsbRequest requestWait() {
|
||||
UsbRequest request = native_request_wait();
|
||||
// -1 is special value indicating infinite wait
|
||||
UsbRequest request = native_request_wait(-1);
|
||||
if (request != null) {
|
||||
request.dequeue();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation
|
||||
* <p>Note that this may return requests queued on multiple
|
||||
* {@link android.hardware.usb.UsbEndpoint}s. When multiple endpoints are in use,
|
||||
* {@link android.hardware.usb.UsbRequest#getEndpoint} and {@link
|
||||
* android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process
|
||||
* the result of this function.</p>
|
||||
* <p>Position and array offset of the request's buffer are ignored and assumed to be 0. The
|
||||
* position will be set to the number of bytes read/written.</p>
|
||||
* <p>Android processes {@link UsbRequest UsbRequests} asynchronously. Hence it is not
|
||||
* guaranteed that {@link #requestWait(int) requestWait(0)} returns a request that has been
|
||||
* 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.
|
||||
*
|
||||
* @return a completed USB request, or {@code null} if an error or time out occurred
|
||||
*
|
||||
* @throws IllegalArgumentException 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(int timeout) {
|
||||
timeout = Preconditions.checkArgumentNonnegative(timeout);
|
||||
|
||||
UsbRequest request = native_request_wait(timeout);
|
||||
if (request != null) {
|
||||
request.dequeue();
|
||||
}
|
||||
@@ -318,7 +354,7 @@ public class UsbDeviceConnection {
|
||||
int index, byte[] buffer, int offset, int length, int timeout);
|
||||
private native int native_bulk_request(int endpoint, byte[] buffer,
|
||||
int offset, int length, int timeout);
|
||||
private native UsbRequest native_request_wait();
|
||||
private native UsbRequest native_request_wait(int timeout);
|
||||
private native String native_get_serial();
|
||||
private native boolean native_reset_device();
|
||||
}
|
||||
|
||||
@@ -24,12 +24,15 @@
|
||||
|
||||
#include <usbhost/usbhost.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
using namespace android;
|
||||
using namespace std::chrono;
|
||||
|
||||
static const int USB_CONTROL_READ_TIMEOUT_MS = 200;
|
||||
|
||||
@@ -217,7 +220,7 @@ android_hardware_UsbDeviceConnection_bulk_request(JNIEnv *env, jobject thiz,
|
||||
}
|
||||
|
||||
static jobject
|
||||
android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz)
|
||||
android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz, jint timeoutMillis)
|
||||
{
|
||||
struct usb_device* device = get_device_from_object(env, thiz);
|
||||
if (!device) {
|
||||
@@ -225,11 +228,33 @@ android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct usb_request* request = usb_request_wait(device);
|
||||
if (request)
|
||||
struct usb_request* request;
|
||||
if (timeoutMillis == -1) {
|
||||
request = usb_request_wait(device, -1);
|
||||
} else {
|
||||
steady_clock::time_point currentTime = steady_clock::now();
|
||||
steady_clock::time_point endTime = currentTime + std::chrono::milliseconds(timeoutMillis);
|
||||
|
||||
// Poll the existence of a request via usb_request_wait until we get a result, an unexpected
|
||||
// error or time out. As several threads can listen on the same fd, we might get wakeups
|
||||
// without data.
|
||||
while (1) {
|
||||
request = usb_request_wait(device, duration_cast<std::chrono::milliseconds>(endTime
|
||||
- currentTime).count());
|
||||
|
||||
int error = errno;
|
||||
currentTime = steady_clock::now();
|
||||
if (request != NULL || error != EAGAIN || currentTime >= endTime) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (request) {
|
||||
return (jobject)request->client_data;
|
||||
else
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static jstring
|
||||
@@ -275,7 +300,7 @@ static const JNINativeMethod method_table[] = {
|
||||
(void *)android_hardware_UsbDeviceConnection_control_request},
|
||||
{"native_bulk_request", "(I[BIII)I",
|
||||
(void *)android_hardware_UsbDeviceConnection_bulk_request},
|
||||
{"native_request_wait", "()Landroid/hardware/usb/UsbRequest;",
|
||||
{"native_request_wait", "(I)Landroid/hardware/usb/UsbRequest;",
|
||||
(void *)android_hardware_UsbDeviceConnection_request_wait},
|
||||
{ "native_get_serial", "()Ljava/lang/String;",
|
||||
(void*)android_hardware_UsbDeviceConnection_get_serial },
|
||||
|
||||
Reference in New Issue
Block a user