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