blob: d73d3d8b04cf813b1ccf7e836ad12e806f936100 [file] [log] [blame]
Mike Lockwood24236072010-06-23 17:36:36 -04001/*
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
Mike Lockwoodc4308f02011-03-01 08:04:54 -080018package android.hardware.usb;
Mike Lockwood24236072010-06-23 17:36:36 -040019
Keun-young Parkbadbbae2016-01-05 13:27:29 -080020import android.annotation.Nullable;
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -060021import android.annotation.SdkConstant;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060022import android.annotation.SystemService;
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -060023import android.annotation.SdkConstant.SdkConstantType;
Mike Lockwood3a68b832011-03-08 10:08:59 -050024import android.app.PendingIntent;
Keun-young Parkbadbbae2016-01-05 13:27:29 -080025import android.content.ComponentName;
Mike Lockwood3a68b832011-03-08 10:08:59 -050026import android.content.Context;
Johan T. Halseth244259a2016-05-24 14:49:04 +010027import android.content.pm.PackageManager.NameNotFoundException;
Mike Lockwoode7d511e2010-12-30 13:39:37 -050028import android.os.Bundle;
29import android.os.ParcelFileDescriptor;
Daichi Hirono47518802015-12-08 09:51:19 +090030import android.os.Process;
Mike Lockwoode7d511e2010-12-30 13:39:37 -050031import android.os.RemoteException;
32import android.util.Log;
33
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -060034import com.android.internal.util.Preconditions;
35
Mike Lockwoode7d511e2010-12-30 13:39:37 -050036import java.util.HashMap;
Mike Lockwood08bff3b2010-08-31 13:27:05 -040037
Mike Lockwood24236072010-06-23 17:36:36 -040038/**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -040039 * This class allows you to access the state of USB and communicate with USB devices.
40 * Currently only host mode is supported in the public API.
Mike Lockwoode7d511e2010-12-30 13:39:37 -050041 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080042 * <div class="special reference">
43 * <h3>Developer Guides</h3>
44 * <p>For more information about communicating with USB hardware, read the
Mark Lu8b739902016-06-24 15:38:02 -070045 * <a href="{@docRoot}guide/topics/connectivity/usb/index.html">USB developer guide</a>.</p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080046 * </div>
Mike Lockwood24236072010-06-23 17:36:36 -040047 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060048@SystemService(Context.USB_SERVICE)
Mike Lockwood770126a2010-12-09 22:30:37 -080049public class UsbManager {
Mike Lockwoode7d511e2010-12-30 13:39:37 -050050 private static final String TAG = "UsbManager";
51
Mike Lockwood24236072010-06-23 17:36:36 -040052 /**
Mike Lockwoode7d511e2010-12-30 13:39:37 -050053 * Broadcast Action: A sticky broadcast for USB state change events when in device mode.
Mike Lockwood709981e2010-06-28 09:58:58 -040054 *
Mike Lockwoodb92df0f2010-12-10 16:19:32 -080055 * This is a sticky broadcast for clients that includes USB connected/disconnected state,
Mike Lockwood9182d3c2011-02-15 09:50:22 -050056 * <ul>
57 * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
Daichi Hirono618fa6f2016-03-17 14:14:32 +090058 * <li> {@link #USB_HOST_CONNECTED} boolean indicating whether USB is connected or
59 * disconnected as host.
Mike Lockwood02e45692011-06-14 15:43:51 -040060 * <li> {@link #USB_CONFIGURED} boolean indicating whether USB is configured.
Mike Lockwood9eb014a2011-06-08 09:17:45 -070061 * currently zero if not configured, one for configured.
Mike Lockwood9eb014a2011-06-08 09:17:45 -070062 * <li> {@link #USB_FUNCTION_ADB} boolean extra indicating whether the
63 * adb function is enabled
64 * <li> {@link #USB_FUNCTION_RNDIS} boolean extra indicating whether the
65 * RNDIS ethernet function is enabled
66 * <li> {@link #USB_FUNCTION_MTP} boolean extra indicating whether the
67 * MTP function is enabled
68 * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
69 * PTP function is enabled
70 * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
71 * accessory function is enabled
Mike Lockwood9d5a4be2012-04-06 09:41:32 -070072 * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
73 * audio source function is enabled
Mike Lockwood2a57bc72014-09-19 11:16:52 -070074 * <li> {@link #USB_FUNCTION_MIDI} boolean extra indicating whether the
75 * MIDI function is enabled
Mike Lockwood9182d3c2011-02-15 09:50:22 -050076 * </ul>
Yasuhiro Matsuda48b9a7c2015-07-16 19:00:16 +090077 * If the sticky intent has not been found, that indicates USB is disconnected,
78 * USB is not configued, MTP function is enabled, and all the other functions are disabled.
Mike Lockwooda75075e12011-03-11 11:26:11 -050079 *
80 * {@hide}
Mike Lockwood709981e2010-06-28 09:58:58 -040081 */
82 public static final String ACTION_USB_STATE =
Mike Lockwoodc4308f02011-03-01 08:04:54 -080083 "android.hardware.usb.action.USB_STATE";
Mike Lockwood709981e2010-06-28 09:58:58 -040084
Jeff Brown76c4c662015-07-07 12:44:17 -070085 /**
86 * Broadcast Action: A broadcast for USB port changes.
87 *
88 * This intent is sent when a USB port is added, removed, or changes state.
89 * <ul>
90 * <li> {@link #EXTRA_PORT} containing the {@link android.hardware.usb.UsbPort}
91 * for the port.
92 * <li> {@link #EXTRA_PORT_STATUS} containing the {@link android.hardware.usb.UsbPortStatus}
93 * for the port, or null if the port has been removed
94 * </ul>
95 *
96 * @hide
97 */
98 public static final String ACTION_USB_PORT_CHANGED =
99 "android.hardware.usb.action.USB_PORT_CHANGED";
100
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500101 /**
102 * Broadcast Action: A broadcast for USB device attached event.
103 *
104 * This intent is sent when a USB device is attached to the USB bus when in host mode.
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500105 * <ul>
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800106 * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500107 * for the attached device
108 * </ul>
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500109 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600110 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500111 public static final String ACTION_USB_DEVICE_ATTACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800112 "android.hardware.usb.action.USB_DEVICE_ATTACHED";
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500113
114 /**
115 * Broadcast Action: A broadcast for USB device detached event.
116 *
117 * This intent is sent when a USB device is detached from the USB bus when in host mode.
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500118 * <ul>
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800119 * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
Mike Lockwood188d00b2011-02-23 13:14:33 -0800120 * for the detached device
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500121 * </ul>
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500122 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600123 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500124 public static final String ACTION_USB_DEVICE_DETACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800125 "android.hardware.usb.action.USB_DEVICE_DETACHED";
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500126
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500127 /**
128 * Broadcast Action: A broadcast for USB accessory attached event.
129 *
130 * This intent is sent when a USB accessory is attached.
131 * <ul>
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800132 * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500133 * for the attached accessory
134 * </ul>
135 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600136 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500137 public static final String ACTION_USB_ACCESSORY_ATTACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800138 "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500139
140 /**
141 * Broadcast Action: A broadcast for USB accessory detached event.
142 *
143 * This intent is sent when a USB accessory is detached.
144 * <ul>
Mike Lockwood980f0432011-03-09 15:49:13 -0500145 * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory}
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500146 * for the attached accessory that was detached
147 * </ul>
148 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600149 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500150 public static final String ACTION_USB_ACCESSORY_DETACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800151 "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500152
Mike Lockwood709981e2010-06-28 09:58:58 -0400153 /**
154 * Boolean extra indicating whether USB is connected or disconnected.
155 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
Mike Lockwooda75075e12011-03-11 11:26:11 -0500156 *
157 * {@hide}
Mike Lockwood709981e2010-06-28 09:58:58 -0400158 */
159 public static final String USB_CONNECTED = "connected";
Mike Lockwood24236072010-06-23 17:36:36 -0400160
161 /**
Daichi Hirono618fa6f2016-03-17 14:14:32 +0900162 * Boolean extra indicating whether USB is connected or disconnected as host.
163 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
164 *
165 * {@hide}
166 */
167 public static final String USB_HOST_CONNECTED = "host_connected";
168
169 /**
Mike Lockwood02e45692011-06-14 15:43:51 -0400170 * Boolean extra indicating whether USB is configured.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800171 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
Mike Lockwooda75075e12011-03-11 11:26:11 -0500172 *
173 * {@hide}
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800174 */
Mike Lockwood02e45692011-06-14 15:43:51 -0400175 public static final String USB_CONFIGURED = "configured";
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800176
177 /**
Nick Kralevich67401902015-06-10 09:38:42 -0700178 * Boolean extra indicating whether confidential user data, such as photos, should be
179 * made available on the USB connection. This variable will only be set when the user
180 * has explicitly asked for this data to be unlocked.
181 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
182 *
183 * {@hide}
184 */
185 public static final String USB_DATA_UNLOCKED = "unlocked";
186
187 /**
Jerry Zhangbb598ee2016-10-24 14:35:08 -0700188 * Boolean extra indicating whether the intent represents a change in the usb
189 * configuration (as opposed to a state update).
190 *
191 * {@hide}
192 */
193 public static final String USB_CONFIG_CHANGED = "config_changed";
194
195 /**
Jeff Brown460a1462015-06-30 17:57:12 -0700196 * A placeholder indicating that no USB function is being specified.
197 * Used to distinguish between selecting no function vs. the default function in
198 * {@link #setCurrentFunction(String)}.
Mike Lockwooda75075e12011-03-11 11:26:11 -0500199 *
200 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400201 */
Jeff Brown460a1462015-06-30 17:57:12 -0700202 public static final String USB_FUNCTION_NONE = "none";
Mike Lockwood24236072010-06-23 17:36:36 -0400203
204 /**
205 * Name of the adb USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800206 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500207 *
208 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400209 */
210 public static final String USB_FUNCTION_ADB = "adb";
211
212 /**
213 * Name of the RNDIS ethernet USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800214 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500215 *
216 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400217 */
218 public static final String USB_FUNCTION_RNDIS = "rndis";
219
220 /**
221 * Name of the MTP USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800222 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500223 *
224 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400225 */
226 public static final String USB_FUNCTION_MTP = "mtp";
227
228 /**
Mike Lockwood9eb014a2011-06-08 09:17:45 -0700229 * Name of the PTP USB function.
230 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
231 *
232 * {@hide}
233 */
234 public static final String USB_FUNCTION_PTP = "ptp";
235
236 /**
Mike Lockwood9d5a4be2012-04-06 09:41:32 -0700237 * Name of the audio source USB function.
238 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
239 *
240 * {@hide}
241 */
242 public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
243
244 /**
Mike Lockwood2a57bc72014-09-19 11:16:52 -0700245 * Name of the MIDI USB function.
246 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
247 *
248 * {@hide}
249 */
250 public static final String USB_FUNCTION_MIDI = "midi";
251
252 /**
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500253 * Name of the Accessory USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800254 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500255 *
256 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400257 */
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500258 public static final String USB_FUNCTION_ACCESSORY = "accessory";
259
260 /**
Jeff Brown76c4c662015-07-07 12:44:17 -0700261 * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
262 * containing the {@link UsbPort} object for the port.
263 *
264 * @hide
265 */
266 public static final String EXTRA_PORT = "port";
267
268 /**
269 * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
270 * containing the {@link UsbPortStatus} object for the port, or null if the port
271 * was removed.
272 *
273 * @hide
274 */
275 public static final String EXTRA_PORT_STATUS = "portStatus";
276
277 /**
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500278 * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
Mike Lockwood02eb8742011-02-27 09:10:37 -0800279 * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
Jeff Brown460a1462015-06-30 17:57:12 -0700280 * containing the {@link UsbDevice} object for the device.
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500281 */
282 public static final String EXTRA_DEVICE = "device";
283
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500284 /**
Mike Lockwood02eb8742011-02-27 09:10:37 -0800285 * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and
286 * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts
Jeff Brown460a1462015-06-30 17:57:12 -0700287 * containing the {@link UsbAccessory} object for the accessory.
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500288 */
289 public static final String EXTRA_ACCESSORY = "accessory";
290
Mike Lockwood3a68b832011-03-08 10:08:59 -0500291 /**
292 * Name of extra added to the {@link android.app.PendingIntent}
Mike Lockwood980f0432011-03-09 15:49:13 -0500293 * passed into {@link #requestPermission(UsbDevice, PendingIntent)}
294 * or {@link #requestPermission(UsbAccessory, PendingIntent)}
Mike Lockwood3a68b832011-03-08 10:08:59 -0500295 * containing a boolean value indicating whether the user granted permission or not.
296 */
297 public static final String EXTRA_PERMISSION_GRANTED = "permission";
298
299 private final Context mContext;
300 private final IUsbManager mService;
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500301
302 /**
303 * {@hide}
304 */
Mike Lockwood3a68b832011-03-08 10:08:59 -0500305 public UsbManager(Context context, IUsbManager service) {
306 mContext = context;
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500307 mService = service;
308 }
309
310 /**
311 * Returns a HashMap containing all USB devices currently attached.
312 * USB device name is the key for the returned HashMap.
313 * The result will be empty if no devices are attached, or if
314 * USB host mode is inactive or unsupported.
315 *
316 * @return HashMap containing all connected USB devices.
317 */
318 public HashMap<String,UsbDevice> getDeviceList() {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800319 HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
320 if (mService == null) {
321 return result;
322 }
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500323 Bundle bundle = new Bundle();
324 try {
325 mService.getDeviceList(bundle);
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500326 for (String name : bundle.keySet()) {
327 result.put(name, (UsbDevice)bundle.get(name));
328 }
329 return result;
330 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700331 throw e.rethrowFromSystemServer();
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500332 }
333 }
334
335 /**
336 * Opens the device so it can be used to send and receive
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800337 * data using {@link android.hardware.usb.UsbRequest}.
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500338 *
339 * @param device the device to open
mike wakerly1567a432012-07-17 19:58:19 -0700340 * @return a {@link UsbDeviceConnection}, or {@code null} if open failed
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500341 */
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500342 public UsbDeviceConnection openDevice(UsbDevice device) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500343 try {
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500344 String deviceName = device.getDeviceName();
345 ParcelFileDescriptor pfd = mService.openDevice(deviceName);
346 if (pfd != null) {
347 UsbDeviceConnection connection = new UsbDeviceConnection(device);
Philip P. Moltmannec3cbb22016-09-14 13:24:52 -0700348 boolean result = connection.open(deviceName, pfd, mContext);
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500349 pfd.close();
350 if (result) {
351 return connection;
352 }
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500353 }
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500354 } catch (Exception e) {
355 Log.e(TAG, "exception in UsbManager.openDevice", e);
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500356 }
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500357 return null;
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500358 }
359
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500360 /**
361 * Returns a list of currently attached USB accessories.
362 * (in the current implementation there can be at most one)
363 *
364 * @return list of USB accessories, or null if none are attached.
365 */
366 public UsbAccessory[] getAccessoryList() {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800367 if (mService == null) {
368 return null;
369 }
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500370 try {
371 UsbAccessory accessory = mService.getCurrentAccessory();
372 if (accessory == null) {
373 return null;
374 } else {
375 return new UsbAccessory[] { accessory };
376 }
377 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700378 throw e.rethrowFromSystemServer();
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500379 }
380 }
381
382 /**
383 * Opens a file descriptor for reading and writing data to the USB accessory.
384 *
385 * @param accessory the USB accessory to open
386 * @return file descriptor, or null if the accessor could not be opened.
387 */
388 public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
389 try {
Mike Lockwood02eb8742011-02-27 09:10:37 -0800390 return mService.openAccessory(accessory);
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500391 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700392 throw e.rethrowFromSystemServer();
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500393 }
394 }
395
Mike Lockwood3a68b832011-03-08 10:08:59 -0500396 /**
397 * Returns true if the caller has permission to access the device.
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500398 * Permission might have been granted temporarily via
Mike Lockwood980f0432011-03-09 15:49:13 -0500399 * {@link #requestPermission(UsbDevice, PendingIntent)} or
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500400 * by the user choosing the caller as the default application for the device.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500401 *
402 * @param device to check permissions for
403 * @return true if caller has permission
404 */
405 public boolean hasPermission(UsbDevice device) {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800406 if (mService == null) {
407 return false;
408 }
Mike Lockwood3a68b832011-03-08 10:08:59 -0500409 try {
410 return mService.hasDevicePermission(device);
411 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700412 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500413 }
414 }
415
416 /**
417 * Returns true if the caller has permission to access the accessory.
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500418 * Permission might have been granted temporarily via
Mike Lockwood980f0432011-03-09 15:49:13 -0500419 * {@link #requestPermission(UsbAccessory, PendingIntent)} or
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500420 * by the user choosing the caller as the default application for the accessory.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500421 *
422 * @param accessory to check permissions for
423 * @return true if caller has permission
424 */
425 public boolean hasPermission(UsbAccessory accessory) {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800426 if (mService == null) {
427 return false;
428 }
Mike Lockwood3a68b832011-03-08 10:08:59 -0500429 try {
430 return mService.hasAccessoryPermission(accessory);
431 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700432 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500433 }
434 }
435
436 /**
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500437 * Requests temporary permission for the given package to access the device.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500438 * This may result in a system dialog being displayed to the user
439 * if permission had not already been granted.
440 * Success or failure is returned via the {@link android.app.PendingIntent} pi.
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500441 * If successful, this grants the caller permission to access the device only
442 * until the device is disconnected.
443 *
Mike Lockwood3a68b832011-03-08 10:08:59 -0500444 * The following extras will be added to pi:
445 * <ul>
446 * <li> {@link #EXTRA_DEVICE} containing the device passed into this call
447 * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
448 * permission was granted by the user
449 * </ul>
450 *
451 * @param device to request permissions for
452 * @param pi PendingIntent for returning result
453 */
454 public void requestPermission(UsbDevice device, PendingIntent pi) {
455 try {
456 mService.requestDevicePermission(device, mContext.getPackageName(), pi);
457 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700458 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500459 }
460 }
461
462 /**
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500463 * Requests temporary permission for the given package to access the accessory.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500464 * This may result in a system dialog being displayed to the user
465 * if permission had not already been granted.
466 * Success or failure is returned via the {@link android.app.PendingIntent} pi.
Mike Lockwood62cfeeb2011-03-11 18:39:03 -0500467 * If successful, this grants the caller permission to access the accessory only
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500468 * until the device is disconnected.
469 *
Mike Lockwood3a68b832011-03-08 10:08:59 -0500470 * The following extras will be added to pi:
471 * <ul>
472 * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
473 * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
474 * permission was granted by the user
475 * </ul>
476 *
477 * @param accessory to request permissions for
478 * @param pi PendingIntent for returning result
479 */
480 public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
481 try {
482 mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi);
483 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700484 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500485 }
486 }
487
Mike Lockwood02e45692011-06-14 15:43:51 -0400488 /**
Daichi Hirono47518802015-12-08 09:51:19 +0900489 * Grants permission for USB device without showing system dialog.
490 * Only system components can call this function.
491 * @param device to request permissions for
492 *
493 * {@hide}
494 */
495 public void grantPermission(UsbDevice device) {
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800496 grantPermission(device, Process.myUid());
497 }
498
499 /**
500 * Grants permission for USB device to given uid without showing system dialog.
501 * Only system components can call this function.
502 * @param device to request permissions for
503 * @uid uid to give permission
504 *
505 * {@hide}
506 */
507 public void grantPermission(UsbDevice device, int uid) {
Daichi Hirono47518802015-12-08 09:51:19 +0900508 try {
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800509 mService.grantDevicePermission(device, uid);
Daichi Hirono47518802015-12-08 09:51:19 +0900510 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700511 throw e.rethrowFromSystemServer();
Daichi Hirono47518802015-12-08 09:51:19 +0900512 }
513 }
514
515 /**
Johan T. Halseth244259a2016-05-24 14:49:04 +0100516 * Grants permission to specified package for USB device without showing system dialog.
517 * Only system components can call this function, as it requires the MANAGE_USB permission.
518 * @param device to request permissions for
519 * @param packageName of package to grant permissions
520 *
521 * {@hide}
522 */
523 public void grantPermission(UsbDevice device, String packageName) {
524 try {
525 int uid = mContext.getPackageManager()
526 .getPackageUidAsUser(packageName, mContext.getUserId());
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800527 grantPermission(device, uid);
Johan T. Halseth244259a2016-05-24 14:49:04 +0100528 } catch (NameNotFoundException e) {
529 Log.e(TAG, "Package " + packageName + " not found.", e);
Johan T. Halseth244259a2016-05-24 14:49:04 +0100530 }
531 }
532
533 /**
Jeff Brown460a1462015-06-30 17:57:12 -0700534 * Returns true if the specified USB function is currently enabled when in device mode.
535 * <p>
536 * USB functions represent interfaces which are published to the host to access
537 * services offered by the device.
538 * </p>
Mike Lockwoode51099f2011-08-02 12:54:49 -0400539 *
Nick Kralevichfcf10f72015-05-13 11:54:03 -0700540 * @param function name of the USB function
Jeff Brown460a1462015-06-30 17:57:12 -0700541 * @return true if the USB function is enabled
Mike Lockwoode51099f2011-08-02 12:54:49 -0400542 *
543 * {@hide}
544 */
Nick Kralevichfcf10f72015-05-13 11:54:03 -0700545 public boolean isFunctionEnabled(String function) {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800546 if (mService == null) {
547 return false;
548 }
Jeff Brown460a1462015-06-30 17:57:12 -0700549 try {
550 return mService.isFunctionEnabled(function);
551 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700552 throw e.rethrowFromSystemServer();
Jeff Brown460a1462015-06-30 17:57:12 -0700553 }
Mike Lockwoode51099f2011-08-02 12:54:49 -0400554 }
555
556 /**
Jeff Brown460a1462015-06-30 17:57:12 -0700557 * Sets the current USB function when in device mode.
558 * <p>
559 * USB functions represent interfaces which are published to the host to access
560 * services offered by the device.
561 * </p><p>
562 * This method is intended to select among primary USB functions. The system may
563 * automatically activate additional functions such as {@link #USB_FUNCTION_ADB}
564 * or {@link #USB_FUNCTION_ACCESSORY} based on other settings and states.
565 * </p><p>
566 * The allowed values are: {@link #USB_FUNCTION_NONE}, {@link #USB_FUNCTION_AUDIO_SOURCE},
567 * {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP},
568 * or {@link #USB_FUNCTION_RNDIS}.
569 * </p><p>
Jerry Zhang7a396be2016-10-12 15:49:32 -0700570 * Also sets whether USB data (for example, MTP exposed pictures) should be made available
571 * on the USB connection when in device mode. Unlocking usb data should only be done with
572 * user involvement, since exposing pictures or other data could leak sensitive
573 * user information.
574 * </p><p>
Jeff Brown460a1462015-06-30 17:57:12 -0700575 * Note: This function is asynchronous and may fail silently without applying
576 * the requested changes.
577 * </p>
Mike Lockwood02e45692011-06-14 15:43:51 -0400578 *
Mike Lockwood875c24b2011-07-18 10:54:32 -0700579 * @param function name of the USB function, or null to restore the default function
Jerry Zhang7a396be2016-10-12 15:49:32 -0700580 * @param usbDataUnlocked whether user data is accessible
Mike Lockwood02e45692011-06-14 15:43:51 -0400581 *
582 * {@hide}
583 */
Jerry Zhang7a396be2016-10-12 15:49:32 -0700584 public void setCurrentFunction(String function, boolean usbDataUnlocked) {
Mike Lockwood08bff3b2010-08-31 13:27:05 -0400585 try {
Jerry Zhang7a396be2016-10-12 15:49:32 -0700586 mService.setCurrentFunction(function, usbDataUnlocked);
Nick Kralevich67401902015-06-10 09:38:42 -0700587 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700588 throw e.rethrowFromSystemServer();
Nick Kralevich67401902015-06-10 09:38:42 -0700589 }
590 }
591
592 /**
Jeff Brown76c4c662015-07-07 12:44:17 -0700593 * Returns a list of physical USB ports on the device.
594 * <p>
595 * This list is guaranteed to contain all dual-role USB Type C ports but it might
596 * be missing other ports depending on whether the kernel USB drivers have been
597 * updated to publish all of the device's ports through the new "dual_role_usb"
598 * device class (which supports all types of ports despite its name).
599 * </p>
600 *
601 * @return The list of USB ports, or null if none.
602 *
603 * @hide
604 */
605 public UsbPort[] getPorts() {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800606 if (mService == null) {
607 return null;
608 }
Jeff Brown76c4c662015-07-07 12:44:17 -0700609 try {
610 return mService.getPorts();
611 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700612 throw e.rethrowFromSystemServer();
Jeff Brown76c4c662015-07-07 12:44:17 -0700613 }
Jeff Brown76c4c662015-07-07 12:44:17 -0700614 }
615
616 /**
617 * Gets the status of the specified USB port.
618 *
619 * @param port The port to query.
620 * @return The status of the specified USB port, or null if unknown.
621 *
622 * @hide
623 */
624 public UsbPortStatus getPortStatus(UsbPort port) {
625 Preconditions.checkNotNull(port, "port must not be null");
626
627 try {
628 return mService.getPortStatus(port.getId());
629 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700630 throw e.rethrowFromSystemServer();
Jeff Brown76c4c662015-07-07 12:44:17 -0700631 }
Jeff Brown76c4c662015-07-07 12:44:17 -0700632 }
633
634 /**
635 * Sets the desired role combination of the port.
636 * <p>
637 * The supported role combinations depend on what is connected to the port and may be
638 * determined by consulting
639 * {@link UsbPortStatus#isRoleCombinationSupported UsbPortStatus.isRoleCombinationSupported}.
640 * </p><p>
641 * Note: This function is asynchronous and may fail silently without applying
642 * the requested changes. If this function does cause a status change to occur then
643 * a {@link #ACTION_USB_PORT_CHANGED} broadcast will be sent.
644 * </p>
645 *
646 * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
647 * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
648 * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
649 * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
650 *
651 * @hide
652 */
653 public void setPortRoles(UsbPort port, int powerRole, int dataRole) {
654 Preconditions.checkNotNull(port, "port must not be null");
655 UsbPort.checkRoles(powerRole, dataRole);
656
Badhri Jagan Sridharan4641fc32017-06-22 16:39:47 -0700657 Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
Jeff Brown76c4c662015-07-07 12:44:17 -0700658 try {
659 mService.setPortRoles(port.getId(), powerRole, dataRole);
660 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700661 throw e.rethrowFromSystemServer();
Jeff Brown76c4c662015-07-07 12:44:17 -0700662 }
663 }
664
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800665 /**
666 * Sets the component that will handle USB device connection.
667 * <p>
668 * Setting component allows to specify external USB host manager to handle use cases, where
669 * selection dialog for an activity that will handle USB device is undesirable.
670 * Only system components can call this function, as it requires the MANAGE_USB permission.
671 *
672 * @param usbDeviceConnectionHandler The component to handle usb connections,
673 * {@code null} to unset.
674 *
675 * {@hide}
676 */
677 public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
678 try {
679 mService.setUsbDeviceConnectionHandler(usbDeviceConnectionHandler);
680 } catch (RemoteException e) {
681 throw e.rethrowFromSystemServer();
682 }
683 }
684
Jeff Brown460a1462015-06-30 17:57:12 -0700685 /** @hide */
686 public static String addFunction(String functions, String function) {
Yasuhiro Matsuda48b9a7c2015-07-16 19:00:16 +0900687 if (USB_FUNCTION_NONE.equals(functions)) {
Jeff Brown460a1462015-06-30 17:57:12 -0700688 return function;
689 }
690 if (!containsFunction(functions, function)) {
691 if (functions.length() > 0) {
692 functions += ",";
693 }
694 functions += function;
695 }
696 return functions;
697 }
698
699 /** @hide */
700 public static String removeFunction(String functions, String function) {
701 String[] split = functions.split(",");
702 for (int i = 0; i < split.length; i++) {
703 if (function.equals(split[i])) {
704 split[i] = null;
705 }
706 }
707 if (split.length == 1 && split[0] == null) {
Yasuhiro Matsuda48b9a7c2015-07-16 19:00:16 +0900708 return USB_FUNCTION_NONE;
Jeff Brown460a1462015-06-30 17:57:12 -0700709 }
710 StringBuilder builder = new StringBuilder();
711 for (int i = 0; i < split.length; i++) {
712 String s = split[i];
713 if (s != null) {
714 if (builder.length() > 0) {
715 builder.append(",");
716 }
717 builder.append(s);
718 }
719 }
720 return builder.toString();
721 }
722
723 /** @hide */
724 public static boolean containsFunction(String functions, String function) {
725 int index = functions.indexOf(function);
726 if (index < 0) return false;
727 if (index > 0 && functions.charAt(index - 1) != ',') return false;
728 int charAfter = index + function.length();
729 if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
730 return true;
731 }
Mike Lockwood24236072010-06-23 17:36:36 -0400732}