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 17 package android.hardware.usb; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import com.android.internal.util.Preconditions; 24 25 /** 26 * This class represents a USB device attached to the android device with the android device 27 * acting as the USB host. 28 * Each device contains one or more {@link UsbInterface}s, each of which contains a number of 29 * {@link UsbEndpoint}s (the channels via which data is transmitted over USB). 30 * 31 * <p> This class contains information (along with {@link UsbInterface} and {@link UsbEndpoint}) 32 * that describes the capabilities of the USB device. 33 * To communicate with the device, you open a {@link UsbDeviceConnection} for the device 34 * and use {@link UsbRequest} to send and receive data on an endpoint. 35 * {@link UsbDeviceConnection#controlTransfer} is used for control requests on endpoint zero. 36 * 37 * <div class="special reference"> 38 * <h3>Developer Guides</h3> 39 * <p>For more information about communicating with USB hardware, read the 40 * <a href="{@docRoot}guide/topics/connectivity/usb/index.html">USB</a> developer guide.</p> 41 * </div> 42 */ 43 public class UsbDevice implements Parcelable { 44 45 private static final String TAG = "UsbDevice"; 46 private static final boolean DEBUG = false; 47 48 private final @NonNull String mName; 49 private final @Nullable String mManufacturerName; 50 private final @Nullable String mProductName; 51 private final @NonNull String mVersion; 52 private final @Nullable String mSerialNumber; 53 private final int mVendorId; 54 private final int mProductId; 55 private final int mClass; 56 private final int mSubclass; 57 private final int mProtocol; 58 59 /** All configurations for this device, only null during creation */ 60 private @Nullable Parcelable[] mConfigurations; 61 62 /** All interfaces on the device. Initialized on first call to getInterfaceList */ 63 private @Nullable UsbInterface[] mInterfaces; 64 65 /** 66 * UsbDevice should only be instantiated by UsbService implementation 67 * @hide 68 */ UsbDevice(@onNull String name, int vendorId, int productId, int Class, int subClass, int protocol, @Nullable String manufacturerName, @Nullable String productName, @NonNull String version, @Nullable String serialNumber)69 public UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass, 70 int protocol, @Nullable String manufacturerName, @Nullable String productName, 71 @NonNull String version, @Nullable String serialNumber) { 72 mName = Preconditions.checkNotNull(name); 73 mVendorId = vendorId; 74 mProductId = productId; 75 mClass = Class; 76 mSubclass = subClass; 77 mProtocol = protocol; 78 mManufacturerName = manufacturerName; 79 mProductName = productName; 80 mVersion = Preconditions.checkStringNotEmpty(version); 81 mSerialNumber = serialNumber; 82 } 83 84 /** 85 * Returns the name of the device. 86 * In the standard implementation, this is the path of the device file 87 * for the device in the usbfs file system. 88 * 89 * @return the device name 90 */ getDeviceName()91 public @NonNull String getDeviceName() { 92 return mName; 93 } 94 95 /** 96 * Returns the manufacturer name of the device. 97 * 98 * @return the manufacturer name, or {@code null} if the property could not be read 99 */ getManufacturerName()100 public @Nullable String getManufacturerName() { 101 return mManufacturerName; 102 } 103 104 /** 105 * Returns the product name of the device. 106 * 107 * @return the product name, or {@code null} if the property could not be read 108 */ getProductName()109 public @Nullable String getProductName() { 110 return mProductName; 111 } 112 113 /** 114 * Returns the version number of the device. 115 * 116 * @return the device version 117 */ getVersion()118 public @NonNull String getVersion() { 119 return mVersion; 120 } 121 122 /** 123 * Returns the serial number of the device. 124 * 125 * @return the serial number name, or {@code null} if the property could not be read 126 */ getSerialNumber()127 public @Nullable String getSerialNumber() { 128 return mSerialNumber; 129 } 130 131 /** 132 * Returns a unique integer ID for the device. 133 * This is a convenience for clients that want to use an integer to represent 134 * the device, rather than the device name. 135 * IDs are not persistent across USB disconnects. 136 * 137 * @return the device ID 138 */ getDeviceId()139 public int getDeviceId() { 140 return getDeviceId(mName); 141 } 142 143 /** 144 * Returns a vendor ID for the device. 145 * 146 * @return the device vendor ID 147 */ getVendorId()148 public int getVendorId() { 149 return mVendorId; 150 } 151 152 /** 153 * Returns a product ID for the device. 154 * 155 * @return the device product ID 156 */ getProductId()157 public int getProductId() { 158 return mProductId; 159 } 160 161 /** 162 * Returns the devices's class field. 163 * Some useful constants for USB device classes can be found in {@link UsbConstants}. 164 * 165 * @return the devices's class 166 */ getDeviceClass()167 public int getDeviceClass() { 168 return mClass; 169 } 170 171 /** 172 * Returns the device's subclass field. 173 * 174 * @return the device's subclass 175 */ getDeviceSubclass()176 public int getDeviceSubclass() { 177 return mSubclass; 178 } 179 180 /** 181 * Returns the device's protocol field. 182 * 183 * @return the device's protocol 184 */ getDeviceProtocol()185 public int getDeviceProtocol() { 186 return mProtocol; 187 } 188 189 /** 190 * Returns the number of {@link UsbConfiguration}s this device contains. 191 * 192 * @return the number of configurations 193 */ getConfigurationCount()194 public int getConfigurationCount() { 195 return mConfigurations.length; 196 } 197 198 /** 199 * Returns the {@link UsbConfiguration} at the given index. 200 * 201 * @return the configuration 202 */ getConfiguration(int index)203 public @NonNull UsbConfiguration getConfiguration(int index) { 204 return (UsbConfiguration)mConfigurations[index]; 205 } 206 getInterfaceList()207 private @Nullable UsbInterface[] getInterfaceList() { 208 if (mInterfaces == null) { 209 int configurationCount = mConfigurations.length; 210 int interfaceCount = 0; 211 for (int i = 0; i < configurationCount; i++) { 212 UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i]; 213 interfaceCount += configuration.getInterfaceCount(); 214 } 215 216 mInterfaces = new UsbInterface[interfaceCount]; 217 int offset = 0; 218 for (int i = 0; i < configurationCount; i++) { 219 UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i]; 220 interfaceCount = configuration.getInterfaceCount(); 221 for (int j = 0; j < interfaceCount; j++) { 222 mInterfaces[offset++] = configuration.getInterface(j); 223 } 224 } 225 } 226 227 return mInterfaces; 228 } 229 230 /** 231 * Returns the number of {@link UsbInterface}s this device contains. 232 * For devices with multiple configurations, you will probably want to use 233 * {@link UsbConfiguration#getInterfaceCount} instead. 234 * 235 * @return the number of interfaces 236 */ getInterfaceCount()237 public int getInterfaceCount() { 238 return getInterfaceList().length; 239 } 240 241 /** 242 * Returns the {@link UsbInterface} at the given index. 243 * For devices with multiple configurations, you will probably want to use 244 * {@link UsbConfiguration#getInterface} instead. 245 * 246 * @return the interface 247 */ getInterface(int index)248 public @NonNull UsbInterface getInterface(int index) { 249 return getInterfaceList()[index]; 250 } 251 252 /** 253 * Only used by UsbService implementation 254 * @hide 255 */ setConfigurations(@onNull Parcelable[] configuration)256 public void setConfigurations(@NonNull Parcelable[] configuration) { 257 mConfigurations = Preconditions.checkArrayElementsNotNull(configuration, "configuration"); 258 } 259 260 @Override equals(Object o)261 public boolean equals(Object o) { 262 if (o instanceof UsbDevice) { 263 return ((UsbDevice)o).mName.equals(mName); 264 } else if (o instanceof String) { 265 return ((String)o).equals(mName); 266 } else { 267 return false; 268 } 269 } 270 271 @Override hashCode()272 public int hashCode() { 273 return mName.hashCode(); 274 } 275 276 @Override toString()277 public String toString() { 278 StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName + 279 ",mVendorId=" + mVendorId + ",mProductId=" + mProductId + 280 ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol + 281 ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName + 282 ",mVersion=" + mVersion + ",mSerialNumber=" + mSerialNumber + ",mConfigurations=["); 283 for (int i = 0; i < mConfigurations.length; i++) { 284 builder.append("\n"); 285 builder.append(mConfigurations[i].toString()); 286 } 287 builder.append("]"); 288 return builder.toString(); 289 } 290 291 public static final Parcelable.Creator<UsbDevice> CREATOR = 292 new Parcelable.Creator<UsbDevice>() { 293 public UsbDevice createFromParcel(Parcel in) { 294 String name = in.readString(); 295 int vendorId = in.readInt(); 296 int productId = in.readInt(); 297 int clasz = in.readInt(); 298 int subClass = in.readInt(); 299 int protocol = in.readInt(); 300 String manufacturerName = in.readString(); 301 String productName = in.readString(); 302 String version = in.readString(); 303 String serialNumber = in.readString(); 304 Parcelable[] configurations = in.readParcelableArray(UsbInterface.class.getClassLoader()); 305 UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol, 306 manufacturerName, productName, version, serialNumber); 307 device.setConfigurations(configurations); 308 return device; 309 } 310 311 public UsbDevice[] newArray(int size) { 312 return new UsbDevice[size]; 313 } 314 }; 315 describeContents()316 public int describeContents() { 317 return 0; 318 } 319 writeToParcel(Parcel parcel, int flags)320 public void writeToParcel(Parcel parcel, int flags) { 321 parcel.writeString(mName); 322 parcel.writeInt(mVendorId); 323 parcel.writeInt(mProductId); 324 parcel.writeInt(mClass); 325 parcel.writeInt(mSubclass); 326 parcel.writeInt(mProtocol); 327 parcel.writeString(mManufacturerName); 328 parcel.writeString(mProductName); 329 parcel.writeString(mVersion); 330 parcel.writeString(mSerialNumber); 331 parcel.writeParcelableArray(mConfigurations, 0); 332 } 333 getDeviceId(String name)334 public static int getDeviceId(String name) { 335 return native_get_device_id(name); 336 } 337 getDeviceName(int id)338 public static String getDeviceName(int id) { 339 return native_get_device_name(id); 340 } 341 native_get_device_id(String name)342 private static native int native_get_device_id(String name); native_get_device_name(int id)343 private static native String native_get_device_name(int id); 344 } 345