Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 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 | |
| 17 | package android.hardware.usb; |
| 18 | |
Philip P. Moltmann | ec3cbb2 | 2016-09-14 13:24:52 -0700 | [diff] [blame] | 19 | import android.annotation.NonNull; |
| 20 | import android.annotation.Nullable; |
Jeff Sharkey | 6f95ab2 | 2017-07-17 13:15:16 -0600 | [diff] [blame] | 21 | import android.annotation.SuppressLint; |
Keun-young Park | badbbae | 2016-01-05 13:27:29 -0800 | [diff] [blame] | 22 | import android.annotation.SystemApi; |
Mathew Inwood | bcbe440 | 2018-08-08 15:42:59 +0100 | [diff] [blame] | 23 | import android.annotation.UnsupportedAppUsage; |
Philip P. Moltmann | ec3cbb2 | 2016-09-14 13:24:52 -0700 | [diff] [blame] | 24 | import android.content.Context; |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 25 | import android.os.Build; |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 26 | import android.os.ParcelFileDescriptor; |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 27 | |
| 28 | import com.android.internal.util.Preconditions; |
| 29 | |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 30 | import dalvik.system.CloseGuard; |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 31 | |
| 32 | import java.io.FileDescriptor; |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 33 | import java.nio.BufferOverflowException; |
Philip P. Moltmann | 5dd4e6c | 2016-09-23 15:31:23 -0700 | [diff] [blame] | 34 | import java.nio.ByteBuffer; |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 35 | import java.util.concurrent.TimeoutException; |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 36 | |
| 37 | /** |
Mike Lockwood | 11dd5ae | 2011-04-01 14:00:08 -0400 | [diff] [blame] | 38 | * This class is used for sending and receiving data and control messages to a USB device. |
| 39 | * Instances of this class are created by {@link UsbManager#openDevice}. |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 40 | */ |
| 41 | public class UsbDeviceConnection { |
| 42 | |
| 43 | private static final String TAG = "UsbDeviceConnection"; |
| 44 | |
| 45 | private final UsbDevice mDevice; |
| 46 | |
Philip P. Moltmann | ec3cbb2 | 2016-09-14 13:24:52 -0700 | [diff] [blame] | 47 | private Context mContext; |
| 48 | |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 49 | // used by the JNI code |
Mathew Inwood | bcbe440 | 2018-08-08 15:42:59 +0100 | [diff] [blame] | 50 | @UnsupportedAppUsage |
Ashok Bhat | 4838e33 | 2014-01-03 14:37:19 +0000 | [diff] [blame] | 51 | private long mNativeContext; |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 52 | |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 53 | private final CloseGuard mCloseGuard = CloseGuard.get(); |
| 54 | |
Al Sutton | ca53d07 | 2019-05-16 12:53:42 +0100 | [diff] [blame] | 55 | private final Object mLock = new Object(); |
| 56 | |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 57 | /** |
| 58 | * UsbDevice should only be instantiated by UsbService implementation |
| 59 | * @hide |
| 60 | */ |
| 61 | public UsbDeviceConnection(UsbDevice device) { |
| 62 | mDevice = device; |
| 63 | } |
| 64 | |
Philip P. Moltmann | ec3cbb2 | 2016-09-14 13:24:52 -0700 | [diff] [blame] | 65 | /* package */ boolean open(String name, ParcelFileDescriptor pfd, @NonNull Context context) { |
| 66 | mContext = context.getApplicationContext(); |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 67 | |
Al Sutton | ca53d07 | 2019-05-16 12:53:42 +0100 | [diff] [blame] | 68 | synchronized (mLock) { |
| 69 | boolean wasOpened = native_open(name, pfd.getFileDescriptor()); |
| 70 | |
| 71 | if (wasOpened) { |
| 72 | mCloseGuard.open("close"); |
| 73 | } |
| 74 | |
| 75 | return wasOpened; |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 76 | } |
Al Sutton | ca53d07 | 2019-05-16 12:53:42 +0100 | [diff] [blame] | 77 | } |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 78 | |
Al Sutton | ca53d07 | 2019-05-16 12:53:42 +0100 | [diff] [blame] | 79 | /*** |
| 80 | * @return If this connection is currently open and usable. |
| 81 | */ |
| 82 | boolean isOpen() { |
| 83 | return mNativeContext != 0; |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | /** |
Philip P. Moltmann | ec3cbb2 | 2016-09-14 13:24:52 -0700 | [diff] [blame] | 87 | * @return The application context the connection was created for. |
| 88 | * |
| 89 | * @hide |
| 90 | */ |
| 91 | public @Nullable Context getContext() { |
| 92 | return mContext; |
| 93 | } |
| 94 | |
| 95 | /** |
Al Sutton | ca53d07 | 2019-05-16 12:53:42 +0100 | [diff] [blame] | 96 | * Cancel a request which relates to this connection. |
| 97 | * |
| 98 | * @return true if the request was successfully cancelled. |
| 99 | */ |
| 100 | /* package */ boolean cancelRequest(UsbRequest request) { |
| 101 | synchronized (mLock) { |
| 102 | if (!isOpen()) { |
| 103 | return false; |
| 104 | } |
| 105 | |
| 106 | return request.cancelIfOpen(); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | /** |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 111 | * Releases all system resources related to the device. |
Mike Lockwood | 11dd5ae | 2011-04-01 14:00:08 -0400 | [diff] [blame] | 112 | * Once the object is closed it cannot be used again. |
| 113 | * The client must call {@link UsbManager#openDevice} again |
| 114 | * to retrieve a new instance to reestablish communication with the device. |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 115 | */ |
| 116 | public void close() { |
Al Sutton | ca53d07 | 2019-05-16 12:53:42 +0100 | [diff] [blame] | 117 | synchronized (mLock) { |
| 118 | if (isOpen()) { |
| 119 | native_close(); |
| 120 | mCloseGuard.close(); |
| 121 | } |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 122 | } |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | /** |
Mike Lockwood | 11dd5ae | 2011-04-01 14:00:08 -0400 | [diff] [blame] | 126 | * Returns the native file descriptor for the device, or |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 127 | * -1 if the device is not opened. |
Mike Lockwood | 11dd5ae | 2011-04-01 14:00:08 -0400 | [diff] [blame] | 128 | * This is intended for passing to native code to access the device. |
| 129 | * |
| 130 | * @return the native file descriptor |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 131 | */ |
| 132 | public int getFileDescriptor() { |
| 133 | return native_get_fd(); |
| 134 | } |
| 135 | |
| 136 | /** |
Mike Lockwood | a88b42d | 2011-05-19 11:52:40 -0400 | [diff] [blame] | 137 | * Returns the raw USB descriptors for the device. |
| 138 | * This can be used to access descriptors not supported directly |
| 139 | * via the higher level APIs. |
| 140 | * |
| 141 | * @return raw USB descriptors |
| 142 | */ |
| 143 | public byte[] getRawDescriptors() { |
| 144 | return native_get_desc(); |
| 145 | } |
| 146 | |
| 147 | /** |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 148 | * Claims exclusive access to a {@link android.hardware.usb.UsbInterface}. |
| 149 | * This must be done before sending or receiving data on any |
Mike Lockwood | 11dd5ae | 2011-04-01 14:00:08 -0400 | [diff] [blame] | 150 | * {@link android.hardware.usb.UsbEndpoint}s belonging to the interface. |
| 151 | * |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 152 | * @param intf the interface to claim |
| 153 | * @param force true to disconnect kernel driver if necessary |
| 154 | * @return true if the interface was successfully claimed |
| 155 | */ |
| 156 | public boolean claimInterface(UsbInterface intf, boolean force) { |
| 157 | return native_claim_interface(intf.getId(), force); |
| 158 | } |
| 159 | |
| 160 | /** |
| 161 | * Releases exclusive access to a {@link android.hardware.usb.UsbInterface}. |
| 162 | * |
| 163 | * @return true if the interface was successfully released |
| 164 | */ |
| 165 | public boolean releaseInterface(UsbInterface intf) { |
| 166 | return native_release_interface(intf.getId()); |
| 167 | } |
| 168 | |
| 169 | /** |
Mike Lockwood | 7531aa2 | 2014-01-13 10:31:01 -0800 | [diff] [blame] | 170 | * Sets the current {@link android.hardware.usb.UsbInterface}. |
| 171 | * Used to select between two interfaces with the same ID but different alternate setting. |
| 172 | * |
Mike Lockwood | fa2b3fc | 2014-05-20 08:08:37 -0700 | [diff] [blame] | 173 | * @return true if the interface was successfully selected |
Mike Lockwood | 7531aa2 | 2014-01-13 10:31:01 -0800 | [diff] [blame] | 174 | */ |
| 175 | public boolean setInterface(UsbInterface intf) { |
| 176 | return native_set_interface(intf.getId(), intf.getAlternateSetting()); |
| 177 | } |
| 178 | |
| 179 | /** |
| 180 | * Sets the device's current {@link android.hardware.usb.UsbConfiguration}. |
| 181 | * |
| 182 | * @return true if the configuration was successfully set |
| 183 | */ |
| 184 | public boolean setConfiguration(UsbConfiguration configuration) { |
| 185 | return native_set_configuration(configuration.getId()); |
| 186 | } |
| 187 | |
| 188 | /** |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 189 | * Performs a control transaction on endpoint zero for this device. |
| 190 | * The direction of the transfer is determined by the request type. |
| 191 | * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is |
| 192 | * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write, |
| 193 | * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer |
| 194 | * is a read. |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 195 | * <p> |
| 196 | * This method transfers data starting from index 0 in the buffer. |
| 197 | * To specify a different offset, use |
| 198 | * {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}. |
| 199 | * </p> |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 200 | * |
| 201 | * @param requestType request type for this transaction |
| 202 | * @param request request ID for this transaction |
| 203 | * @param value value field for this transaction |
| 204 | * @param index index field for this transaction |
| 205 | * @param buffer buffer for data portion of transaction, |
| 206 | * or null if no data needs to be sent or received |
| 207 | * @param length the length of the data to send or receive |
| 208 | * @param timeout in milliseconds |
| 209 | * @return length of data transferred (or zero) for success, |
| 210 | * or negative value for failure |
| 211 | */ |
| 212 | public int controlTransfer(int requestType, int request, int value, |
| 213 | int index, byte[] buffer, int length, int timeout) { |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 214 | return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout); |
| 215 | } |
| 216 | |
| 217 | /** |
| 218 | * Performs a control transaction on endpoint zero for this device. |
| 219 | * The direction of the transfer is determined by the request type. |
| 220 | * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is |
| 221 | * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write, |
| 222 | * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer |
| 223 | * is a read. |
| 224 | * |
| 225 | * @param requestType request type for this transaction |
| 226 | * @param request request ID for this transaction |
| 227 | * @param value value field for this transaction |
| 228 | * @param index index field for this transaction |
| 229 | * @param buffer buffer for data portion of transaction, |
| 230 | * or null if no data needs to be sent or received |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 231 | * @param offset the index of the first byte in the buffer to send or receive |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 232 | * @param length the length of the data to send or receive |
| 233 | * @param timeout in milliseconds |
| 234 | * @return length of data transferred (or zero) for success, |
| 235 | * or negative value for failure |
| 236 | */ |
| 237 | public int controlTransfer(int requestType, int request, int value, int index, |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 238 | byte[] buffer, int offset, int length, int timeout) { |
| 239 | checkBounds(buffer, offset, length); |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 240 | return native_control_request(requestType, request, value, index, |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 241 | buffer, offset, length, timeout); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 242 | } |
| 243 | |
| 244 | /** |
| 245 | * Performs a bulk transaction on the given endpoint. |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 246 | * The direction of the transfer is determined by the direction of the endpoint. |
| 247 | * <p> |
| 248 | * This method transfers data starting from index 0 in the buffer. |
| 249 | * To specify a different offset, use |
| 250 | * {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}. |
| 251 | * </p> |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 252 | * |
| 253 | * @param endpoint the endpoint for this transaction |
Philip P. Moltmann | 5e040ae | 2016-09-20 14:09:20 -0700 | [diff] [blame] | 254 | * @param buffer buffer for data to send or receive; can be {@code null} to wait for next |
| 255 | * transaction without reading data |
Jerry Zhang | 910e9b0 | 2018-02-07 16:14:25 -0800 | [diff] [blame] | 256 | * @param length the length of the data to send or receive. Before |
| 257 | * {@value Build.VERSION_CODES#P}, a value larger than 16384 bytes |
| 258 | * would be truncated down to 16384. In API {@value Build.VERSION_CODES#P} |
| 259 | * and after, any value of length is valid. |
Philip P. Moltmann | 5e040ae | 2016-09-20 14:09:20 -0700 | [diff] [blame] | 260 | * @param timeout in milliseconds, 0 is infinite |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 261 | * @return length of data transferred (or zero) for success, |
| 262 | * or negative value for failure |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 263 | */ |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 264 | public int bulkTransfer(UsbEndpoint endpoint, |
| 265 | byte[] buffer, int length, int timeout) { |
| 266 | return bulkTransfer(endpoint, buffer, 0, length, timeout); |
| 267 | } |
| 268 | |
| 269 | /** |
| 270 | * Performs a bulk transaction on the given endpoint. |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 271 | * The direction of the transfer is determined by the direction of the endpoint. |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 272 | * |
| 273 | * @param endpoint the endpoint for this transaction |
| 274 | * @param buffer buffer for data to send or receive |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 275 | * @param offset the index of the first byte in the buffer to send or receive |
Jerry Zhang | 910e9b0 | 2018-02-07 16:14:25 -0800 | [diff] [blame] | 276 | * @param length the length of the data to send or receive. Before |
| 277 | * {@value Build.VERSION_CODES#P}, a value larger than 16384 bytes |
| 278 | * would be truncated down to 16384. In API {@value Build.VERSION_CODES#P} |
| 279 | * and after, any value of length is valid. |
Philip P. Moltmann | 5e040ae | 2016-09-20 14:09:20 -0700 | [diff] [blame] | 280 | * @param timeout in milliseconds, 0 is infinite |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 281 | * @return length of data transferred (or zero) for success, |
| 282 | * or negative value for failure |
| 283 | */ |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 284 | public int bulkTransfer(UsbEndpoint endpoint, |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 285 | byte[] buffer, int offset, int length, int timeout) { |
| 286 | checkBounds(buffer, offset, length); |
Jerry Zhang | 910e9b0 | 2018-02-07 16:14:25 -0800 | [diff] [blame] | 287 | if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P |
| 288 | && length > UsbRequest.MAX_USBFS_BUFFER_SIZE) { |
| 289 | length = UsbRequest.MAX_USBFS_BUFFER_SIZE; |
| 290 | } |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 291 | return native_bulk_request(endpoint.getAddress(), buffer, offset, length, timeout); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 292 | } |
| 293 | |
| 294 | /** |
Keun-young Park | badbbae | 2016-01-05 13:27:29 -0800 | [diff] [blame] | 295 | * Reset USB port for the connected device. |
| 296 | * |
| 297 | * @return true if reset succeeds. |
| 298 | * |
| 299 | * @hide |
| 300 | */ |
| 301 | @SystemApi |
Jeff Sharkey | 6f95ab2 | 2017-07-17 13:15:16 -0600 | [diff] [blame] | 302 | @SuppressLint("Doclava125") |
Keun-young Park | badbbae | 2016-01-05 13:27:29 -0800 | [diff] [blame] | 303 | public boolean resetDevice() { |
| 304 | return native_reset_device(); |
| 305 | } |
| 306 | |
| 307 | /** |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 308 | * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation |
Philip P. Moltmann | 5dd4e6c | 2016-09-23 15:31:23 -0700 | [diff] [blame] | 309 | * <p>Note that this may return requests queued on multiple |
| 310 | * {@link android.hardware.usb.UsbEndpoint}s. When multiple endpoints are in use, |
| 311 | * {@link android.hardware.usb.UsbRequest#getEndpoint} and {@link |
| 312 | * android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process |
| 313 | * the result of this function.</p> |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 314 | * |
| 315 | * @return a completed USB request, or null if an error occurred |
Philip P. Moltmann | 5dd4e6c | 2016-09-23 15:31:23 -0700 | [diff] [blame] | 316 | * |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 317 | * @throws IllegalArgumentException Before API {@value Build.VERSION_CODES#O}: if the number of |
| 318 | * bytes read or written is more than the limit of the |
| 319 | * request's buffer. The number of bytes is determined by the |
| 320 | * {@code length} parameter of |
Philip P. Moltmann | 5dd4e6c | 2016-09-23 15:31:23 -0700 | [diff] [blame] | 321 | * {@link UsbRequest#queue(ByteBuffer, int)} |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 322 | * @throws BufferOverflowException In API {@value Build.VERSION_CODES#O} and after: if the |
| 323 | * number of bytes read or written is more than the limit of the |
| 324 | * request's buffer. The number of bytes is determined by the |
| 325 | * {@code length} parameter of |
| 326 | * {@link UsbRequest#queue(ByteBuffer, int)} |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 327 | */ |
| 328 | public UsbRequest requestWait() { |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 329 | UsbRequest request = null; |
| 330 | try { |
| 331 | // -1 is special value indicating infinite wait |
| 332 | request = native_request_wait(-1); |
| 333 | } catch (TimeoutException e) { |
| 334 | // Does not happen, infinite timeout |
| 335 | } |
| 336 | |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 337 | if (request != null) { |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 338 | request.dequeue( |
| 339 | mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O); |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 340 | } |
| 341 | return request; |
| 342 | } |
| 343 | |
| 344 | /** |
| 345 | * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation |
| 346 | * <p>Note that this may return requests queued on multiple |
| 347 | * {@link android.hardware.usb.UsbEndpoint}s. When multiple endpoints are in use, |
| 348 | * {@link android.hardware.usb.UsbRequest#getEndpoint} and {@link |
| 349 | * android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process |
| 350 | * the result of this function.</p> |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 351 | * <p>Android processes {@link UsbRequest UsbRequests} asynchronously. Hence it is not |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 352 | * guaranteed that {@link #requestWait(long) requestWait(0)} returns a request that has been |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 353 | * queued right before even if the request could have been processed immediately.</p> |
| 354 | * |
| 355 | * @param timeout timeout in milliseconds. If 0 this method does not wait. |
| 356 | * |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 357 | * @return a completed USB request, or {@code null} if an error occurred |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 358 | * |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 359 | * @throws BufferOverflowException if the number of bytes read or written is more than the |
| 360 | * limit of the request's buffer. The number of bytes is |
| 361 | * determined by the {@code length} parameter of |
| 362 | * {@link UsbRequest#queue(ByteBuffer, int)} |
| 363 | * @throws TimeoutException if no request was received in {@code timeout} milliseconds. |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 364 | */ |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 365 | public UsbRequest requestWait(long timeout) throws TimeoutException { |
Philip P. Moltmann | 08b678c | 2016-10-18 17:43:37 -0700 | [diff] [blame] | 366 | timeout = Preconditions.checkArgumentNonnegative(timeout, "timeout"); |
Philip P. Moltmann | 927fefe | 2016-10-18 12:57:34 -0700 | [diff] [blame] | 367 | |
| 368 | UsbRequest request = native_request_wait(timeout); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 369 | if (request != null) { |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 370 | request.dequeue(true); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 371 | } |
| 372 | return request; |
| 373 | } |
| 374 | |
| 375 | /** |
| 376 | * Returns the serial number for the device. |
| 377 | * This will return null if the device has not been opened. |
| 378 | * |
| 379 | * @return the device serial number |
| 380 | */ |
| 381 | public String getSerial() { |
| 382 | return native_get_serial(); |
| 383 | } |
| 384 | |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 385 | private static void checkBounds(byte[] buffer, int start, int length) { |
| 386 | final int bufferLength = (buffer != null ? buffer.length : 0); |
Philip P. Moltmann | 5e040ae | 2016-09-20 14:09:20 -0700 | [diff] [blame] | 387 | if (length < 0 || start < 0 || start + length > bufferLength) { |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 388 | throw new IllegalArgumentException("Buffer start or length out of bounds."); |
| 389 | } |
| 390 | } |
| 391 | |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 392 | @Override |
| 393 | protected void finalize() throws Throwable { |
| 394 | try { |
Narayan Kamath | 492e9e8 | 2017-03-22 14:28:08 +0000 | [diff] [blame] | 395 | if (mCloseGuard != null) { |
| 396 | mCloseGuard.warnIfOpen(); |
| 397 | } |
Philip P. Moltmann | 674e8c3 | 2016-08-29 12:28:31 -0700 | [diff] [blame] | 398 | } finally { |
| 399 | super.finalize(); |
| 400 | } |
| 401 | } |
| 402 | |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 403 | private native boolean native_open(String deviceName, FileDescriptor pfd); |
| 404 | private native void native_close(); |
| 405 | private native int native_get_fd(); |
Mike Lockwood | a88b42d | 2011-05-19 11:52:40 -0400 | [diff] [blame] | 406 | private native byte[] native_get_desc(); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 407 | private native boolean native_claim_interface(int interfaceID, boolean force); |
| 408 | private native boolean native_release_interface(int interfaceID); |
Mike Lockwood | 7531aa2 | 2014-01-13 10:31:01 -0800 | [diff] [blame] | 409 | private native boolean native_set_interface(int interfaceID, int alternateSetting); |
| 410 | private native boolean native_set_configuration(int configurationID); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 411 | private native int native_control_request(int requestType, int request, int value, |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 412 | int index, byte[] buffer, int offset, int length, int timeout); |
Jeff Brown | 6c81a93 | 2013-03-28 03:13:09 -0700 | [diff] [blame] | 413 | private native int native_bulk_request(int endpoint, byte[] buffer, |
Jeff Brown | e783d99 | 2013-04-18 19:15:17 -0700 | [diff] [blame] | 414 | int offset, int length, int timeout); |
Philip P. Moltmann | 9b6dd2b | 2017-04-06 15:34:04 -0700 | [diff] [blame] | 415 | private native UsbRequest native_request_wait(long timeout) throws TimeoutException; |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 416 | private native String native_get_serial(); |
Keun-young Park | badbbae | 2016-01-05 13:27:29 -0800 | [diff] [blame] | 417 | private native boolean native_reset_device(); |
Mike Lockwood | acc29cc | 2011-03-11 08:18:08 -0500 | [diff] [blame] | 418 | } |