UsbRequest.java revision c4308f01c965571dc2354107c3574df113e397ee
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.UsbDevice}.
27 * UsbRequests are sent asynchronously via {@link #queue} and the results
28 * are read by {@link android.hardware.usb.UsbDevice#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(UsbEndpoint endpoint) {
57        mEndpoint = endpoint;
58        return native_init(endpoint.getDevice(),
59                endpoint.getAddress(), endpoint.getAttributes(),
60                endpoint.getMaxPacketSize(), endpoint.getInterval());
61    }
62
63    /**
64     * Releases all resources related to this request.
65     */
66    public void close() {
67        mEndpoint = null;
68        native_close();
69    }
70
71    @Override
72    protected void finalize() throws Throwable {
73        try {
74            if (mEndpoint != null) {
75                Log.v(TAG, "endpoint still open in finalize(): " + this);
76                close();
77            }
78        } finally {
79            super.finalize();
80        }
81    }
82
83    /**
84     * Returns the endpoint for the request, or null if the request is not opened.
85     *
86     * @return the request's endpoint
87     */
88    public UsbEndpoint getEndpoint() {
89        return mEndpoint;
90    }
91
92    /**
93     * Returns the client data for the request.
94     * This can be used in conjunction with {@link #setClientData}
95     * to associate another object with this request, which can be useful for
96     * maintaining state between calls to {@link #queue} and
97     * {@link android.hardware.usb.UsbDevice#requestWait}
98     *
99     * @return the client data for the request
100     */
101    public Object getClientData() {
102        return mClientData;
103    }
104
105    /**
106     * Sets the client data for the request.
107     * This can be used in conjunction with {@link #getClientData}
108     * to associate another object with this request, which can be useful for
109     * maintaining state between calls to {@link #queue} and
110     * {@link android.hardware.usb.UsbDevice#requestWait}
111     *
112     * @param data the client data for the request
113     */
114    public void setClientData(Object data) {
115        mClientData = data;
116    }
117
118    /**
119     * Queues the request to send or receive data on its endpoint.
120     * For OUT endpoints, the given buffer data will be sent on the endpoint.
121     * For IN endpoints, the endpoint will attempt to read the given number of bytes
122     * into the specified buffer.
123     * If the queueing operation is successful, we return true and the result will be
124     * returned via {@link android.hardware.usb.UsbDevice#requestWait}
125     *
126     * @param buffer the buffer containing the bytes to write, or location to store
127     * the results of a read
128     * @param length number of bytes to read or write
129     * @return true if the queueing operation succeeded
130     */
131    public boolean queue(ByteBuffer buffer, int length) {
132        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
133        boolean result;
134        if (buffer.isDirect()) {
135            result = native_queue_direct(buffer, length, out);
136        } else if (buffer.hasArray()) {
137            result = native_queue_array(buffer.array(), length, out);
138        } else {
139            throw new IllegalArgumentException("buffer is not direct and has no array");
140        }
141        if (result) {
142            // save our buffer for when the request has completed
143            mBuffer = buffer;
144            mLength = length;
145        }
146        return result;
147    }
148
149    /* package */ void dequeue() {
150        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
151        if (mBuffer.isDirect()) {
152            native_dequeue_direct();
153        } else {
154            native_dequeue_array(mBuffer.array(), mLength, out);
155        }
156        mBuffer = null;
157        mLength = 0;
158    }
159
160    /**
161     * Cancels a pending queue operation.
162     *
163     * @return true if cancelling succeeded
164     */
165    public boolean cancel() {
166        return native_cancel();
167    }
168
169    private native boolean native_init(UsbDevice device, int ep_address, int ep_attributes,
170            int ep_max_packet_size, int ep_interval);
171    private native void native_close();
172    private native boolean native_queue_array(byte[] buffer, int length, boolean out);
173    private native void native_dequeue_array(byte[] buffer, int length, boolean out);
174    private native boolean native_queue_direct(ByteBuffer buffer, int length, boolean out);
175    private native void native_dequeue_direct();
176    private native boolean native_cancel();
177}
178