• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
UsbManager(Context context, IUsbManager service)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      */
getAccessoryList()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      */
openAccessory(UsbAccessory accessory)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      */
hasPermission(UsbAccessory accessory)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      */
requestPermission(UsbAccessory accessory, PendingIntent pi)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 
getFunctionEnableFile(String function)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      */
isFunctionSupported(String function)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      */
isFunctionEnabled(String function)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      */
setFunctionEnabled(String function, boolean enable)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