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 18 package android.hardware.usb; 19 20 import android.app.PendingIntent; 21 import android.content.Context; 22 import android.os.Bundle; 23 import android.os.ParcelFileDescriptor; 24 import android.os.RemoteException; 25 import android.util.Log; 26 27 import java.io.File; 28 import java.io.FileInputStream; 29 import java.io.FileOutputStream; 30 import java.io.IOException; 31 import java.util.HashMap; 32 33 /** 34 * This class allows you to access the state of USB. 35 * 36 * <p>You can obtain an instance of this class by calling 37 * {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. 38 * 39 * {@samplecode 40 * UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); 41 * } 42 * @hide 43 */ 44 public class UsbManager { 45 private static final String TAG = "UsbManager"; 46 47 /** 48 * Broadcast Action: A sticky broadcast for USB state change events when in device mode. 49 * 50 * This is a sticky broadcast for clients that includes USB connected/disconnected state, 51 * <ul> 52 * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected. 53 * <li> {@link #USB_CONFIGURATION} a Bundle containing name/value pairs where the name 54 * is the name of a USB function and the value is either {@link #USB_FUNCTION_ENABLED} 55 * or {@link #USB_FUNCTION_DISABLED}. The possible function names include 56 * {@link #USB_FUNCTION_MASS_STORAGE}, {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS}, 57 * {@link #USB_FUNCTION_MTP} and {@link #USB_FUNCTION_ACCESSORY}. 58 * </ul> 59 */ 60 public static final String ACTION_USB_STATE = 61 "android.hardware.usb.action.USB_STATE"; 62 63 /** 64 * Broadcast Action: A broadcast for USB accessory attached event. 65 * 66 * This intent is sent when a USB accessory is attached. 67 * <ul> 68 * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory} 69 * for the attached accessory 70 * </ul> 71 */ 72 public static final String ACTION_USB_ACCESSORY_ATTACHED = 73 "android.hardware.usb.action.USB_ACCESSORY_ATTACHED"; 74 75 /** 76 * Broadcast Action: A broadcast for USB accessory detached event. 77 * 78 * This intent is sent when a USB accessory is detached. 79 * <ul> 80 * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory} 81 * for the attached accessory that was detached 82 * </ul> 83 */ 84 public static final String ACTION_USB_ACCESSORY_DETACHED = 85 "android.hardware.usb.action.USB_ACCESSORY_DETACHED"; 86 87 /** 88 * Boolean extra indicating whether USB is connected or disconnected. 89 * Used in extras for the {@link #ACTION_USB_STATE} broadcast. 90 */ 91 public static final String USB_CONNECTED = "connected"; 92 93 /** 94 * Integer extra containing currently set USB configuration. 95 * Used in extras for the {@link #ACTION_USB_STATE} broadcast. 96 */ 97 public static final String USB_CONFIGURATION = "configuration"; 98 99 /** 100 * Name of the USB mass storage USB function. 101 * Used in extras for the {@link #ACTION_USB_STATE} broadcast 102 */ 103 public static final String USB_FUNCTION_MASS_STORAGE = "mass_storage"; 104 105 /** 106 * Name of the adb USB function. 107 * Used in extras for the {@link #ACTION_USB_STATE} broadcast 108 */ 109 public static final String USB_FUNCTION_ADB = "adb"; 110 111 /** 112 * Name of the RNDIS ethernet USB function. 113 * Used in extras for the {@link #ACTION_USB_STATE} broadcast 114 */ 115 public static final String USB_FUNCTION_RNDIS = "rndis"; 116 117 /** 118 * Name of the MTP USB function. 119 * Used in extras for the {@link #ACTION_USB_STATE} broadcast 120 */ 121 public static final String USB_FUNCTION_MTP = "mtp"; 122 123 /** 124 * Name of the Accessory USB function. 125 * Used in extras for the {@link #ACTION_USB_STATE} broadcast 126 */ 127 public static final String USB_FUNCTION_ACCESSORY = "accessory"; 128 129 /** 130 * Value indicating that a USB function is enabled. 131 * Used in {@link #USB_CONFIGURATION} extras bundle for the 132 * {@link #ACTION_USB_STATE} broadcast 133 */ 134 public static final String USB_FUNCTION_ENABLED = "enabled"; 135 136 /** 137 * Value indicating that a USB function is disabled. 138 * Used in {@link #USB_CONFIGURATION} extras bundle for the 139 * {@link #ACTION_USB_STATE} broadcast 140 */ 141 public static final String USB_FUNCTION_DISABLED = "disabled"; 142 143 /** 144 * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and 145 * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts 146 * containing the UsbAccessory object for the accessory. 147 */ 148 public static final String EXTRA_ACCESSORY = "accessory"; 149 150 /** 151 * Name of extra added to the {@link android.app.PendingIntent} 152 * passed into {@link #requestPermission(UsbDevice, PendingIntent)} 153 * or {@link #requestPermission(UsbAccessory, PendingIntent)} 154 * containing a boolean value indicating whether the user granted permission or not. 155 */ 156 public static final String EXTRA_PERMISSION_GRANTED = "permission"; 157 158 private final Context mContext; 159 private final IUsbManager mService; 160 161 /** 162 * {@hide} 163 */ 164 public UsbManager(Context context, IUsbManager service) { 165 mContext = context; 166 mService = service; 167 } 168 169 /** 170 * Returns a list of currently attached USB accessories. 171 * (in the current implementation there can be at most one) 172 * 173 * @return list of USB accessories, or null if none are attached. 174 */ 175 public UsbAccessory[] getAccessoryList() { 176 try { 177 UsbAccessory accessory = mService.getCurrentAccessory(); 178 if (accessory == null) { 179 return null; 180 } else { 181 return new UsbAccessory[] { accessory }; 182 } 183 } catch (RemoteException e) { 184 Log.e(TAG, "RemoteException in getAccessoryList", e); 185 return null; 186 } 187 } 188 189 /** 190 * Opens a file descriptor for reading and writing data to the USB accessory. 191 * 192 * @param accessory the USB accessory to open 193 * @return file descriptor, or null if the accessor could not be opened. 194 */ 195 public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { 196 try { 197 return mService.openAccessory(accessory); 198 } catch (RemoteException e) { 199 Log.e(TAG, "RemoteException in openAccessory", e); 200 return null; 201 } 202 } 203 204 /** 205 * Returns true if the caller has permission to access the accessory. 206 * Permission might have been granted temporarily via 207 * {@link #requestPermission(UsbAccessory, PendingIntent)} or 208 * by the user choosing the caller as the default application for the accessory. 209 * 210 * @param accessory to check permissions for 211 * @return true if caller has permission 212 */ 213 public boolean hasPermission(UsbAccessory accessory) { 214 try { 215 return mService.hasAccessoryPermission(accessory); 216 } catch (RemoteException e) { 217 Log.e(TAG, "RemoteException in hasPermission", e); 218 return false; 219 } 220 } 221 222 /** 223 * Requests temporary permission for the given package to access the accessory. 224 * This may result in a system dialog being displayed to the user 225 * if permission had not already been granted. 226 * Success or failure is returned via the {@link android.app.PendingIntent} pi. 227 * If successful, this grants the caller permission to access the accessory only 228 * until the device is disconnected. 229 * 230 * The following extras will be added to pi: 231 * <ul> 232 * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call 233 * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether 234 * permission was granted by the user 235 * </ul> 236 * 237 * @param accessory to request permissions for 238 * @param pi PendingIntent for returning result 239 */ 240 public void requestPermission(UsbAccessory accessory, PendingIntent pi) { 241 try { 242 mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi); 243 } catch (RemoteException e) { 244 Log.e(TAG, "RemoteException in requestPermission", e); 245 } 246 } 247 248 private static File getFunctionEnableFile(String function) { 249 return new File("/sys/class/usb_composite/" + function + "/enable"); 250 } 251 252 /** 253 * Returns true if the specified USB function is supported by the kernel. 254 * Note that a USB function maybe supported but disabled. 255 * 256 * @param function name of the USB function 257 * @return true if the USB function is supported. 258 */ 259 public static boolean isFunctionSupported(String function) { 260 return getFunctionEnableFile(function).exists(); 261 } 262 263 /** 264 * Returns true if the specified USB function is currently enabled. 265 * 266 * @param function name of the USB function 267 * @return true if the USB function is enabled. 268 */ 269 public static boolean isFunctionEnabled(String function) { 270 try { 271 FileInputStream stream = new FileInputStream(getFunctionEnableFile(function)); 272 boolean enabled = (stream.read() == '1'); 273 stream.close(); 274 return enabled; 275 } catch (IOException e) { 276 return false; 277 } 278 } 279 280 /** 281 * Enables or disables a USB function. 282 * 283 * @hide 284 */ 285 public static boolean setFunctionEnabled(String function, boolean enable) { 286 try { 287 FileOutputStream stream = new FileOutputStream(getFunctionEnableFile(function)); 288 stream.write(enable ? '1' : '0'); 289 stream.close(); 290 return true; 291 } catch (IOException e) { 292 return false; 293 } 294 } 295 } 296