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