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