summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-12-30 13:39:37 -0500
committerMike Lockwood <lockwood@android.com>2011-01-22 15:56:09 -0800
commite7d511e148bc901ef41ac44d7b3593e5d803f72f (patch)
tree4561bf7d69a83c285c874c6b9ec038f9411d062c /core/jni
parentf5426634d8228c5bc3fe968caf09cc369e5a9272 (diff)
downloadframeworks_base-e7d511e148bc901ef41ac44d7b3593e5d803f72f.zip
frameworks_base-e7d511e148bc901ef41ac44d7b3593e5d803f72f.tar.gz
frameworks_base-e7d511e148bc901ef41ac44d7b3593e5d803f72f.tar.bz2
New APIs for USB host support:
UsbManager: - is now a service retrievable via Context.getSystemService(Context.USB_SERVICE). - provides support for returning a list all connected USB devices - broadcasts ACTION_USB_DEVICE_ATTACHED and USB_DEVICE_DETACHED when devices are added and removed from the USB host bus UsbDevice: - represents an attached USB device. UsbInterface: - represents an interface on a USB device - devices may have multiple interfaces if they provide multiple sets of functionality (for example, android phones typically have interfaces for both USB mass storage and adb) UsbEndpoint: - represents an endpoint on a USB interface - endpoints are used for sending or receiving data (only in one or the other direction) UsbRequest: - encapsulates a send or receive request to be sent over an endpoint Change-Id: Ieef3e434c62760770ea839070cf5eba1a705967a Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/Android.mk3
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android_hardware_UsbDevice.cpp239
-rw-r--r--core/jni/android_hardware_UsbEndpoint.cpp124
-rw-r--r--core/jni/android_hardware_UsbRequest.cpp217
5 files changed, 587 insertions, 0 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c635b39..d1e7e5c 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -124,6 +124,8 @@ LOCAL_SRC_FILES:= \
android_media_ToneGenerator.cpp \
android_hardware_Camera.cpp \
android_hardware_SensorManager.cpp \
+ android_hardware_UsbDevice.cpp \
+ android_hardware_UsbRequest.cpp \
android_debug_JNITest.cpp \
android_util_FileObserver.cpp \
android/opengl/poly_clip.cpp.arm \
@@ -202,6 +204,7 @@ LOCAL_SHARED_LIBRARIES := \
libwpa_client \
libjpeg \
libnfc_ndef \
+ libusbhost \
ifeq ($(USE_OPENGL_RENDERER),true)
LOCAL_SHARED_LIBRARIES += libhwui
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 342b884..c1c6c91 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -77,6 +77,8 @@ extern int register_android_opengl_jni_GLES20(JNIEnv* env);
extern int register_android_hardware_Camera(JNIEnv *env);
extern int register_android_hardware_SensorManager(JNIEnv *env);
+extern int register_android_hardware_UsbDevice(JNIEnv *env);
+extern int register_android_hardware_UsbRequest(JNIEnv *env);
extern int register_android_media_AudioRecord(JNIEnv *env);
extern int register_android_media_AudioSystem(JNIEnv *env);
@@ -1275,6 +1277,8 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_SensorManager),
+ REG_JNI(register_android_hardware_UsbDevice),
+ REG_JNI(register_android_hardware_UsbRequest),
REG_JNI(register_android_media_AudioRecord),
REG_JNI(register_android_media_AudioSystem),
REG_JNI(register_android_media_AudioTrack),
diff --git a/core/jni/android_hardware_UsbDevice.cpp b/core/jni/android_hardware_UsbDevice.cpp
new file mode 100644
index 0000000..22cf387
--- /dev/null
+++ b/core/jni/android_hardware_UsbDevice.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "UsbDeviceJNI"
+
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <usbhost/usbhost.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+using namespace android;
+
+static jfieldID field_context;
+
+struct usb_device* get_device_from_object(JNIEnv* env, jobject javaDevice)
+{
+ return (struct usb_device*)env->GetIntField(javaDevice, field_context);
+}
+
+// in android_hardware_UsbEndpoint.cpp
+extern struct usb_endpoint* get_endpoint_from_object(JNIEnv* env, jobject javaEndpoint);
+
+static jboolean
+android_hardware_UsbDevice_open(JNIEnv *env, jobject thiz, jstring deviceName,
+ jobject fileDescriptor)
+{
+ int fd = getParcelFileDescriptorFD(env, fileDescriptor);
+ // duplicate the file descriptor, since ParcelFileDescriptor will eventually close its copy
+ fd = dup(fd);
+ if (fd < 0)
+ return false;
+
+ const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
+ struct usb_device* device = usb_device_new(deviceNameStr, fd);
+ if (device) {
+ env->SetIntField(thiz, field_context, (int)device);
+ } else {
+ LOGE("usb_device_open failed for %s", deviceNameStr);
+ close(fd);
+ }
+
+ env->ReleaseStringUTFChars(deviceName, deviceNameStr);
+ return (device != NULL);
+}
+
+static void
+android_hardware_UsbDevice_close(JNIEnv *env, jobject thiz)
+{
+ LOGD("close\n");
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (device) {
+ usb_device_close(device);
+ env->SetIntField(thiz, field_context, 0);
+ }
+}
+
+static jint
+android_hardware_UsbDevice_get_fd(JNIEnv *env, jobject thiz)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_get_fd");
+ return -1;
+ }
+ return usb_device_get_fd(device);
+}
+
+static jint
+android_hardware_UsbDevice_claim_interface(JNIEnv *env, jobject thiz, int interfaceID, jboolean force)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_claim_interface");
+ return -1;
+ }
+
+ int ret = usb_device_claim_interface(device, interfaceID);
+ if (ret && force && errno == EBUSY) {
+ // disconnect kernel driver and try again
+ usb_device_connect_kernel_driver(device, interfaceID, false);
+ ret = usb_device_claim_interface(device, interfaceID);
+ }
+ return ret;
+}
+
+static jint
+android_hardware_UsbDevice_release_interface(JNIEnv *env, jobject thiz, int interfaceID)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_release_interface");
+ return -1;
+ }
+ int ret = usb_device_release_interface(device, interfaceID);
+ if (ret == 0) {
+ // allow kernel to reconnect its driver
+ usb_device_connect_kernel_driver(device, interfaceID, true);
+ }
+ return ret;
+}
+
+static jint
+android_hardware_UsbDevice_control_request(JNIEnv *env, jobject thiz,
+ jint requestType, jint request, jint value, jint index,
+ jbyteArray buffer, jint length)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_control_request");
+ return -1;
+ }
+
+ jbyte* bufferBytes = NULL;
+ if (buffer) {
+ if (env->GetArrayLength(buffer) < length) {
+ env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
+ return -1;
+ }
+ bufferBytes = env->GetByteArrayElements(buffer, 0);
+ }
+
+ jint result = usb_device_send_control(device, requestType, request,
+ value, index, length, bufferBytes);
+
+ if (bufferBytes)
+ env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
+
+ return result;
+}
+
+static jobject
+android_hardware_UsbDevice_request_wait(JNIEnv *env, jobject thiz)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_request_wait");
+ return NULL;
+ }
+
+ struct usb_request* request = usb_request_wait(device);
+ if (request)
+ return (jobject)request->client_data;
+ else
+ return NULL;
+}
+
+static jstring
+android_hardware_UsbDevice_get_serial(JNIEnv *env, jobject thiz)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_request_wait");
+ return NULL;
+ }
+ char* serial = usb_device_get_serial(device);
+ if (!serial)
+ return NULL;
+ jstring result = env->NewStringUTF(serial);
+ free(serial);
+ return result;
+}
+
+static jint
+android_hardware_UsbDevice_get_device_id(JNIEnv *env, jobject clazz, jstring name)
+{
+ const char *nameStr = env->GetStringUTFChars(name, NULL);
+ int id = usb_device_get_unique_id_from_name(nameStr);
+ env->ReleaseStringUTFChars(name, nameStr);
+ return id;
+}
+
+static jstring
+android_hardware_UsbDevice_get_device_name(JNIEnv *env, jobject clazz, jint id)
+{
+ char* name = usb_device_get_name_from_unique_id(id);
+ jstring result = env->NewStringUTF(name);
+ free(name);
+ return result;
+}
+
+static JNINativeMethod method_table[] = {
+ {"native_open", "(Ljava/lang/String;Ljava/io/FileDescriptor;)Z",
+ (void *)android_hardware_UsbDevice_open},
+ {"native_close", "()V", (void *)android_hardware_UsbDevice_close},
+ {"native_get_fd", "()I", (void *)android_hardware_UsbDevice_get_fd},
+ {"native_claim_interface", "(IZ)Z",(void *)android_hardware_UsbDevice_claim_interface},
+ {"native_release_interface","(I)Z", (void *)android_hardware_UsbDevice_release_interface},
+ {"native_control_request", "(IIII[BI)I",
+ (void *)android_hardware_UsbDevice_control_request},
+ {"native_request_wait", "()Landroid/hardware/UsbRequest;",
+ (void *)android_hardware_UsbDevice_request_wait},
+ { "native_get_serial", "()Ljava/lang/String;",
+ (void*)android_hardware_UsbDevice_get_serial },
+
+ // static methods
+ { "native_get_device_id", "(Ljava/lang/String;)I",
+ (void*)android_hardware_UsbDevice_get_device_id },
+ { "native_get_device_name", "(I)Ljava/lang/String;",
+ (void*)android_hardware_UsbDevice_get_device_name },
+};
+
+int register_android_hardware_UsbDevice(JNIEnv *env)
+{
+ jclass clazz = env->FindClass("android/hardware/UsbDevice");
+ if (clazz == NULL) {
+ LOGE("Can't find android/hardware/UsbDevice");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find UsbDevice.mNativeContext");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env, "android/hardware/UsbDevice",
+ method_table, NELEM(method_table));
+}
+
diff --git a/core/jni/android_hardware_UsbEndpoint.cpp b/core/jni/android_hardware_UsbEndpoint.cpp
new file mode 100644
index 0000000..00c8235
--- /dev/null
+++ b/core/jni/android_hardware_UsbEndpoint.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "UsbEndpoint"
+
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <usbhost/usbhost.h>
+
+#include <stdio.h>
+
+using namespace android;
+
+static jfieldID field_context;
+static jfieldID field_address;
+static jfieldID field_attributes;
+static jfieldID field_max_packet_size;
+static jfieldID field_interval;
+
+struct usb_endpoint* get_endpoint_from_object(JNIEnv* env, jobject javaEndpoint)
+{
+ return (struct usb_endpoint*)env->GetIntField(javaEndpoint, field_context);
+}
+
+// in android_hardware_UsbDevice.cpp
+extern struct usb_device* get_device_from_object(JNIEnv* env, jobject javaDevice);
+
+static jboolean
+android_hardware_UsbEndpoint_init(JNIEnv *env, jobject thiz, jobject javaDevice)
+{
+ LOGD("open\n");
+
+ struct usb_device* device = get_device_from_object(env, javaDevice);
+ if (!device) {
+ LOGE("device null in native_init");
+ return false;
+ }
+
+ // construct an endpoint descriptor from the Java object fields
+ struct usb_endpoint_descriptor desc;
+ desc.bLength = USB_DT_ENDPOINT_SIZE;
+ desc.bDescriptorType = USB_DT_ENDPOINT;
+ desc.bEndpointAddress = env->GetIntField(thiz, field_address);
+ desc.bmAttributes = env->GetIntField(thiz, field_attributes);
+ desc.wMaxPacketSize = env->GetIntField(thiz, field_max_packet_size);
+ desc.bInterval = env->GetIntField(thiz, field_interval);
+
+ struct usb_endpoint* endpoint = usb_endpoint_init(device, &desc);
+ if (endpoint)
+ env->SetIntField(thiz, field_context, (int)device);
+ return (endpoint != NULL);
+}
+
+static void
+android_hardware_UsbEndpoint_close(JNIEnv *env, jobject thiz)
+{
+ LOGD("close\n");
+ struct usb_endpoint* endpoint = get_endpoint_from_object(env, thiz);
+ if (endpoint) {
+ usb_endpoint_close(endpoint);
+ env->SetIntField(thiz, field_context, 0);
+ }
+}
+
+static JNINativeMethod method_table[] = {
+ {"native_init", "(Landroid/hardware/UsbDevice;)Z",
+ (void *)android_hardware_UsbEndpoint_init},
+ {"native_close", "()V", (void *)android_hardware_UsbEndpoint_close},
+};
+
+int register_android_hardware_UsbEndpoint(JNIEnv *env)
+{
+ jclass clazz = env->FindClass("android/hardware/UsbEndpoint");
+ if (clazz == NULL) {
+ LOGE("Can't find android/hardware/UsbEndpoint");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find UsbEndpoint.mNativeContext");
+ return -1;
+ }
+ field_address = env->GetFieldID(clazz, "mAddress", "I");
+ if (field_address == NULL) {
+ LOGE("Can't find UsbEndpoint.mAddress");
+ return -1;
+ }
+ field_attributes = env->GetFieldID(clazz, "mAttributes", "I");
+ if (field_attributes == NULL) {
+ LOGE("Can't find UsbEndpoint.mAttributes");
+ return -1;
+ }
+ field_max_packet_size = env->GetFieldID(clazz, "mMaxPacketSize", "I");
+ if (field_max_packet_size == NULL) {
+ LOGE("Can't find UsbEndpoint.mMaxPacketSize");
+ return -1;
+ }
+ field_interval = env->GetFieldID(clazz, "mInterval", "I");
+ if (field_interval == NULL) {
+ LOGE("Can't find UsbEndpoint.mInterval");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env, "android/hardware/UsbEndpoint",
+ method_table, NELEM(method_table));
+}
+
diff --git a/core/jni/android_hardware_UsbRequest.cpp b/core/jni/android_hardware_UsbRequest.cpp
new file mode 100644
index 0000000..710afae
--- /dev/null
+++ b/core/jni/android_hardware_UsbRequest.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "UsbRequestJNI"
+
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <usbhost/usbhost.h>
+
+#include <stdio.h>
+
+using namespace android;
+
+static jfieldID field_context;
+
+struct usb_request* get_request_from_object(JNIEnv* env, jobject java_request)
+{
+ return (struct usb_request*)env->GetIntField(java_request, field_context);
+}
+
+// in android_hardware_UsbDevice.cpp
+extern struct usb_device* get_device_from_object(JNIEnv* env, jobject java_device);
+
+static jboolean
+android_hardware_UsbRequest_init(JNIEnv *env, jobject thiz, jobject java_device,
+ jint ep_address, jint ep_attributes, jint ep_max_packet_size, jint ep_interval)
+{
+ LOGD("init\n");
+
+ struct usb_device* device = get_device_from_object(env, java_device);
+ if (!device) {
+ LOGE("device null in native_init");
+ return false;
+ }
+
+ // construct an endpoint descriptor from the Java object fields
+ struct usb_endpoint_descriptor desc;
+ desc.bLength = USB_DT_ENDPOINT_SIZE;
+ desc.bDescriptorType = USB_DT_ENDPOINT;
+ desc.bEndpointAddress = ep_address;
+ desc.bmAttributes = ep_attributes;
+ desc.wMaxPacketSize = ep_max_packet_size;
+ desc.bInterval = ep_interval;
+
+ struct usb_request* request = usb_request_new(device, &desc);
+ if (request)
+ env->SetIntField(thiz, field_context, (int)request);
+ return (request != NULL);
+}
+
+static void
+android_hardware_UsbRequest_close(JNIEnv *env, jobject thiz)
+{
+ LOGD("close\n");
+ struct usb_request* request = get_request_from_object(env, thiz);
+ if (request) {
+ usb_request_free(request);
+ env->SetIntField(thiz, field_context, 0);
+ }
+}
+
+static jboolean
+android_hardware_UsbRequest_queue_array(JNIEnv *env, jobject thiz,
+ jbyteArray buffer, jint length, jboolean out)
+{
+ struct usb_request* request = get_request_from_object(env, thiz);
+ if (!request) {
+ LOGE("request is closed in native_queue");
+ return false;
+ }
+
+ if (buffer && length) {
+ request->buffer = malloc(length);
+ if (!request->buffer)
+ return false;
+ if (out) {
+ // copy data from Java buffer to native buffer
+ env->GetByteArrayRegion(buffer, 0, length, (jbyte *)request->buffer);
+ }
+ } else {
+ request->buffer = NULL;
+ }
+ request->buffer_length = length;
+
+ if (usb_request_queue(request)) {
+ if (request->buffer) {
+ // free our buffer if usb_request_queue fails
+ free(request->buffer);
+ request->buffer = NULL;
+ }
+ return false;
+ } else {
+ // save a reference to ourselves so UsbDevice.waitRequest() can find us
+ request->client_data = (void *)env->NewGlobalRef(thiz);
+ return true;
+ }
+}
+
+static void
+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) {
+ LOGE("request is closed in native_dequeue");
+ return;
+ }
+
+ if (buffer && length && request->buffer && !out) {
+ // copy data from native buffer to Java buffer
+ env->SetByteArrayRegion(buffer, 0, length, (jbyte *)request->buffer);
+ }
+ free(request->buffer);
+ env->DeleteGlobalRef((jobject)request->client_data);
+
+}
+
+static jboolean
+android_hardware_UsbRequest_queue_direct(JNIEnv *env, jobject thiz,
+ jobject buffer, jint length, jboolean out)
+{
+ struct usb_request* request = get_request_from_object(env, thiz);
+ if (!request) {
+ LOGE("request is closed in native_queue");
+ return false;
+ }
+
+ if (buffer && length) {
+ request->buffer = env->GetDirectBufferAddress(buffer);
+ if (!request->buffer)
+ return false;
+ } else {
+ request->buffer = NULL;
+ }
+ request->buffer_length = length;
+
+ if (usb_request_queue(request)) {
+ request->buffer = NULL;
+ return false;
+ } else {
+ // save a reference to ourselves so UsbDevice.waitRequest() can find us
+ // we also need this to make sure our native buffer is not deallocated
+ // while IO is active
+ request->client_data = (void *)env->NewGlobalRef(thiz);
+ return true;
+ }
+}
+
+static void
+android_hardware_UsbRequest_dequeue_direct(JNIEnv *env, jobject thiz)
+{
+ struct usb_request* request = get_request_from_object(env, thiz);
+ if (!request) {
+ LOGE("request is closed in native_dequeue");
+ return;
+ }
+ // all we need to do is delete our global ref
+ env->DeleteGlobalRef((jobject)request->client_data);
+}
+
+static jboolean
+android_hardware_UsbRequest_cancel(JNIEnv *env, jobject thiz)
+{
+ struct usb_request* request = get_request_from_object(env, thiz);
+ if (!request) {
+ LOGE("request is closed in native_cancel");
+ return false;
+ }
+ return (usb_request_cancel(request) == 0);
+}
+
+static JNINativeMethod method_table[] = {
+ {"native_init", "(Landroid/hardware/UsbDevice;IIII)Z",
+ (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_queue_direct", "(Ljava/nio/ByteBuffer;IZ)Z",
+ (void *)android_hardware_UsbRequest_queue_direct},
+ {"native_dequeue_direct", "()V", (void *)android_hardware_UsbRequest_dequeue_direct},
+ {"native_cancel", "()Z", (void *)android_hardware_UsbRequest_cancel},
+};
+
+int register_android_hardware_UsbRequest(JNIEnv *env)
+{
+ jclass clazz = env->FindClass("android/hardware/UsbRequest");
+ if (clazz == NULL) {
+ LOGE("Can't find android/hardware/UsbRequest");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find UsbRequest.mNativeContext");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env, "android/hardware/UsbRequest",
+ method_table, NELEM(method_table));
+}
+