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