Home | History | Annotate | Download | only in usb
      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