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