1e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood/*
2e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * Copyright (C) 2010 The Android Open Source Project
3e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood *
4e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
5e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * you may not use this file except in compliance with the License.
6e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * You may obtain a copy of the License at
7e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood *
8e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
9e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood *
10e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * Unless required by applicable law or agreed to in writing, software
11e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
12e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * See the License for the specific language governing permissions and
14e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood * limitations under the License.
15e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood */
16e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
17e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood#define LOG_TAG "UsbRequestJNI"
18e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
19e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood#include "utils/Log.h"
20e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
21e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood#include "jni.h"
222279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h>
23ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
24e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
25e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood#include <usbhost/usbhost.h>
26e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
27e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood#include <stdio.h>
28e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
29e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodusing namespace android;
30e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
31e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstatic jfieldID field_context;
32e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
33e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstruct usb_request* get_request_from_object(JNIEnv* env, jobject java_request)
34e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
354838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat    return (struct usb_request*)env->GetLongField(java_request, field_context);
36e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
37e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
38acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood// in android_hardware_UsbDeviceConnection.cpp
39acc29cc91be634070c92a807df412ced97b9b375Mike Lockwoodextern struct usb_device* get_device_from_object(JNIEnv* env, jobject connection);
40e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
41e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstatic jboolean
42e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_init(JNIEnv *env, jobject thiz, jobject java_device,
43e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        jint ep_address, jint ep_attributes, jint ep_max_packet_size, jint ep_interval)
44e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
455baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("init\n");
46e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
47e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_device* device = get_device_from_object(env, java_device);
48e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (!device) {
493762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("device null in native_init");
504346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann        return JNI_FALSE;
51e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
52e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
53e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    // construct an endpoint descriptor from the Java object fields
54e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_endpoint_descriptor desc;
55e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    desc.bLength = USB_DT_ENDPOINT_SIZE;
56e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    desc.bDescriptorType = USB_DT_ENDPOINT;
57e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    desc.bEndpointAddress = ep_address;
58e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    desc.bmAttributes = ep_attributes;
59e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    desc.wMaxPacketSize = ep_max_packet_size;
60e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    desc.bInterval = ep_interval;
61e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
62e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = usb_request_new(device, &desc);
63e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (request)
644838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat        env->SetLongField(thiz, field_context, (jlong)request);
65e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    return (request != NULL);
66e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
67e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
68e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstatic void
69e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_close(JNIEnv *env, jobject thiz)
70e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
715baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("close\n");
72e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = get_request_from_object(env, thiz);
73e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (request) {
74e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        usb_request_free(request);
754838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat        env->SetLongField(thiz, field_context, 0);
76e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
77e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
78e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
79e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstatic jboolean
80e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_queue_array(JNIEnv *env, jobject thiz,
81e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        jbyteArray buffer, jint length, jboolean out)
82e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
83e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = get_request_from_object(env, thiz);
84e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (!request) {
853762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("request is closed in native_queue");
864346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann        return JNI_FALSE;
87e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
88e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
89e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (buffer && length) {
90e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        request->buffer = malloc(length);
91e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        if (!request->buffer)
924346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann            return JNI_FALSE;
93a3665ba95d806fcb6780d29d49bd0f1032e8bc86mike wakerly        memset(request->buffer, 0, length);
94e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        if (out) {
95e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood            // copy data from Java buffer to native buffer
96e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood            env->GetByteArrayRegion(buffer, 0, length, (jbyte *)request->buffer);
97e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        }
98e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    } else {
99e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        request->buffer = NULL;
100e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
101e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    request->buffer_length = length;
102e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
103b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood    // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
104b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood    request->client_data = (void *)env->NewGlobalRef(thiz);
105b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood
106e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (usb_request_queue(request)) {
107e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        if (request->buffer) {
108e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood            // free our buffer if usb_request_queue fails
109e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood            free(request->buffer);
110e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood            request->buffer = NULL;
111e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        }
112b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood        env->DeleteGlobalRef((jobject)request->client_data);
1134346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann        return JNI_FALSE;
114e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
1154346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann    return JNI_TRUE;
116e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
117e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
1184838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint
119e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_dequeue_array(JNIEnv *env, jobject thiz,
120e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        jbyteArray buffer, jint length, jboolean out)
121e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
122e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = get_request_from_object(env, thiz);
123e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (!request) {
1243762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("request is closed in native_dequeue");
1254838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat        return (jint) -1;
126e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
127e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
128e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (buffer && length && request->buffer && !out) {
129e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        // copy data from native buffer to Java buffer
130e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        env->SetByteArrayRegion(buffer, 0, length, (jbyte *)request->buffer);
131e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
132e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    free(request->buffer);
133e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    env->DeleteGlobalRef((jobject)request->client_data);
1344838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat    return (jint) request->actual_length;
135e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
136e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
137e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstatic jboolean
138e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_queue_direct(JNIEnv *env, jobject thiz,
139e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        jobject buffer, jint length, jboolean out)
140e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
141e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = get_request_from_object(env, thiz);
142e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (!request) {
1433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("request is closed in native_queue");
1444346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann        return JNI_FALSE;
145e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
146e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
147e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (buffer && length) {
148e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        request->buffer = env->GetDirectBufferAddress(buffer);
149e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        if (!request->buffer)
1504346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann            return JNI_FALSE;
151e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    } else {
152e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        request->buffer = NULL;
153e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
154e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    request->buffer_length = length;
155e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
156b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood    // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
157b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood    // we also need this to make sure our native buffer is not deallocated
158b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood    // while IO is active
159b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood    request->client_data = (void *)env->NewGlobalRef(thiz);
160b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood
161e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (usb_request_queue(request)) {
162e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        request->buffer = NULL;
163b2a4658a630a99b0e0ff44bc54aa5b02557a571bMike Lockwood        env->DeleteGlobalRef((jobject)request->client_data);
1644346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann        return JNI_FALSE;
165e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
1664346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann    return JNI_TRUE;
167e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
168e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
16908b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmannstatic jboolean
17091ed33b03292eb65f88175813875b12ba9a7eb51Philip P. Moltmannandroid_hardware_UsbRequest_queue(JNIEnv *env, jobject thiz, jobject buffer, jint offset,
17108b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        jint length)
17208b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann{
17308b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    struct usb_request* request = get_request_from_object(env, thiz);
17408b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    if (!request) {
17508b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        ALOGE("request is closed in native_queue");
17608b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        return JNI_FALSE;
17708b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    }
17808b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann
17908b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    if (buffer == NULL) {
18008b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        request->buffer = NULL;
18108b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        request->buffer_length = 0;
18208b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    } else {
18308b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        request->buffer = (void *)((char *)env->GetDirectBufferAddress(buffer) + offset);
18408b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        request->buffer_length = length;
18508b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    }
18608b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann
18708b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    // Save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us.
18808b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    // We also need this to make sure our native buffer is not deallocated while IO is active.
18908b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    request->client_data = (void *)env->NewGlobalRef(thiz);
19008b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann
19108b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    int err = usb_request_queue(request);
19208b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann
19308b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    if (err != 0) {
19408b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        request->buffer = NULL;
19508b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        env->DeleteGlobalRef((jobject)request->client_data);
19608b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann        return JNI_FALSE;
19708b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    }
19808b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann    return JNI_TRUE;
19908b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann}
20008b678c0299153e4843e637ed29d5404dae54b4fPhilip P. Moltmann
2014838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint
202e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_dequeue_direct(JNIEnv *env, jobject thiz)
203e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
204e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = get_request_from_object(env, thiz);
205e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (!request) {
2063762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("request is closed in native_dequeue");
2074838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat        return (jint) -1;
208e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
209e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    // all we need to do is delete our global ref
210e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    env->DeleteGlobalRef((jobject)request->client_data);
2114838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat    return (jint) request->actual_length;
212e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
213e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
214e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodstatic jboolean
215e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodandroid_hardware_UsbRequest_cancel(JNIEnv *env, jobject thiz)
216e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
217e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    struct usb_request* request = get_request_from_object(env, thiz);
218e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (!request) {
2193762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("request is closed in native_cancel");
2204346f3c5ec7bc9a5d6cced81c0d7584d69d7397aPhilip P. Moltmann        return JNI_FALSE;
221e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
222e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    return (usb_request_cancel(request) == 0);
223e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
224e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
22576f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod method_table[] = {
226acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood    {"native_init",             "(Landroid/hardware/usb/UsbDeviceConnection;IIII)Z",
227e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood                                            (void *)android_hardware_UsbRequest_init},
228e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    {"native_close",            "()V",      (void *)android_hardware_UsbRequest_close},
22991ed33b03292eb65f88175813875b12ba9a7eb51Philip P. Moltmann    {"native_queue",            "(Ljava/nio/ByteBuffer;II)Z",
23091ed33b03292eb65f88175813875b12ba9a7eb51Philip P. Moltmann                                            (void *)android_hardware_UsbRequest_queue},
231e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    {"native_queue_array",      "([BIZ)Z",  (void *)android_hardware_UsbRequest_queue_array},
232a3665ba95d806fcb6780d29d49bd0f1032e8bc86mike wakerly    {"native_dequeue_array",    "([BIZ)I",  (void *)android_hardware_UsbRequest_dequeue_array},
233e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    {"native_queue_direct",     "(Ljava/nio/ByteBuffer;IZ)Z",
234e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood                                            (void *)android_hardware_UsbRequest_queue_direct},
235a3665ba95d806fcb6780d29d49bd0f1032e8bc86mike wakerly    {"native_dequeue_direct",   "()I",      (void *)android_hardware_UsbRequest_dequeue_direct},
236e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    {"native_cancel",           "()Z",      (void *)android_hardware_UsbRequest_cancel},
237e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood};
238e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
239e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwoodint register_android_hardware_UsbRequest(JNIEnv *env)
240e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood{
241c4308f01c965571dc2354107c3574df113e397eeMike Lockwood    jclass clazz = env->FindClass("android/hardware/usb/UsbRequest");
242e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (clazz == NULL) {
2433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/hardware/usb/UsbRequest");
244e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        return -1;
245e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
2464838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat    field_context = env->GetFieldID(clazz, "mNativeContext", "J");
247e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    if (field_context == NULL) {
2483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find UsbRequest.mNativeContext");
249e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood        return -1;
250e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood    }
251e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
252ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env, "android/hardware/usb/UsbRequest",
253e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood            method_table, NELEM(method_table));
254e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood}
255e7d511e148bc901ef41ac44d7b3593e5d803f72fMike Lockwood
256