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    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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
198    public UsbConfiguration getConfiguration(int index) {
199        return (UsbConfiguration)mConfigurations[index];
200    }
201
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     */
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     */
243    public UsbInterface getInterface(int index) {
244        return getInterfaceList()[index];
245    }
246
247    /**
248     * Only used by UsbService implementation
249     * @hide
250     */
251    public void setConfigurations(Parcelable[] configuration) {
252        mConfigurations = configuration;
253    }
254
255    @Override
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
267    public int hashCode() {
268        return mName.hashCode();
269    }
270
271    @Override
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
311    public int describeContents() {
312        return 0;
313    }
314
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
329    public static int getDeviceId(String name) {
330        return native_get_device_id(name);
331    }
332
333    public static String getDeviceName(int id) {
334        return native_get_device_name(id);
335    }
336
337    private static native int native_get_device_id(String name);
338    private static native String native_get_device_name(int id);
339}
340