• 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 package com.android.tradefed.device;
18 
19 import com.android.ddmlib.IDevice;
20 import com.android.tradefed.result.InputStreamSource;
21 import com.android.tradefed.util.KeyguardControllerState;
22 
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 
30 /**
31  * Provides an reliable and slightly higher level API to a ddmlib {@link IDevice}.
32  * <p/>
33  * Retries device commands for a configurable amount, and provides a device recovery
34  * interface for devices which are unresponsive.
35  */
36 public interface ITestDevice extends INativeDevice {
37 
38     public enum RecoveryMode {
39         /** don't attempt to recover device. */
40         NONE,
41         /** recover device to online state only */
42         ONLINE,
43         /**
44          * Recover device into fully testable state - framework is up, and external storage is
45          * mounted.
46          */
47         AVAILABLE
48     }
49 
50     /**
51      * A simple struct class to store information about a single mountpoint
52      */
53     public static class MountPointInfo {
54         public String filesystem;
55         public String mountpoint;
56         public String type;
57         public List<String> options;
58 
59         /** Simple constructor */
MountPointInfo()60         public MountPointInfo() {}
61 
62         /**
63          * Convenience constructor to set all members
64          */
MountPointInfo(String filesystem, String mountpoint, String type, List<String> options)65         public MountPointInfo(String filesystem, String mountpoint, String type,
66                 List<String> options) {
67             this.filesystem = filesystem;
68             this.mountpoint = mountpoint;
69             this.type = type;
70             this.options = options;
71         }
72 
MountPointInfo(String filesystem, String mountpoint, String type, String optString)73         public MountPointInfo(String filesystem, String mountpoint, String type, String optString) {
74             this(filesystem, mountpoint, type, splitMountOptions(optString));
75         }
76 
splitMountOptions(String options)77         public static List<String> splitMountOptions(String options) {
78             List<String> list = Arrays.asList(options.split(","));
79             return list;
80         }
81 
82         @Override
toString()83         public String toString() {
84             return String.format("%s %s %s %s", this.filesystem, this.mountpoint, this.type,
85                     this.options);
86         }
87     }
88 
89     /** A simple struct class to store information about a single APEX */
90     public static class ApexInfo {
91         public final String name;
92         public final long versionCode;
93 
ApexInfo(String name, long versionCode)94         public ApexInfo(String name, long versionCode) {
95             this.name = name;
96             this.versionCode = versionCode;
97         }
98 
99         @Override
equals(Object other)100         public boolean equals(Object other) {
101             if (other != null && other instanceof ApexInfo) {
102                 ApexInfo ai = (ApexInfo) other;
103                 return name.equals(ai.name) && versionCode == ai.versionCode;
104             }
105             return false;
106         }
107 
108         @Override
hashCode()109         public int hashCode() {
110             // no need to consider versionCode here.
111             return name.hashCode();
112         }
113 
114         @Override
toString()115         public String toString() {
116             return "packageName: " + name + ", versionCode: " + versionCode;
117         }
118     }
119 
120     /**
121      * Install an Android package on device.
122      *
123      * @param packageFile the apk file to install
124      * @param reinstall <code>true</code> if a reinstall should be performed
125      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
126      *            available options.
127      * @return a {@link String} with an error code, or <code>null</code> if success.
128      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
129      *             recovered.
130      */
installPackage(File packageFile, boolean reinstall, String... extraArgs)131     public String installPackage(File packageFile, boolean reinstall, String... extraArgs)
132             throws DeviceNotAvailableException;
133 
134     /**
135      * Install an Android package on device.
136      * <p>Note: Only use cases that requires explicit control of granting runtime permission at
137      * install time should call this function.
138      * @param packageFile the apk file to install
139      * @param reinstall <code>true</code> if a reinstall should be performed
140      * @param grantPermissions if all runtime permissions should be granted at install time
141      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
142      *            available options.
143      * @return a {@link String} with an error code, or <code>null</code> if success.
144      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
145      *             recovered.
146      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
147      *         on device.
148      */
installPackage(File packageFile, boolean reinstall, boolean grantPermissions, String... extraArgs)149     public String installPackage(File packageFile, boolean reinstall, boolean grantPermissions,
150             String... extraArgs) throws DeviceNotAvailableException;
151 
152     /**
153      * Install an Android package on device for a given user.
154      *
155      * @param packageFile the apk file to install
156      * @param reinstall <code>true</code> if a reinstall should be performed
157      * @param userId the integer user id to install for.
158      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
159      *            available options.
160      * @return a {@link String} with an error code, or <code>null</code> if success.
161      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
162      *             recovered.
163      */
installPackageForUser(File packageFile, boolean reinstall, int userId, String... extraArgs)164     public String installPackageForUser(File packageFile, boolean reinstall, int userId,
165             String... extraArgs) throws DeviceNotAvailableException;
166 
167     /**
168      * Install an Android package on device for a given user.
169      * <p>Note: Only use cases that requires explicit control of granting runtime permission at
170      * install time should call this function.
171      * @param packageFile the apk file to install
172      * @param reinstall <code>true</code> if a reinstall should be performed
173      * @param grantPermissions if all runtime permissions should be granted at install time
174      * @param userId the integer user id to install for.
175      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
176      *            available options.
177      * @return a {@link String} with an error code, or <code>null</code> if success.
178      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
179      *             recovered.
180      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
181      *         on device.
182      */
installPackageForUser(File packageFile, boolean reinstall, boolean grantPermissions, int userId, String... extraArgs)183     public String installPackageForUser(File packageFile, boolean reinstall,
184             boolean grantPermissions, int userId, String... extraArgs)
185                     throws DeviceNotAvailableException;
186 
187     /**
188      * Uninstall an Android package from device.
189      *
190      * @param packageName the Android package to uninstall
191      * @return a {@link String} with an error code, or <code>null</code> if success.
192      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
193      *             recovered.
194      */
uninstallPackage(String packageName)195     public String uninstallPackage(String packageName) throws DeviceNotAvailableException;
196 
197     /**
198      * Install an Android application made of several APK files (one main and extra split packages).
199      * See "https://developer.android.com/studio/build/configure-apk-splits" on how to split
200      * apk to several files.
201      *
202      * @param packageFiles the local apk files
203      * @param reinstall <code>true</code> if a reinstall should be performed
204      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
205      *     available options.
206      * @return a {@link String} with an error code, or <code>null</code> if success.
207      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
208      *     recovered.
209      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
210      *     on device.
211      */
installPackages( List<File> packageFiles, boolean reinstall, String... extraArgs)212     public default String installPackages(
213             List<File> packageFiles, boolean reinstall, String... extraArgs)
214             throws DeviceNotAvailableException {
215         throw new UnsupportedOperationException("No support for Package Manager's features");
216     }
217 
218     /**
219      * Install an Android application made of several APK files (one main and extra split packages)
220      * that are sitting on the android device. See
221      * "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
222      * several files.
223      *
224      * <p>Note: Only use cases that requires explicit control of granting runtime permission at
225      * install time should call this function.
226      *
227      * @param packageFiles the remote apk file paths to install
228      * @param reinstall <code>true</code> if a reinstall should be performed
229      * @param grantPermissions if all runtime permissions should be granted at install time
230      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
231      *     available options.
232      * @return a {@link String} with an error code, or <code>null</code> if success.
233      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
234      *     recovered.
235      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
236      *     on device.
237      */
installPackages( List<File> packageFiles, boolean reinstall, boolean grantPermissions, String... extraArgs)238     public default String installPackages(
239             List<File> packageFiles,
240             boolean reinstall,
241             boolean grantPermissions,
242             String... extraArgs)
243             throws DeviceNotAvailableException {
244         throw new UnsupportedOperationException("No support for Package Manager's features");
245     }
246 
247     /**
248      * Install an Android application made of several APK files (one main and extra split packages)
249      * for a given user. See "https://developer.android.com/studio/build/configure-apk-splits" on
250      * how to split apk to several files.
251      *
252      * @param packageFiles the local apk files
253      * @param reinstall <code>true</code> if a reinstall should be performed
254      * @param userId the integer user id to install for.
255      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
256      *     available options.
257      * @return a {@link String} with an error code, or <code>null</code> if success.
258      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
259      *     recovered.
260      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
261      *     on device.
262      */
installPackagesForUser( List<File> packageFiles, boolean reinstall, int userId, String... extraArgs)263     public default String installPackagesForUser(
264             List<File> packageFiles, boolean reinstall, int userId, String... extraArgs)
265             throws DeviceNotAvailableException {
266         throw new UnsupportedOperationException("No support for Package Manager's features");
267     }
268 
269     /**
270      * Install an Android application made of several APK files (one main and extra split packages)
271      * for a given user. See "https://developer.android.com/studio/build/configure-apk-splits" on
272      * how to split apk to several files.
273      *
274      * <p>Note: Only use cases that requires explicit control of granting runtime permission at
275      * install time should call this function.
276      *
277      * @param packageFiles the local apk files
278      * @param reinstall <code>true</code> if a reinstall should be performed
279      * @param grantPermissions if all runtime permissions should be granted at install time
280      * @param userId the integer user id to install for.
281      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
282      *     available options.
283      * @return a {@link String} with an error code, or <code>null</code> if success.
284      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
285      *     recovered.
286      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
287      *     on device.
288      */
installPackagesForUser( List<File> packageFiles, boolean reinstall, boolean grantPermissions, int userId, String... extraArgs)289     public default String installPackagesForUser(
290             List<File> packageFiles,
291             boolean reinstall,
292             boolean grantPermissions,
293             int userId,
294             String... extraArgs)
295             throws DeviceNotAvailableException {
296         throw new UnsupportedOperationException("No support for Package Manager's features");
297     }
298 
299     /**
300      * Install an Android application made of several APK files (one main and extra split packages)
301      * that are sitting on the android device. See
302      * "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
303      * several files.
304      *
305      * <p>Note: Only use cases that requires explicit control of granting runtime permission at
306      * install time should call this function.
307      *
308      * @param remoteApkPaths the remote apk file paths
309      * @param reinstall <code>true</code> if a reinstall should be performed
310      * @param grantPermissions if all runtime permissions should be granted at install time
311      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
312      *     available options.
313      * @return a {@link String} with an error code, or <code>null</code> if success.
314      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
315      *     recovered.
316      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
317      *     on device.
318      */
installRemotePackages( List<String> remoteApkPaths, boolean reinstall, boolean grantPermissions, String... extraArgs)319     public default String installRemotePackages(
320             List<String> remoteApkPaths,
321             boolean reinstall,
322             boolean grantPermissions,
323             String... extraArgs)
324             throws DeviceNotAvailableException {
325         throw new UnsupportedOperationException("No support for Package Manager's features");
326     }
327 
328     /**
329      * Install an Android application made of several APK files (one main and extra split packages)
330      * that are sitting on the android device. See
331      * "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
332      * several files.
333      *
334      * @param remoteApkPaths the remote apk file paths
335      * @param reinstall <code>true</code> if a reinstall should be performed
336      * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
337      *     available options.
338      * @return a {@link String} with an error code, or <code>null</code> if success.
339      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
340      *     recovered.
341      * @throws UnsupportedOperationException if runtime permission is not supported by the platform
342      *     on device.
343      */
installRemotePackages( List<String> remoteApkPaths, boolean reinstall, String... extraArgs)344     public default String installRemotePackages(
345             List<String> remoteApkPaths, boolean reinstall, String... extraArgs)
346             throws DeviceNotAvailableException {
347         throw new UnsupportedOperationException("No support for Package Manager's features");
348     }
349 
350 
351     /**
352      * Grabs a screenshot from the device.
353      *
354      * @return a {@link InputStreamSource} of the screenshot in png format, or <code>null</code> if
355      *         the screenshot was not successful.
356      * @throws DeviceNotAvailableException
357      */
getScreenshot()358     public InputStreamSource getScreenshot() throws DeviceNotAvailableException;
359 
360     /**
361      * Grabs a screenshot from the device.
362      * Recommended to use getScreenshot(format) instead with JPEG encoding for smaller size
363      * @param format supported PNG, JPEG
364      * @return a {@link InputStreamSource} of the screenshot in format, or <code>null</code> if
365      *         the screenshot was not successful.
366      * @throws DeviceNotAvailableException
367      */
getScreenshot(String format)368     public InputStreamSource getScreenshot(String format) throws DeviceNotAvailableException;
369 
370     /**
371      * Grabs a screenshot from the device. Recommended to use {@link #getScreenshot(String)} instead
372      * with JPEG encoding for smaller size.
373      *
374      * @param format supported PNG, JPEG
375      * @param rescale if screenshot should be rescaled to reduce the size of resulting image
376      * @return a {@link InputStreamSource} of the screenshot in format, or <code>null</code> if the
377      *     screenshot was not successful.
378      * @throws DeviceNotAvailableException
379      */
getScreenshot(String format, boolean rescale)380     public InputStreamSource getScreenshot(String format, boolean rescale)
381             throws DeviceNotAvailableException;
382 
383     /**
384      * Grabs a screenshot from the device given display id. Format is PNG.
385      *
386      * <p>TODO: extend the implementations above to support 'format' and 'rescale'
387      *
388      * @param displayId the display id of the screen to get screenshot from.
389      * @return a {@link InputStreamSource} of the screenshot in format, or <code>null</code> if the
390      *     screenshot was not successful.
391      * @throws DeviceNotAvailableException
392      */
getScreenshot(int displayId)393     public InputStreamSource getScreenshot(int displayId) throws DeviceNotAvailableException;
394 
395     /**
396      * Clears the last connected wifi network. This should be called when starting a new invocation
397      * to avoid connecting to the wifi network used in the previous test after device reboots.
398      */
clearLastConnectedWifiNetwork()399     public void clearLastConnectedWifiNetwork();
400 
401     /**
402      * Connects to a wifi network.
403      * <p/>
404      * Turns on wifi and blocks until a successful connection is made to the specified wifi network.
405      * Once a connection is made, the instance will try to restore the connection after every reboot
406      * until {@link ITestDevice#disconnectFromWifi()} or
407      * {@link ITestDevice#clearLastConnectedWifiNetwork()} is called.
408      *
409      * @param wifiSsid the wifi ssid to connect to
410      * @param wifiPsk PSK passphrase or null if unencrypted
411      * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
412      *         otherwise
413      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
414      *             recovered.
415      */
connectToWifiNetwork(String wifiSsid, String wifiPsk)416     public boolean connectToWifiNetwork(String wifiSsid, String wifiPsk)
417             throws DeviceNotAvailableException;
418 
419     /**
420      * Connects to a wifi network.
421      * <p/>
422      * Turns on wifi and blocks until a successful connection is made to the specified wifi network.
423      * Once a connection is made, the instance will try to restore the connection after every reboot
424      * until {@link ITestDevice#disconnectFromWifi()} or
425      * {@link ITestDevice#clearLastConnectedWifiNetwork()} is called.
426      *
427      * @param wifiSsid the wifi ssid to connect to
428      * @param wifiPsk PSK passphrase or null if unencrypted
429      * @param scanSsid whether to scan for hidden SSID for this network.
430      * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
431      *         otherwise
432      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
433      *             recovered.
434      */
connectToWifiNetwork(String wifiSsid, String wifiPsk, boolean scanSsid)435     public boolean connectToWifiNetwork(String wifiSsid, String wifiPsk, boolean scanSsid)
436             throws DeviceNotAvailableException;
437 
438     /**
439      * A variant of {@link #connectToWifiNetwork(String, String)} that only connects if device
440      * currently does not have network connectivity.
441      *
442      * @param wifiSsid
443      * @param wifiPsk
444      * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
445      *         otherwise
446      * @throws DeviceNotAvailableException
447      */
connectToWifiNetworkIfNeeded(String wifiSsid, String wifiPsk)448     public boolean connectToWifiNetworkIfNeeded(String wifiSsid, String wifiPsk)
449             throws DeviceNotAvailableException;
450 
451     /**
452      * A variant of {@link #connectToWifiNetwork(String, String)} that only connects if device
453      * currently does not have network connectivity.
454      *
455      * @param wifiSsid
456      * @param wifiPsk
457      * @param scanSsid whether to scan for hidden SSID for this network
458      * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
459      *         otherwise
460      * @throws DeviceNotAvailableException
461      */
connectToWifiNetworkIfNeeded(String wifiSsid, String wifiPsk, boolean scanSsid)462     public boolean connectToWifiNetworkIfNeeded(String wifiSsid, String wifiPsk, boolean scanSsid)
463             throws DeviceNotAvailableException;
464 
465     /**
466      * Disconnects from a wifi network.
467      * <p/>
468      * Removes all networks from known networks list and disables wifi.
469      *
470      * @return <code>true</code> if disconnected from wifi network successfully. <code>false</code>
471      *         if disconnect failed.
472      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
473      *             recovered.
474      */
disconnectFromWifi()475     public boolean disconnectFromWifi() throws DeviceNotAvailableException;
476 
477     /**
478      * Test if wifi is enabled.
479      * <p/>
480      * Checks if wifi is enabled on device. Useful for asserting wifi status before tests that
481      * shouldn't run with wifi, e.g. mobile data tests.
482      *
483      * @return <code>true</code> if wifi is enabled. <code>false</code> if disabled
484      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
485      *             recovered.
486      */
isWifiEnabled()487     public boolean isWifiEnabled() throws DeviceNotAvailableException;
488 
489     /**
490      * Gets the device's IP address.
491      *
492      * @return the device's IP address, or <code>null</code> if device has no IP address
493      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
494      *             recovered.
495      */
getIpAddress()496     public String getIpAddress() throws DeviceNotAvailableException;
497 
498     /**
499      * Enables network monitoring on device.
500      *
501      * @return <code>true</code> if monitoring is enabled successfully. <code>false</code>
502      *         if it failed.
503      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
504      *             recovered.
505      */
enableNetworkMonitor()506     public boolean enableNetworkMonitor() throws DeviceNotAvailableException;
507 
508     /**
509      * Disables network monitoring on device.
510      *
511      * @return <code>true</code> if monitoring is disabled successfully. <code>false</code>
512      *         if it failed.
513      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
514      *             recovered.
515      */
disableNetworkMonitor()516     public boolean disableNetworkMonitor() throws DeviceNotAvailableException;
517 
518     /**
519      * Check that device has network connectivity.
520      *
521      * @return <code>true</code> if device has a working network connection,
522      *          <code>false</code> overwise.
523      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
524      *          recovered.
525      */
checkConnectivity()526     public boolean checkConnectivity() throws DeviceNotAvailableException;
527 
528     /**
529      * Attempt to dismiss any error dialogs currently displayed on device UI.
530      *
531      * @return <code>true</code> if no dialogs were present or dialogs were successfully cleared.
532      *         <code>false</code> otherwise.
533      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
534      *             recovered.
535      */
clearErrorDialogs()536     public boolean clearErrorDialogs() throws DeviceNotAvailableException;
537 
538     /**
539      * Return an object to get the current state of the keyguard or null if not supported.
540      *
541      * @return a {@link KeyguardControllerState} containing a snapshot of the state of the keyguard
542      *     and returns Null if the Keyguard query is not supported.
543      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
544      *     recovered.
545      */
getKeyguardState()546     public KeyguardControllerState getKeyguardState() throws DeviceNotAvailableException;
547 
548     /**
549      * Fetch the test options for the device.
550      *
551      * @return {@link TestDeviceOptions} related to the device under test.
552      */
getOptions()553     public TestDeviceOptions getOptions();
554 
555     /**
556      * Fetch the application package names present on the device.
557      *
558      * @return {@link Set} of {@link String} package names currently installed on the device.
559      * @throws DeviceNotAvailableException
560      */
getInstalledPackageNames()561     public Set<String> getInstalledPackageNames() throws DeviceNotAvailableException;
562 
563     /**
564      * Query the device for a given package name to check if it's currently installed or not.
565      *
566      * @return True if the package is reported as installed. False otherwise.
567      * @throws DeviceNotAvailableException
568      */
isPackageInstalled(String packageName)569     public boolean isPackageInstalled(String packageName) throws DeviceNotAvailableException;
570 
571     /**
572      * Query the device for a given package name and given user id to check if it's currently
573      * installed or not for that user.
574      *
575      * @param packageName the package we are checking if it's installed.
576      * @param userId The user id we are checking the package is installed for. If null, primary user
577      *     zero will be used.
578      * @return True if the package is reported as installed. False otherwise.
579      * @throws DeviceNotAvailableException
580      */
isPackageInstalled(String packageName, String userId)581     public boolean isPackageInstalled(String packageName, String userId)
582             throws DeviceNotAvailableException;
583 
584     /**
585      * Fetch the information about APEXes activated on the device.
586      *
587      * @return {@link Set} of {@link ApexInfo} currently activated on the device
588      * @throws DeviceNotAvailableException
589      */
getActiveApexes()590     public Set<ApexInfo> getActiveApexes() throws DeviceNotAvailableException;
591 
592     /**
593      * Fetch the application package names that can be uninstalled. This is presently defined as
594      * non-system packages, and updated system packages.
595      *
596      * @return {@link Set} of uninstallable {@link String} package names currently installed on the
597      *         device.
598      * @throws DeviceNotAvailableException
599      */
getUninstallablePackageNames()600     public Set<String> getUninstallablePackageNames() throws DeviceNotAvailableException;
601 
602     /**
603      * Fetch information about a package installed on device.
604      *
605      * @return the {@link PackageInfo} or <code>null</code> if information could not be retrieved
606      * @throws DeviceNotAvailableException
607      */
getAppPackageInfo(String packageName)608     public PackageInfo getAppPackageInfo(String packageName) throws DeviceNotAvailableException;
609 
610     /**
611      * Determines if multi user is supported.
612      *
613      * @return true if multi user is supported, false otherwise
614      * @throws DeviceNotAvailableException
615      */
isMultiUserSupported()616     public boolean isMultiUserSupported() throws DeviceNotAvailableException;
617 
618     /**
619      * Create a user with a given name and default flags 0.
620      *
621      * @param name of the user to create on the device
622      * @return the integer for the user id created
623      * @throws DeviceNotAvailableException
624      */
createUser(String name)625     public int createUser(String name) throws DeviceNotAvailableException, IllegalStateException;
626 
627     /**
628      * Create a user with a given name and default flags 0.
629      *
630      * @param name of the user to create on the device
631      * @return the integer for the user id created or -1 for error.
632      * @throws DeviceNotAvailableException
633      */
createUserNoThrow(String name)634     public int createUserNoThrow(String name) throws DeviceNotAvailableException;
635 
636     /**
637      * Create a user with a given name and the provided flags
638      *
639      * @param name of the user to create on the device
640      * @param guest enable the user flag --guest during creation
641      * @param ephemeral enable the user flag --ephemeral during creation
642      * @return id of the created user
643      * @throws DeviceNotAvailableException
644      */
createUser(String name, boolean guest, boolean ephemeral)645     public int createUser(String name, boolean guest, boolean ephemeral)
646             throws DeviceNotAvailableException, IllegalStateException;
647 
648     /**
649      * Remove a given user from the device.
650      *
651      * @param userId of the user to remove
652      * @return true if we were successful in removing the user, false otherwise.
653      * @throws DeviceNotAvailableException
654      */
removeUser(int userId)655     public boolean removeUser(int userId) throws DeviceNotAvailableException;
656 
657     /**
658      * Gets the list of users on the device. Will throw {@link DeviceRuntimeException} if output
659      * from device is not as expected.
660      *
661      * @return the list of user ids.
662      * @throws DeviceNotAvailableException
663      * @throws DeviceRuntimeException
664      */
listUsers()665     ArrayList<Integer> listUsers() throws DeviceNotAvailableException;
666 
667     /**
668      * Get the maximum number of supported users. Defaults to 0.
669      *
670      * @return an integer indicating the number of supported users
671      * @throws DeviceNotAvailableException
672      */
getMaxNumberOfUsersSupported()673     public int getMaxNumberOfUsersSupported() throws DeviceNotAvailableException;
674 
675     /**
676      * Get the maximum number of supported simultaneously running users. Defaults to 0.
677      *
678      * @return an integer indicating the number of simultaneously running users
679      * @throws DeviceNotAvailableException
680      */
getMaxNumberOfRunningUsersSupported()681     public int getMaxNumberOfRunningUsersSupported() throws DeviceNotAvailableException;
682 
683     /**
684      * Starts a given user in the background if it is currently stopped. If the user is already
685      * running in the background, this method is a NOOP.
686      * @param userId of the user to start in the background
687      * @return true if the user was successfully started in the background.
688      * @throws DeviceNotAvailableException
689      */
startUser(int userId)690     public boolean startUser(int userId) throws DeviceNotAvailableException;
691 
692     /**
693      * Starts a given user in the background if it is currently stopped. If the user is already
694      * running in the background, this method is a NOOP. Possible to provide extra flag to wait for
695      * the operation to have effect.
696      *
697      * @param userId of the user to start in the background
698      * @param waitFlag will make the command wait until user is started and unlocked.
699      * @return true if the user was successfully started in the background.
700      * @throws DeviceNotAvailableException
701      */
startUser(int userId, boolean waitFlag)702     public boolean startUser(int userId, boolean waitFlag) throws DeviceNotAvailableException;
703 
704     /**
705      * Stops a given user. If the user is already stopped, this method is a NOOP.
706      * Cannot stop current and system user.
707      *
708      * @param userId of the user to stop.
709      * @return true if the user was successfully stopped.
710      * @throws DeviceNotAvailableException
711      */
stopUser(int userId)712     public boolean stopUser(int userId) throws DeviceNotAvailableException;
713 
714     /**
715      * Stop a given user. Possible to provide extra flags to wait for the operation to have effect,
716      * and force terminate the user. Cannot stop current and system user.
717      *
718      * @param userId of the user to stop.
719      * @param waitFlag will make the command wait until user is stopped.
720      * @param forceFlag will force stop the user.
721      * @return true if the user was successfully stopped.
722      * @throws DeviceNotAvailableException
723      */
stopUser(int userId, boolean waitFlag, boolean forceFlag)724     public boolean stopUser(int userId, boolean waitFlag, boolean forceFlag)
725             throws DeviceNotAvailableException;
726 
727     /**
728      * Returns the primary user id.
729      *
730      * @return the userId of the primary user if there is one, and null if there is no primary user.
731      * @throws DeviceNotAvailableException
732      * @throws DeviceRuntimeException if the output from the device is not as expected.
733      */
getPrimaryUserId()734     public Integer getPrimaryUserId() throws DeviceNotAvailableException;
735 
736     /**
737      * Return the id of the current running user.
738      *
739      * @throws DeviceNotAvailableException
740      */
getCurrentUser()741     public int getCurrentUser() throws DeviceNotAvailableException, DeviceRuntimeException;
742 
743     /**
744      * Find and return the flags of a given user.
745      * Flags are defined in "android.content.pm.UserInfo" class in Android Open Source Project.
746      *
747      * @return the flags associated with the userId provided if found, -10000 in any other cases.
748      * @throws DeviceNotAvailableException
749      */
getUserFlags(int userId)750     public int getUserFlags(int userId) throws DeviceNotAvailableException;
751 
752     /**
753      * Return whether the specified user is a secondary user according to it's flags.
754      *
755      * @return true if the user is secondary, false otherwise.
756      * @throws DeviceNotAvailableException
757      */
isUserSecondary(int userId)758     public boolean isUserSecondary(int userId) throws DeviceNotAvailableException;
759 
760     /**
761      * Return the serial number associated to the userId if found, -10000 in any other cases.
762      *
763      * @throws DeviceNotAvailableException
764      */
getUserSerialNumber(int userId)765     public int getUserSerialNumber(int userId) throws DeviceNotAvailableException;
766 
767     /**
768      * Switch to another userId with a default timeout. {@link #switchUser(int, long)}.
769      *
770      * @return True if the new userId matches the userId provider. False otherwise.
771      * @throws DeviceNotAvailableException
772      */
switchUser(int userId)773     public boolean switchUser(int userId) throws DeviceNotAvailableException;
774 
775     /**
776      * Switch to another userId with the provided timeout as deadline.
777      * Attempt to disable keyguard after user change is successful.
778      *
779      * @param timeout to wait before returning false for switch-user failed.
780      * @return True if the new userId matches the userId provider. False otherwise.
781      * @throws DeviceNotAvailableException
782      */
switchUser(int userId, long timeout)783     public boolean switchUser(int userId, long timeout) throws DeviceNotAvailableException;
784 
785     /**
786      * Check if a given user is running.
787      *
788      * @return True if the user is running, false in every other cases.
789      * @throws DeviceNotAvailableException
790      */
isUserRunning(int userId)791     public boolean isUserRunning(int userId) throws DeviceNotAvailableException;
792 
793     /**
794      * Check if a feature is available on a device.
795      *
796      * @param feature which format should be "feature:<name>".
797      * @return True if feature is found, false otherwise.
798      * @throws DeviceNotAvailableException
799      */
hasFeature(String feature)800     public boolean hasFeature(String feature) throws DeviceNotAvailableException;
801 
802     /**
803      * See {@link #getSetting(int, String, String)} and performed on system user.
804      *
805      * @throws DeviceNotAvailableException
806      */
getSetting(String namespace, String key)807     public String getSetting(String namespace, String key) throws DeviceNotAvailableException;
808 
809     /**
810      * Return the value of the requested setting.
811      * namespace must be one of: {"system", "secure", "global"}
812      *
813      * @return the value associated with the namespace:key of a user. Null if not found.
814      * @throws DeviceNotAvailableException
815      */
getSetting(int userId, String namespace, String key)816     public String getSetting(int userId, String namespace, String key)
817             throws DeviceNotAvailableException;
818 
819     /**
820      * Return key value pairs of requested namespace.
821      *
822      * @param namespace must be one of {"system", "secure", "global"}
823      * @return the map of key value pairs. Null if namespace is not supported.
824      * @throws DeviceNotAvailableException
825      */
getAllSettings(String namespace)826     public Map<String, String> getAllSettings(String namespace) throws DeviceNotAvailableException;
827 
828     /**
829      * See {@link #setSetting(int, String, String, String)} and performed on system user.
830      *
831      * @throws DeviceNotAvailableException
832      */
setSetting(String namespace, String key, String value)833     public void setSetting(String namespace, String key, String value)
834             throws DeviceNotAvailableException;
835 
836     /**
837      * Add a setting value to the namespace of a given user. Some settings will only be available
838      * after a reboot.
839      * namespace must be one of: {"system", "secure", "global"}
840      *
841      * @throws DeviceNotAvailableException
842      */
setSetting(int userId, String namespace, String key, String value)843     public void setSetting(int userId, String namespace, String key, String value)
844             throws DeviceNotAvailableException;
845 
846     /**
847      * Find and return the android-id associated to a userId, null if not found.
848      *
849      * @throws DeviceNotAvailableException
850      */
getAndroidId(int userId)851     public String getAndroidId(int userId) throws DeviceNotAvailableException;
852 
853     /**
854      * Create a Map of android ids found matching user ids. There is no insurance that each user
855      * id will found an android id associated in this function so some user ids may match null.
856      *
857      * @return Map of android ids found matching user ids.
858      * @throws DeviceNotAvailableException
859      */
getAndroidIds()860     public Map<Integer, String> getAndroidIds() throws DeviceNotAvailableException;
861 
862     /**
863      * Set a device admin component as device owner in given user.
864      *
865      * @param componentName of device admin to be device owner.
866      * @param userId of the user that the device owner lives in.
867      * @return True if it is successful, false otherwise.
868      * @throws DeviceNotAvailableException
869      */
setDeviceOwner(String componentName, int userId)870     public boolean setDeviceOwner(String componentName, int userId)
871             throws DeviceNotAvailableException;
872 
873     /**
874      * Remove given device admin in given user and return {@code true} if it is successful, {@code
875      * false} otherwise.
876      *
877      * @param componentName of device admin to be removed.
878      * @param userId of user that the device admin lives in.
879      * @return True if it is successful, false otherwise.
880      * @throws DeviceNotAvailableException
881      */
removeAdmin(String componentName, int userId)882     public boolean removeAdmin(String componentName, int userId) throws DeviceNotAvailableException;
883 
884     /**
885      * Remove all existing device profile owners with the best effort.
886      *
887      * @throws DeviceNotAvailableException
888      */
removeOwners()889     public void removeOwners() throws DeviceNotAvailableException;
890 
891     /**
892      * Attempts to disable the keyguard.
893      * <p>
894      * First wait for the input dispatch to become ready, this happens around the same time when the
895      * device reports BOOT_COMPLETE, apparently asynchronously, because current framework
896      * implementation has occasional race condition. Then command is sent to dismiss keyguard (works
897      * on non-secure ones only)
898      */
disableKeyguard()899     public void disableKeyguard() throws DeviceNotAvailableException;
900 
901     /**
902      * Attempt to dump the heap from the system_server. It is the caller responsibility to clean up
903      * the dumped file.
904      *
905      * @param process the name of the device process to dumpheap on.
906      * @param devicePath the path on the device where to put the dump. This must be a location where
907      *     permissions allow it.
908      * @return the {@link File} containing the report. Null if something failed.
909      * @throws DeviceNotAvailableException
910      */
dumpHeap(String process, String devicePath)911     public File dumpHeap(String process, String devicePath) throws DeviceNotAvailableException;
912 
913     /**
914      * Collect the list of available displays id on the device as reported by "dumpsys
915      * SurfaceFlinger".
916      *
917      * @return The list of displays. Default always returns the default display 0.
918      * @throws DeviceNotAvailableException
919      */
listDisplayIds()920     public Set<Integer> listDisplayIds() throws DeviceNotAvailableException;
921 }
922