UsbRequest.java revision acc29cc91be634070c92a807df412ced97b9b375
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.hardware.usb;
18
19import android.util.Log;
20
21import java.nio.ByteBuffer;
22
23/**
24 * A class representing USB request packet.
25 * This can be used for both reading and writing data to or from a
26 * {@link android.hardware.usb.UsbDeviceConnection}.
27 * UsbRequests are sent asynchronously via {@link #queue} and the results
28 * are read by {@link android.hardware.usb.UsbDeviceConnection#requestWait}.
29 */
30public class UsbRequest {
31
32    private static final String TAG = "UsbRequest";
33
34    // used by the JNI code
35    private int mNativeContext;
36
37    private UsbEndpoint mEndpoint;
38
39    // for temporarily saving current buffer across queue and dequeue
40    private ByteBuffer mBuffer;
41    private int mLength;
42
43    // for client use
44    private Object mClientData;
45
46    public UsbRequest() {
47    }
48
49    /**
50     * Initializes the request so it can read or write data on the given endpoint.
51     * Whether the request allows reading or writing depends on the direction of the endpoint.
52     *
53     * @param endpoint the endpoint to be used for this request.
54     * @return true if the request was successfully opened.
55     */
56    public boolean initialize(UsbDeviceConnection connection, UsbEndpoint endpoint) {
57        mEndpoint = endpoint;
58        return native_init(connection, endpoint.getAddress(), endpoint.getAttributes(),
59                endpoint.getMaxPacketSize(), endpoint.getInterval());
60    }
61
62    /**
63     * Releases all resources related to this request.
64     */
65    public void close() {
66        mEndpoint = null;
67        native_close();
68    }
69
70    @Override
71    protected void finalize() throws Throwable {
72        try {
73            if (mEndpoint != null) {
74                Log.v(TAG, "endpoint still open in finalize(): " + this);
75                close();
76            }
77        } finally {
78            super.finalize();
79        }
80    }
81
82    /**
83     * Returns the endpoint for the request, or null if the request is not opened.
84     *
85     * @return the request's endpoint
86     */
87    public UsbEndpoint getEndpoint() {
88        return mEndpoint;
89    }
90
91    /**
92     * Returns the client data for the request.
93     * This can be used in conjunction with {@link #setClientData}
94     * to associate another object with this request, which can be useful for
95     * maintaining state between calls to {@link #queue} and
96     * {@link android.hardware.usb.UsbDeviceConnection#requestWait}
97     *
98     * @return the client data for the request
99     */
100    public Object getClientData() {
101        return mClientData;
102    }
103
104    /**
105     * Sets the client data for the request.
106     * This can be used in conjunction with {@link #getClientData}
107     * to associate another object with this request, which can be useful for
108     * maintaining state between calls to {@link #queue} and
109     * {@link android.hardware.usb.UsbDeviceConnection#requestWait}
110     *
111     * @param data the client data for the request
112     */
113    public void setClientData(Object data) {
114        mClientData = data;
115    }
116
117    /**
118     * Queues the request to send or receive data on its endpoint.
119     * For OUT endpoints, the given buffer data will be sent on the endpoint.
120     * For IN endpoints, the endpoint will attempt to read the given number of bytes
121     * into the specified buffer.
122     * If the queueing operation is successful, we return true and the result will be
123     * returned via {@link android.hardware.usb.UsbDeviceConnection#requestWait}
124     *
125     * @param buffer the buffer containing the bytes to write, or location to store
126     * the results of a read
127     * @param length number of bytes to read or write
128     * @return true if the queueing operation succeeded
129     */
130    public boolean queue(ByteBuffer buffer, int length) {
131        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
132        boolean result;
133        if (buffer.isDirect()) {
134            result = native_queue_direct(buffer, length, out);
135        } else if (buffer.hasArray()) {
136            result = native_queue_array(buffer.array(), length, out);
137        } else {
138            throw new IllegalArgumentException("buffer is not direct and has no array");
139        }
140        if (result) {
141            // save our buffer for when the request has completed
142            mBuffer = buffer;
143            mLength = length;
144        }
145        return result;
146    }
147
148    /* package */ void dequeue() {
149        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
150        if (mBuffer.isDirect()) {
151            native_dequeue_direct();
152        } else {
153            native_dequeue_array(mBuffer.array(), mLength, out);
154        }
155        mBuffer = null;
156        mLength = 0;
157    }
158
159    /**
160     * Cancels a pending queue operation.
161     *
162     * @return true if cancelling succeeded
163     */
164    public boolean cancel() {
165        return native_cancel();
166    }
167
168    private native boolean native_init(UsbDeviceConnection connection, int ep_address,
169            int ep_attributes, int ep_max_packet_size, int ep_interval);
170    private native void native_close();
171    private native boolean native_queue_array(byte[] buffer, int length, boolean out);
172    private native void native_dequeue_array(byte[] buffer, int length, boolean out);
173    private native boolean native_queue_direct(ByteBuffer buffer, int length, boolean out);
174    private native void native_dequeue_direct();
175    private native boolean native_cancel();
176}
177