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 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.ActivityThread; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.os.RemoteException; 25 26 import com.android.internal.util.Preconditions; 27 28 import java.util.Objects; 29 30 /** 31 * A class representing a USB accessory, which is an external hardware component 32 * that communicates with an android application over USB. 33 * The accessory is the USB host and android the device side of the USB connection. 34 * 35 * <p>When the accessory connects, it reports its manufacturer and model names, 36 * the version of the accessory, and a user visible description of the accessory to the device. 37 * The manufacturer, model and version strings are used by the USB Manager to choose 38 * an appropriate application for the accessory. 39 * The accessory may optionally provide a unique serial number 40 * and a URL to for the accessory's website to the device as well. 41 * 42 * <p>An instance of this class is sent to the application via the 43 * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} Intent. 44 * The application can then call {@link UsbManager#openAccessory} to open a file descriptor 45 * for reading and writing data to and from the accessory. 46 * 47 * <div class="special reference"> 48 * <h3>Developer Guides</h3> 49 * <p>For more information about communicating with USB hardware, read the 50 * <a href="{@docRoot}guide/topics/usb/index.html">USB</a> developer guide.</p> 51 * </div> 52 */ 53 public class UsbAccessory implements Parcelable { 54 55 private static final String TAG = "UsbAccessory"; 56 57 private final @NonNull String mManufacturer; 58 private final @NonNull String mModel; 59 private final @Nullable String mDescription; 60 private final @Nullable String mVersion; 61 private final @Nullable String mUri; 62 private final @NonNull IUsbSerialReader mSerialNumberReader; 63 64 /** @hide */ 65 public static final int MANUFACTURER_STRING = 0; 66 /** @hide */ 67 public static final int MODEL_STRING = 1; 68 /** @hide */ 69 public static final int DESCRIPTION_STRING = 2; 70 /** @hide */ 71 public static final int VERSION_STRING = 3; 72 /** @hide */ 73 public static final int URI_STRING = 4; 74 /** @hide */ 75 public static final int SERIAL_STRING = 5; 76 77 /** 78 * UsbAccessory should only be instantiated by UsbService implementation 79 * @hide 80 */ UsbAccessory(@onNull String manufacturer, @NonNull String model, @Nullable String description, @Nullable String version, @Nullable String uri, @NonNull IUsbSerialReader serialNumberReader)81 public UsbAccessory(@NonNull String manufacturer, @NonNull String model, 82 @Nullable String description, @Nullable String version, @Nullable String uri, 83 @NonNull IUsbSerialReader serialNumberReader) { 84 mManufacturer = Objects.requireNonNull(manufacturer); 85 mModel = Objects.requireNonNull(model); 86 mDescription = description; 87 mVersion = version; 88 mUri = uri; 89 mSerialNumberReader = serialNumberReader; 90 91 // Make sure the binder belongs to the system 92 if (ActivityThread.isSystem()) { 93 Preconditions.checkArgument(mSerialNumberReader instanceof IUsbSerialReader.Stub); 94 } 95 } 96 97 /** 98 * DO NOT USE. Only for backwards compatibility with 99 * {@link com.android.future.usb.UsbAccessory}. 100 * 101 * @hide 102 * @deprecated use {@link UsbAccessory#UsbAccessory(String, String, String, String, String, 103 * IUsbSerialReader) instead} 104 */ 105 @Deprecated UsbAccessory(@onNull String manufacturer, @NonNull String model, @Nullable String description, @Nullable String version, @Nullable String uri, @Nullable String serialNumber)106 public UsbAccessory(@NonNull String manufacturer, @NonNull String model, 107 @Nullable String description, @Nullable String version, @Nullable String uri, 108 @Nullable String serialNumber) { 109 this(manufacturer, model, description, version, uri, new IUsbSerialReader.Stub() { 110 @Override 111 public String getSerial(String packageName) { 112 return serialNumber; 113 } 114 }); 115 } 116 117 /** 118 * Returns the manufacturer name of the accessory. 119 * 120 * @return the accessory manufacturer 121 */ getManufacturer()122 public @NonNull String getManufacturer() { 123 return mManufacturer; 124 } 125 126 /** 127 * Returns the model name of the accessory. 128 * 129 * @return the accessory model 130 */ getModel()131 public @NonNull String getModel() { 132 return mModel; 133 } 134 135 /** 136 * Returns a user visible description of the accessory. 137 * 138 * @return the accessory description, or {@code null} if not set 139 */ getDescription()140 public @Nullable String getDescription() { 141 return mDescription; 142 } 143 144 /** 145 * Returns the version of the accessory. 146 * 147 * @return the accessory version, or {@code null} if not set 148 */ getVersion()149 public @Nullable String getVersion() { 150 return mVersion; 151 } 152 153 /** 154 * Returns the URI for the accessory. 155 * This is an optional URI that might show information about the accessory 156 * or provide the option to download an application for the accessory 157 * 158 * @return the accessory URI, or {@code null} if not set 159 */ getUri()160 public @Nullable String getUri() { 161 return mUri; 162 } 163 164 /** 165 * Returns the unique serial number for the accessory. 166 * This is an optional serial number that can be used to differentiate 167 * between individual accessories of the same model and manufacturer 168 * 169 * @return the unique serial number, or {@code null} if not set 170 * 171 * @throws SecurityException if the app targets SDK >= {@value android.os.Build.VERSION_CODES#Q} 172 * and the app does not have permission to read from the accessory. 173 */ getSerial()174 public @Nullable String getSerial() { 175 try { 176 return mSerialNumberReader.getSerial(ActivityThread.currentPackageName()); 177 } catch (RemoteException e) { 178 e.rethrowFromSystemServer(); 179 return null; 180 } 181 } 182 compare(String s1, String s2)183 private static boolean compare(String s1, String s2) { 184 if (s1 == null) return (s2 == null); 185 return s1.equals(s2); 186 } 187 188 @Override equals(@ullable Object obj)189 public boolean equals(@Nullable Object obj) { 190 if (obj instanceof UsbAccessory) { 191 UsbAccessory accessory = (UsbAccessory)obj; 192 return (compare(mManufacturer, accessory.getManufacturer()) && 193 compare(mModel, accessory.getModel()) && 194 compare(mDescription, accessory.getDescription()) && 195 compare(mVersion, accessory.getVersion()) && 196 compare(mUri, accessory.getUri()) && 197 compare(getSerial(), accessory.getSerial())); 198 } 199 return false; 200 } 201 202 @Override hashCode()203 public int hashCode() { 204 return mManufacturer.hashCode() ^ mModel.hashCode() ^ 205 (mDescription == null ? 0 : mDescription.hashCode()) ^ 206 (mVersion == null ? 0 : mVersion.hashCode()) ^ 207 (mUri == null ? 0 : mUri.hashCode()); 208 } 209 210 @Override toString()211 public String toString() { 212 return "UsbAccessory[mManufacturer=" + mManufacturer + 213 ", mModel=" + mModel + 214 ", mDescription=" + mDescription + 215 ", mVersion=" + mVersion + 216 ", mUri=" + mUri + 217 ", mSerialNumberReader=" + mSerialNumberReader + "]"; 218 } 219 220 public static final @android.annotation.NonNull Parcelable.Creator<UsbAccessory> CREATOR = 221 new Parcelable.Creator<UsbAccessory>() { 222 public UsbAccessory createFromParcel(Parcel in) { 223 String manufacturer = in.readString(); 224 String model = in.readString(); 225 String description = in.readString(); 226 String version = in.readString(); 227 String uri = in.readString(); 228 IUsbSerialReader serialNumberReader = IUsbSerialReader.Stub.asInterface( 229 in.readStrongBinder()); 230 231 return new UsbAccessory(manufacturer, model, description, version, uri, 232 serialNumberReader); 233 } 234 235 public UsbAccessory[] newArray(int size) { 236 return new UsbAccessory[size]; 237 } 238 }; 239 describeContents()240 public int describeContents() { 241 return 0; 242 } 243 writeToParcel(Parcel parcel, int flags)244 public void writeToParcel(Parcel parcel, int flags) { 245 parcel.writeString(mManufacturer); 246 parcel.writeString(mModel); 247 parcel.writeString(mDescription); 248 parcel.writeString(mVersion); 249 parcel.writeString(mUri); 250 parcel.writeStrongBinder(mSerialNumberReader.asBinder()); 251 } 252 } 253