blob: 595d85715fc955d6c1a53682f9944d783d4ee890 [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
Philip P. Moltmannf3189e62017-08-16 16:04:24 -070020import android.Manifest;
Keun-young Parkbadbbae2016-01-05 13:27:29 -080021import android.annotation.Nullable;
Philip P. Moltmannf3189e62017-08-16 16:04:24 -070022import android.annotation.RequiresPermission;
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -060023import android.annotation.SdkConstant;
24import android.annotation.SdkConstant.SdkConstantType;
Philip P. Moltmannf3189e62017-08-16 16:04:24 -070025import android.annotation.SystemApi;
26import android.annotation.SystemService;
Mike Lockwood3a68b832011-03-08 10:08:59 -050027import android.app.PendingIntent;
Keun-young Parkbadbbae2016-01-05 13:27:29 -080028import android.content.ComponentName;
Mike Lockwood3a68b832011-03-08 10:08:59 -050029import android.content.Context;
Johan T. Halseth244259a2016-05-24 14:49:04 +010030import android.content.pm.PackageManager.NameNotFoundException;
Mike Lockwoode7d511e2010-12-30 13:39:37 -050031import android.os.Bundle;
32import android.os.ParcelFileDescriptor;
Daichi Hirono47518802015-12-08 09:51:19 +090033import android.os.Process;
Mike Lockwoode7d511e2010-12-30 13:39:37 -050034import android.os.RemoteException;
35import android.util.Log;
36
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -060037import com.android.internal.util.Preconditions;
38
Mike Lockwoode7d511e2010-12-30 13:39:37 -050039import java.util.HashMap;
Mike Lockwood08bff3b2010-08-31 13:27:05 -040040
Mike Lockwood24236072010-06-23 17:36:36 -040041/**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -040042 * This class allows you to access the state of USB and communicate with USB devices.
43 * Currently only host mode is supported in the public API.
Mike Lockwoode7d511e2010-12-30 13:39:37 -050044 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080045 * <div class="special reference">
46 * <h3>Developer Guides</h3>
47 * <p>For more information about communicating with USB hardware, read the
Mark Lu8b739902016-06-24 15:38:02 -070048 * <a href="{@docRoot}guide/topics/connectivity/usb/index.html">USB developer guide</a>.</p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080049 * </div>
Mike Lockwood24236072010-06-23 17:36:36 -040050 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060051@SystemService(Context.USB_SERVICE)
Mike Lockwood770126a2010-12-09 22:30:37 -080052public class UsbManager {
Mike Lockwoode7d511e2010-12-30 13:39:37 -050053 private static final String TAG = "UsbManager";
54
Mike Lockwood24236072010-06-23 17:36:36 -040055 /**
Mike Lockwoode7d511e2010-12-30 13:39:37 -050056 * Broadcast Action: A sticky broadcast for USB state change events when in device mode.
Mike Lockwood709981e2010-06-28 09:58:58 -040057 *
Mike Lockwoodb92df0f2010-12-10 16:19:32 -080058 * This is a sticky broadcast for clients that includes USB connected/disconnected state,
Mike Lockwood9182d3c2011-02-15 09:50:22 -050059 * <ul>
60 * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
Daichi Hirono618fa6f2016-03-17 14:14:32 +090061 * <li> {@link #USB_HOST_CONNECTED} boolean indicating whether USB is connected or
62 * disconnected as host.
Mike Lockwood02e45692011-06-14 15:43:51 -040063 * <li> {@link #USB_CONFIGURED} boolean indicating whether USB is configured.
Mike Lockwood9eb014a2011-06-08 09:17:45 -070064 * currently zero if not configured, one for configured.
Mike Lockwood9eb014a2011-06-08 09:17:45 -070065 * <li> {@link #USB_FUNCTION_ADB} boolean extra indicating whether the
66 * adb function is enabled
67 * <li> {@link #USB_FUNCTION_RNDIS} boolean extra indicating whether the
68 * RNDIS ethernet function is enabled
69 * <li> {@link #USB_FUNCTION_MTP} boolean extra indicating whether the
70 * MTP function is enabled
71 * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
72 * PTP function is enabled
73 * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
74 * accessory function is enabled
Mike Lockwood9d5a4be2012-04-06 09:41:32 -070075 * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
76 * audio source function is enabled
Mike Lockwood2a57bc72014-09-19 11:16:52 -070077 * <li> {@link #USB_FUNCTION_MIDI} boolean extra indicating whether the
78 * MIDI function is enabled
Mike Lockwood9182d3c2011-02-15 09:50:22 -050079 * </ul>
Yasuhiro Matsuda48b9a7c2015-07-16 19:00:16 +090080 * If the sticky intent has not been found, that indicates USB is disconnected,
81 * USB is not configued, MTP function is enabled, and all the other functions are disabled.
Mike Lockwooda75075e12011-03-11 11:26:11 -050082 *
83 * {@hide}
Mike Lockwood709981e2010-06-28 09:58:58 -040084 */
85 public static final String ACTION_USB_STATE =
Mike Lockwoodc4308f02011-03-01 08:04:54 -080086 "android.hardware.usb.action.USB_STATE";
Mike Lockwood709981e2010-06-28 09:58:58 -040087
Jeff Brown76c4c662015-07-07 12:44:17 -070088 /**
89 * Broadcast Action: A broadcast for USB port changes.
90 *
91 * This intent is sent when a USB port is added, removed, or changes state.
92 * <ul>
93 * <li> {@link #EXTRA_PORT} containing the {@link android.hardware.usb.UsbPort}
94 * for the port.
95 * <li> {@link #EXTRA_PORT_STATUS} containing the {@link android.hardware.usb.UsbPortStatus}
96 * for the port, or null if the port has been removed
97 * </ul>
98 *
99 * @hide
100 */
101 public static final String ACTION_USB_PORT_CHANGED =
102 "android.hardware.usb.action.USB_PORT_CHANGED";
103
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500104 /**
105 * Broadcast Action: A broadcast for USB device attached event.
106 *
107 * 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 -0500108 * <ul>
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800109 * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500110 * for the attached device
111 * </ul>
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500112 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600113 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500114 public static final String ACTION_USB_DEVICE_ATTACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800115 "android.hardware.usb.action.USB_DEVICE_ATTACHED";
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500116
117 /**
118 * Broadcast Action: A broadcast for USB device detached event.
119 *
120 * 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 -0500121 * <ul>
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800122 * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
Mike Lockwood188d00b2011-02-23 13:14:33 -0800123 * for the detached device
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500124 * </ul>
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500125 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600126 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500127 public static final String ACTION_USB_DEVICE_DETACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800128 "android.hardware.usb.action.USB_DEVICE_DETACHED";
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500129
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500130 /**
131 * Broadcast Action: A broadcast for USB accessory attached event.
132 *
133 * This intent is sent when a USB accessory is attached.
134 * <ul>
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800135 * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500136 * for the attached accessory
137 * </ul>
138 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600139 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500140 public static final String ACTION_USB_ACCESSORY_ATTACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800141 "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500142
143 /**
144 * Broadcast Action: A broadcast for USB accessory detached event.
145 *
146 * This intent is sent when a USB accessory is detached.
147 * <ul>
Mike Lockwood980f0432011-03-09 15:49:13 -0500148 * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory}
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500149 * for the attached accessory that was detached
150 * </ul>
151 */
Jeff Sharkey0f3f60b2017-04-24 18:06:20 -0600152 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500153 public static final String ACTION_USB_ACCESSORY_DETACHED =
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800154 "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500155
Mike Lockwood709981e2010-06-28 09:58:58 -0400156 /**
157 * Boolean extra indicating whether USB is connected or disconnected.
158 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
Mike Lockwooda75075e12011-03-11 11:26:11 -0500159 *
160 * {@hide}
Mike Lockwood709981e2010-06-28 09:58:58 -0400161 */
162 public static final String USB_CONNECTED = "connected";
Mike Lockwood24236072010-06-23 17:36:36 -0400163
164 /**
Daichi Hirono618fa6f2016-03-17 14:14:32 +0900165 * Boolean extra indicating whether USB is connected or disconnected as host.
166 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
167 *
168 * {@hide}
169 */
170 public static final String USB_HOST_CONNECTED = "host_connected";
171
172 /**
Mike Lockwood02e45692011-06-14 15:43:51 -0400173 * Boolean extra indicating whether USB is configured.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800174 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
Mike Lockwooda75075e12011-03-11 11:26:11 -0500175 *
176 * {@hide}
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800177 */
Mike Lockwood02e45692011-06-14 15:43:51 -0400178 public static final String USB_CONFIGURED = "configured";
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800179
180 /**
Nick Kralevich67401902015-06-10 09:38:42 -0700181 * Boolean extra indicating whether confidential user data, such as photos, should be
182 * made available on the USB connection. This variable will only be set when the user
183 * has explicitly asked for this data to be unlocked.
184 * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
185 *
186 * {@hide}
187 */
188 public static final String USB_DATA_UNLOCKED = "unlocked";
189
190 /**
Jerry Zhangbb598ee2016-10-24 14:35:08 -0700191 * Boolean extra indicating whether the intent represents a change in the usb
192 * configuration (as opposed to a state update).
193 *
194 * {@hide}
195 */
196 public static final String USB_CONFIG_CHANGED = "config_changed";
197
198 /**
Jeff Brown460a1462015-06-30 17:57:12 -0700199 * A placeholder indicating that no USB function is being specified.
200 * Used to distinguish between selecting no function vs. the default function in
201 * {@link #setCurrentFunction(String)}.
Mike Lockwooda75075e12011-03-11 11:26:11 -0500202 *
203 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400204 */
Jeff Brown460a1462015-06-30 17:57:12 -0700205 public static final String USB_FUNCTION_NONE = "none";
Mike Lockwood24236072010-06-23 17:36:36 -0400206
207 /**
208 * Name of the adb USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800209 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500210 *
211 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400212 */
213 public static final String USB_FUNCTION_ADB = "adb";
214
215 /**
216 * Name of the RNDIS ethernet USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800217 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500218 *
219 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400220 */
221 public static final String USB_FUNCTION_RNDIS = "rndis";
222
223 /**
224 * Name of the MTP USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800225 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500226 *
227 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400228 */
229 public static final String USB_FUNCTION_MTP = "mtp";
230
231 /**
Mike Lockwood9eb014a2011-06-08 09:17:45 -0700232 * Name of the PTP USB function.
233 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
234 *
235 * {@hide}
236 */
237 public static final String USB_FUNCTION_PTP = "ptp";
238
239 /**
Mike Lockwood9d5a4be2012-04-06 09:41:32 -0700240 * Name of the audio source USB function.
241 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
242 *
243 * {@hide}
244 */
245 public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
246
247 /**
Mike Lockwood2a57bc72014-09-19 11:16:52 -0700248 * Name of the MIDI USB function.
249 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
250 *
251 * {@hide}
252 */
253 public static final String USB_FUNCTION_MIDI = "midi";
254
255 /**
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500256 * Name of the Accessory USB function.
Mike Lockwoodb92df0f2010-12-10 16:19:32 -0800257 * Used in extras for the {@link #ACTION_USB_STATE} broadcast
Mike Lockwooda75075e12011-03-11 11:26:11 -0500258 *
259 * {@hide}
Mike Lockwood24236072010-06-23 17:36:36 -0400260 */
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500261 public static final String USB_FUNCTION_ACCESSORY = "accessory";
262
263 /**
Jeff Brown76c4c662015-07-07 12:44:17 -0700264 * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
265 * containing the {@link UsbPort} object for the port.
266 *
267 * @hide
268 */
269 public static final String EXTRA_PORT = "port";
270
271 /**
272 * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
273 * containing the {@link UsbPortStatus} object for the port, or null if the port
274 * was removed.
275 *
276 * @hide
277 */
278 public static final String EXTRA_PORT_STATUS = "portStatus";
279
280 /**
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500281 * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
Mike Lockwood02eb8742011-02-27 09:10:37 -0800282 * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
Jeff Brown460a1462015-06-30 17:57:12 -0700283 * containing the {@link UsbDevice} object for the device.
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500284 */
285 public static final String EXTRA_DEVICE = "device";
286
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500287 /**
Mike Lockwood02eb8742011-02-27 09:10:37 -0800288 * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and
289 * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts
Jeff Brown460a1462015-06-30 17:57:12 -0700290 * containing the {@link UsbAccessory} object for the accessory.
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500291 */
292 public static final String EXTRA_ACCESSORY = "accessory";
293
Mike Lockwood3a68b832011-03-08 10:08:59 -0500294 /**
295 * Name of extra added to the {@link android.app.PendingIntent}
Mike Lockwood980f0432011-03-09 15:49:13 -0500296 * passed into {@link #requestPermission(UsbDevice, PendingIntent)}
297 * or {@link #requestPermission(UsbAccessory, PendingIntent)}
Mike Lockwood3a68b832011-03-08 10:08:59 -0500298 * containing a boolean value indicating whether the user granted permission or not.
299 */
300 public static final String EXTRA_PERMISSION_GRANTED = "permission";
301
302 private final Context mContext;
303 private final IUsbManager mService;
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500304
305 /**
306 * {@hide}
307 */
Mike Lockwood3a68b832011-03-08 10:08:59 -0500308 public UsbManager(Context context, IUsbManager service) {
309 mContext = context;
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500310 mService = service;
311 }
312
313 /**
314 * Returns a HashMap containing all USB devices currently attached.
315 * USB device name is the key for the returned HashMap.
316 * The result will be empty if no devices are attached, or if
317 * USB host mode is inactive or unsupported.
318 *
319 * @return HashMap containing all connected USB devices.
320 */
321 public HashMap<String,UsbDevice> getDeviceList() {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800322 HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
323 if (mService == null) {
324 return result;
325 }
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500326 Bundle bundle = new Bundle();
327 try {
328 mService.getDeviceList(bundle);
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500329 for (String name : bundle.keySet()) {
330 result.put(name, (UsbDevice)bundle.get(name));
331 }
332 return result;
333 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700334 throw e.rethrowFromSystemServer();
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500335 }
336 }
337
338 /**
339 * Opens the device so it can be used to send and receive
Mike Lockwoodc4308f02011-03-01 08:04:54 -0800340 * data using {@link android.hardware.usb.UsbRequest}.
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500341 *
342 * @param device the device to open
mike wakerly1567a432012-07-17 19:58:19 -0700343 * @return a {@link UsbDeviceConnection}, or {@code null} if open failed
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500344 */
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500345 public UsbDeviceConnection openDevice(UsbDevice device) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500346 try {
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500347 String deviceName = device.getDeviceName();
348 ParcelFileDescriptor pfd = mService.openDevice(deviceName);
349 if (pfd != null) {
350 UsbDeviceConnection connection = new UsbDeviceConnection(device);
Philip P. Moltmannec3cbb22016-09-14 13:24:52 -0700351 boolean result = connection.open(deviceName, pfd, mContext);
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500352 pfd.close();
353 if (result) {
354 return connection;
355 }
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500356 }
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500357 } catch (Exception e) {
358 Log.e(TAG, "exception in UsbManager.openDevice", e);
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500359 }
Mike Lockwoodacc29cc2011-03-11 08:18:08 -0500360 return null;
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500361 }
362
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500363 /**
364 * Returns a list of currently attached USB accessories.
365 * (in the current implementation there can be at most one)
366 *
367 * @return list of USB accessories, or null if none are attached.
368 */
369 public UsbAccessory[] getAccessoryList() {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800370 if (mService == null) {
371 return null;
372 }
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500373 try {
374 UsbAccessory accessory = mService.getCurrentAccessory();
375 if (accessory == null) {
376 return null;
377 } else {
378 return new UsbAccessory[] { accessory };
379 }
380 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700381 throw e.rethrowFromSystemServer();
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500382 }
383 }
384
385 /**
386 * Opens a file descriptor for reading and writing data to the USB accessory.
387 *
388 * @param accessory the USB accessory to open
389 * @return file descriptor, or null if the accessor could not be opened.
390 */
391 public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
392 try {
Mike Lockwood02eb8742011-02-27 09:10:37 -0800393 return mService.openAccessory(accessory);
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500394 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700395 throw e.rethrowFromSystemServer();
Mike Lockwood9182d3c2011-02-15 09:50:22 -0500396 }
397 }
398
Mike Lockwood3a68b832011-03-08 10:08:59 -0500399 /**
400 * Returns true if the caller has permission to access the device.
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500401 * Permission might have been granted temporarily via
Mike Lockwood980f0432011-03-09 15:49:13 -0500402 * {@link #requestPermission(UsbDevice, PendingIntent)} or
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500403 * by the user choosing the caller as the default application for the device.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500404 *
405 * @param device to check permissions for
406 * @return true if caller has permission
407 */
408 public boolean hasPermission(UsbDevice device) {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800409 if (mService == null) {
410 return false;
411 }
Mike Lockwood3a68b832011-03-08 10:08:59 -0500412 try {
413 return mService.hasDevicePermission(device);
414 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700415 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500416 }
417 }
418
419 /**
420 * Returns true if the caller has permission to access the accessory.
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500421 * Permission might have been granted temporarily via
Mike Lockwood980f0432011-03-09 15:49:13 -0500422 * {@link #requestPermission(UsbAccessory, PendingIntent)} or
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500423 * by the user choosing the caller as the default application for the accessory.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500424 *
425 * @param accessory to check permissions for
426 * @return true if caller has permission
427 */
428 public boolean hasPermission(UsbAccessory accessory) {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800429 if (mService == null) {
430 return false;
431 }
Mike Lockwood3a68b832011-03-08 10:08:59 -0500432 try {
433 return mService.hasAccessoryPermission(accessory);
434 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700435 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500436 }
437 }
438
439 /**
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500440 * Requests temporary permission for the given package to access the device.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500441 * This may result in a system dialog being displayed to the user
442 * if permission had not already been granted.
443 * Success or failure is returned via the {@link android.app.PendingIntent} pi.
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500444 * If successful, this grants the caller permission to access the device only
445 * until the device is disconnected.
446 *
Mike Lockwood3a68b832011-03-08 10:08:59 -0500447 * The following extras will be added to pi:
448 * <ul>
449 * <li> {@link #EXTRA_DEVICE} containing the device passed into this call
450 * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
451 * permission was granted by the user
452 * </ul>
453 *
454 * @param device to request permissions for
455 * @param pi PendingIntent for returning result
456 */
457 public void requestPermission(UsbDevice device, PendingIntent pi) {
458 try {
459 mService.requestDevicePermission(device, mContext.getPackageName(), pi);
460 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700461 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500462 }
463 }
464
465 /**
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500466 * Requests temporary permission for the given package to access the accessory.
Mike Lockwood3a68b832011-03-08 10:08:59 -0500467 * This may result in a system dialog being displayed to the user
468 * if permission had not already been granted.
469 * Success or failure is returned via the {@link android.app.PendingIntent} pi.
Mike Lockwood62cfeeb2011-03-11 18:39:03 -0500470 * If successful, this grants the caller permission to access the accessory only
Mike Lockwoodc6f23e82011-03-09 12:05:20 -0500471 * until the device is disconnected.
472 *
Mike Lockwood3a68b832011-03-08 10:08:59 -0500473 * The following extras will be added to pi:
474 * <ul>
475 * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
476 * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
477 * permission was granted by the user
478 * </ul>
479 *
480 * @param accessory to request permissions for
481 * @param pi PendingIntent for returning result
482 */
483 public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
484 try {
485 mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi);
486 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700487 throw e.rethrowFromSystemServer();
Mike Lockwood3a68b832011-03-08 10:08:59 -0500488 }
489 }
490
Mike Lockwood02e45692011-06-14 15:43:51 -0400491 /**
Daichi Hirono47518802015-12-08 09:51:19 +0900492 * Grants permission for USB device without showing system dialog.
493 * Only system components can call this function.
494 * @param device to request permissions for
495 *
496 * {@hide}
497 */
498 public void grantPermission(UsbDevice device) {
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800499 grantPermission(device, Process.myUid());
500 }
501
502 /**
503 * Grants permission for USB device to given uid without showing system dialog.
504 * Only system components can call this function.
505 * @param device to request permissions for
506 * @uid uid to give permission
507 *
508 * {@hide}
509 */
510 public void grantPermission(UsbDevice device, int uid) {
Daichi Hirono47518802015-12-08 09:51:19 +0900511 try {
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800512 mService.grantDevicePermission(device, uid);
Daichi Hirono47518802015-12-08 09:51:19 +0900513 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700514 throw e.rethrowFromSystemServer();
Daichi Hirono47518802015-12-08 09:51:19 +0900515 }
516 }
517
518 /**
Johan T. Halseth244259a2016-05-24 14:49:04 +0100519 * Grants permission to specified package for USB device without showing system dialog.
520 * Only system components can call this function, as it requires the MANAGE_USB permission.
521 * @param device to request permissions for
522 * @param packageName of package to grant permissions
523 *
524 * {@hide}
525 */
Philip P. Moltmannf3189e62017-08-16 16:04:24 -0700526 @SystemApi
527 @RequiresPermission(Manifest.permission.MANAGE_USB)
Johan T. Halseth244259a2016-05-24 14:49:04 +0100528 public void grantPermission(UsbDevice device, String packageName) {
529 try {
530 int uid = mContext.getPackageManager()
531 .getPackageUidAsUser(packageName, mContext.getUserId());
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800532 grantPermission(device, uid);
Johan T. Halseth244259a2016-05-24 14:49:04 +0100533 } catch (NameNotFoundException e) {
534 Log.e(TAG, "Package " + packageName + " not found.", e);
Johan T. Halseth244259a2016-05-24 14:49:04 +0100535 }
536 }
537
538 /**
Jeff Brown460a1462015-06-30 17:57:12 -0700539 * Returns true if the specified USB function is currently enabled when in device mode.
540 * <p>
541 * USB functions represent interfaces which are published to the host to access
542 * services offered by the device.
543 * </p>
Mike Lockwoode51099f2011-08-02 12:54:49 -0400544 *
Nick Kralevichfcf10f72015-05-13 11:54:03 -0700545 * @param function name of the USB function
Jeff Brown460a1462015-06-30 17:57:12 -0700546 * @return true if the USB function is enabled
Mike Lockwoode51099f2011-08-02 12:54:49 -0400547 *
548 * {@hide}
549 */
Nick Kralevichfcf10f72015-05-13 11:54:03 -0700550 public boolean isFunctionEnabled(String function) {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800551 if (mService == null) {
552 return false;
553 }
Jeff Brown460a1462015-06-30 17:57:12 -0700554 try {
555 return mService.isFunctionEnabled(function);
556 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700557 throw e.rethrowFromSystemServer();
Jeff Brown460a1462015-06-30 17:57:12 -0700558 }
Mike Lockwoode51099f2011-08-02 12:54:49 -0400559 }
560
561 /**
Jeff Brown460a1462015-06-30 17:57:12 -0700562 * Sets the current USB function when in device mode.
563 * <p>
564 * USB functions represent interfaces which are published to the host to access
565 * services offered by the device.
566 * </p><p>
567 * This method is intended to select among primary USB functions. The system may
568 * automatically activate additional functions such as {@link #USB_FUNCTION_ADB}
569 * or {@link #USB_FUNCTION_ACCESSORY} based on other settings and states.
570 * </p><p>
571 * The allowed values are: {@link #USB_FUNCTION_NONE}, {@link #USB_FUNCTION_AUDIO_SOURCE},
572 * {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP},
573 * or {@link #USB_FUNCTION_RNDIS}.
574 * </p><p>
Jerry Zhang7a396be2016-10-12 15:49:32 -0700575 * Also sets whether USB data (for example, MTP exposed pictures) should be made available
576 * on the USB connection when in device mode. Unlocking usb data should only be done with
577 * user involvement, since exposing pictures or other data could leak sensitive
578 * user information.
579 * </p><p>
Jeff Brown460a1462015-06-30 17:57:12 -0700580 * Note: This function is asynchronous and may fail silently without applying
581 * the requested changes.
582 * </p>
Mike Lockwood02e45692011-06-14 15:43:51 -0400583 *
Mike Lockwood875c24b2011-07-18 10:54:32 -0700584 * @param function name of the USB function, or null to restore the default function
Jerry Zhang7a396be2016-10-12 15:49:32 -0700585 * @param usbDataUnlocked whether user data is accessible
Mike Lockwood02e45692011-06-14 15:43:51 -0400586 *
587 * {@hide}
588 */
Jerry Zhang7a396be2016-10-12 15:49:32 -0700589 public void setCurrentFunction(String function, boolean usbDataUnlocked) {
Mike Lockwood08bff3b2010-08-31 13:27:05 -0400590 try {
Jerry Zhang7a396be2016-10-12 15:49:32 -0700591 mService.setCurrentFunction(function, usbDataUnlocked);
Nick Kralevich67401902015-06-10 09:38:42 -0700592 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700593 throw e.rethrowFromSystemServer();
Nick Kralevich67401902015-06-10 09:38:42 -0700594 }
595 }
596
597 /**
Jeff Brown76c4c662015-07-07 12:44:17 -0700598 * Returns a list of physical USB ports on the device.
599 * <p>
600 * This list is guaranteed to contain all dual-role USB Type C ports but it might
601 * be missing other ports depending on whether the kernel USB drivers have been
602 * updated to publish all of the device's ports through the new "dual_role_usb"
603 * device class (which supports all types of ports despite its name).
604 * </p>
605 *
606 * @return The list of USB ports, or null if none.
607 *
608 * @hide
609 */
610 public UsbPort[] getPorts() {
Jim Kaye9b5ee822017-02-15 14:28:23 -0800611 if (mService == null) {
612 return null;
613 }
Jeff Brown76c4c662015-07-07 12:44:17 -0700614 try {
615 return mService.getPorts();
616 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700617 throw e.rethrowFromSystemServer();
Jeff Brown76c4c662015-07-07 12:44:17 -0700618 }
Jeff Brown76c4c662015-07-07 12:44:17 -0700619 }
620
621 /**
622 * Gets the status of the specified USB port.
623 *
624 * @param port The port to query.
625 * @return The status of the specified USB port, or null if unknown.
626 *
627 * @hide
628 */
629 public UsbPortStatus getPortStatus(UsbPort port) {
630 Preconditions.checkNotNull(port, "port must not be null");
631
632 try {
633 return mService.getPortStatus(port.getId());
634 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700635 throw e.rethrowFromSystemServer();
Jeff Brown76c4c662015-07-07 12:44:17 -0700636 }
Jeff Brown76c4c662015-07-07 12:44:17 -0700637 }
638
639 /**
640 * Sets the desired role combination of the port.
641 * <p>
642 * The supported role combinations depend on what is connected to the port and may be
643 * determined by consulting
644 * {@link UsbPortStatus#isRoleCombinationSupported UsbPortStatus.isRoleCombinationSupported}.
645 * </p><p>
646 * Note: This function is asynchronous and may fail silently without applying
647 * the requested changes. If this function does cause a status change to occur then
648 * a {@link #ACTION_USB_PORT_CHANGED} broadcast will be sent.
649 * </p>
650 *
651 * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
652 * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
653 * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
654 * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
655 *
656 * @hide
657 */
658 public void setPortRoles(UsbPort port, int powerRole, int dataRole) {
659 Preconditions.checkNotNull(port, "port must not be null");
660 UsbPort.checkRoles(powerRole, dataRole);
661
Badhri Jagan Sridharan4641fc32017-06-22 16:39:47 -0700662 Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
Jeff Brown76c4c662015-07-07 12:44:17 -0700663 try {
664 mService.setPortRoles(port.getId(), powerRole, dataRole);
665 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700666 throw e.rethrowFromSystemServer();
Jeff Brown76c4c662015-07-07 12:44:17 -0700667 }
668 }
669
Keun-young Parkbadbbae2016-01-05 13:27:29 -0800670 /**
671 * Sets the component that will handle USB device connection.
672 * <p>
673 * Setting component allows to specify external USB host manager to handle use cases, where
674 * selection dialog for an activity that will handle USB device is undesirable.
675 * Only system components can call this function, as it requires the MANAGE_USB permission.
676 *
677 * @param usbDeviceConnectionHandler The component to handle usb connections,
678 * {@code null} to unset.
679 *
680 * {@hide}
681 */
682 public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
683 try {
684 mService.setUsbDeviceConnectionHandler(usbDeviceConnectionHandler);
685 } catch (RemoteException e) {
686 throw e.rethrowFromSystemServer();
687 }
688 }
689
Jeff Brown460a1462015-06-30 17:57:12 -0700690 /** @hide */
691 public static String addFunction(String functions, String function) {
Yasuhiro Matsuda48b9a7c2015-07-16 19:00:16 +0900692 if (USB_FUNCTION_NONE.equals(functions)) {
Jeff Brown460a1462015-06-30 17:57:12 -0700693 return function;
694 }
695 if (!containsFunction(functions, function)) {
696 if (functions.length() > 0) {
697 functions += ",";
698 }
699 functions += function;
700 }
701 return functions;
702 }
703
704 /** @hide */
705 public static String removeFunction(String functions, String function) {
706 String[] split = functions.split(",");
707 for (int i = 0; i < split.length; i++) {
708 if (function.equals(split[i])) {
709 split[i] = null;
710 }
711 }
712 if (split.length == 1 && split[0] == null) {
Yasuhiro Matsuda48b9a7c2015-07-16 19:00:16 +0900713 return USB_FUNCTION_NONE;
Jeff Brown460a1462015-06-30 17:57:12 -0700714 }
715 StringBuilder builder = new StringBuilder();
716 for (int i = 0; i < split.length; i++) {
717 String s = split[i];
718 if (s != null) {
719 if (builder.length() > 0) {
720 builder.append(",");
721 }
722 builder.append(s);
723 }
724 }
725 return builder.toString();
726 }
727
728 /** @hide */
729 public static boolean containsFunction(String functions, String function) {
730 int index = functions.indexOf(function);
731 if (index < 0) return false;
732 if (index > 0 && functions.charAt(index - 1) != ',') return false;
733 int charAfter = index + function.length();
734 if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
735 return true;
736 }
Mike Lockwood24236072010-06-23 17:36:36 -0400737}