1 /* 2 * Copyright (C) 2016 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 package com.android.tradefed.device; 17 18 import com.android.ddmlib.IDevice; 19 import com.android.ddmlib.IShellOutputReceiver; 20 import com.android.ddmlib.Log.LogLevel; 21 import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner; 22 import com.android.tradefed.build.IBuildInfo; 23 import com.android.tradefed.command.remote.DeviceDescriptor; 24 import com.android.tradefed.device.ITestDevice.MountPointInfo; 25 import com.android.tradefed.device.ITestDevice.RecoveryMode; 26 import com.android.tradefed.log.ITestLogger; 27 import com.android.tradefed.result.ITestLifeCycleReceiver; 28 import com.android.tradefed.result.InputStreamSource; 29 import com.android.tradefed.targetprep.TargetSetupError; 30 import com.android.tradefed.util.Bugreport; 31 import com.android.tradefed.util.CommandResult; 32 import com.android.tradefed.util.ProcessInfo; 33 import com.android.tradefed.util.TimeUtil; 34 35 import com.google.errorprone.annotations.MustBeClosed; 36 37 import java.io.File; 38 import java.io.InputStream; 39 import java.util.Collection; 40 import java.util.Date; 41 import java.util.List; 42 import java.util.concurrent.TimeUnit; 43 44 /** 45 * Provides an reliable and slightly higher level API to a ddmlib {@link IDevice}. 46 * <p/> 47 * Retries device commands for a configurable amount, and provides a device recovery 48 * interface for devices which are unresponsive. 49 */ 50 public interface INativeDevice { 51 52 /** 53 * Default value when API Level cannot be detected 54 */ 55 public final static int UNKNOWN_API_LEVEL = -1; 56 57 /** 58 * Set the {@link TestDeviceOptions} for the device 59 */ 60 public void setOptions(TestDeviceOptions options); 61 62 /** 63 * Returns a reference to the associated ddmlib {@link IDevice}. 64 * <p/> 65 * A new {@link IDevice} may be allocated by DDMS each time the device disconnects and 66 * reconnects from adb. Thus callers should not keep a reference to the {@link IDevice}, 67 * because that reference may become stale. 68 * 69 * @return the {@link IDevice} 70 */ 71 public IDevice getIDevice(); 72 73 /** 74 * Convenience method to get serial number of this device. 75 * 76 * @return the {@link String} serial number 77 */ 78 public String getSerialNumber(); 79 80 /** 81 * Retrieve the given property value from the device. 82 * 83 * @param name the property name 84 * @return the property value or <code>null</code> if it does not exist 85 * @throws DeviceNotAvailableException 86 */ 87 public String getProperty(String name) throws DeviceNotAvailableException; 88 89 /** 90 * Convenience method to get the bootloader version of this device. 91 * <p/> 92 * Will attempt to retrieve bootloader version from the device's current state. (ie if device 93 * is in fastboot mode, it will attempt to retrieve version from fastboot) 94 * 95 * @return the {@link String} bootloader version or <code>null</code> if it cannot be found 96 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 97 * recovered. 98 */ 99 public String getBootloaderVersion() throws DeviceNotAvailableException; 100 101 /** 102 * Convenience method to get baseband (radio) version of this device. Getting the radio version 103 * is device specific, so it might not return the correct information for all devices. This 104 * method relies on the gsm.version.baseband propery to return the correct version information. 105 * This is not accurate for some CDMA devices and the version returned here might not match 106 * the version reported from fastboot and might not return the version for the CDMA radio. 107 * TL;DR this method only reports accurate version if the gsm.version.baseband property is the 108 * same as the version returned by <code>fastboot getvar version-baseband</code>. 109 * 110 * @return the {@link String} baseband version or <code>null</code> if it cannot be determined 111 * (device has no radio or version string cannot be read) 112 * @throws DeviceNotAvailableException if the connection with the device is lost and cannot 113 * be recovered. 114 */ 115 public String getBasebandVersion() throws DeviceNotAvailableException; 116 117 /** 118 * Convenience method to get the product type of this device. 119 * <p/> 120 * This method will work if device is in either adb or fastboot mode. 121 * 122 * @return the {@link String} product type name. Will not be null 123 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 124 * recovered, or if product type can not be determined 125 */ 126 public String getProductType() throws DeviceNotAvailableException; 127 128 /** 129 * Convenience method to get the product variant of this device. 130 * <p/> 131 * This method will work if device is in either adb or fastboot mode. 132 * 133 * @return the {@link String} product variant name or <code>null</code> if it cannot be 134 * determined 135 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 136 * recovered. 137 */ 138 public String getProductVariant() throws DeviceNotAvailableException; 139 140 /** 141 * Convenience method to get the product type of this device when its in fastboot mode. 142 * <p/> 143 * This method should only be used if device should be in fastboot. Its a bit safer variant 144 * than the generic {@link #getProductType()} method in this case, because ITestDevice 145 * will know to recover device into fastboot if device is in incorrect state or is 146 * unresponsive. 147 * 148 * @return the {@link String} product type name or <code>null</code> if it cannot be determined 149 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 150 * recovered. 151 */ 152 public String getFastbootProductType() throws DeviceNotAvailableException; 153 154 /** 155 * Convenience method to get the product type of this device when its in fastboot mode. 156 * <p/> 157 * This method should only be used if device should be in fastboot. Its a bit safer variant 158 * than the generic {@link #getProductType()} method in this case, because ITestDevice 159 * will know to recover device into fastboot if device is in incorrect state or is 160 * unresponsive. 161 * 162 * @return the {@link String} product type name or <code>null</code> if it cannot be determined 163 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 164 * recovered. 165 */ 166 public String getFastbootProductVariant() throws DeviceNotAvailableException; 167 168 /** 169 * Retrieve the alias of the build that the device is currently running. 170 * 171 * <p>Build alias is usually a more readable string than build id (typically a number for 172 * Nexus builds). For example, final Android 4.2 release has build alias JDQ39, and build id 173 * 573038 174 * @return the build alias or fall back to build id if it could not be retrieved 175 * @throws DeviceNotAvailableException 176 */ 177 public String getBuildAlias() throws DeviceNotAvailableException; 178 179 /** 180 * Retrieve the build the device is currently running. 181 * 182 * @return the build id or {@link IBuildInfo#UNKNOWN_BUILD_ID} if it could not be retrieved 183 * @throws DeviceNotAvailableException 184 */ 185 public String getBuildId() throws DeviceNotAvailableException; 186 187 /** 188 * Retrieve the build flavor for the device. 189 * 190 * @return the build flavor or null if it could not be retrieved 191 * @throws DeviceNotAvailableException 192 */ 193 public String getBuildFlavor() throws DeviceNotAvailableException; 194 195 /** 196 * Executes the given adb shell command, retrying multiple times if command fails. 197 * <p/> 198 * A simpler form of 199 * {@link #executeShellCommand(String, IShellOutputReceiver, long, TimeUnit, int)} with 200 * default values. 201 * 202 * @param command the adb shell command to run 203 * @param receiver the {@link IShellOutputReceiver} to direct shell output to. 204 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 205 * recovered. 206 */ 207 public void executeShellCommand(String command, IShellOutputReceiver receiver) 208 throws DeviceNotAvailableException; 209 210 /** 211 * Executes a adb shell command, with more parameters to control command behavior. 212 * 213 * @see #executeShellCommand(String, IShellOutputReceiver) 214 * @param command the adb shell command to run 215 * @param receiver the {@link IShellOutputReceiver} to direct shell output to. 216 * @param maxTimeToOutputShellResponse the maximum amount of time during which the command is 217 * allowed to not output any response; unit as specified in <code>timeUnit</code> 218 * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code> 219 * @param retryAttempts the maximum number of times to retry command if it fails due to a 220 * exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var> 221 * are performed without success. 222 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 223 * recovered. 224 * @see TimeUtil 225 */ 226 public void executeShellCommand(String command, IShellOutputReceiver receiver, 227 long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts) 228 throws DeviceNotAvailableException; 229 230 /** 231 * Executes a adb shell command, with more parameters to control command behavior. 232 * 233 * @see #executeShellCommand(String, IShellOutputReceiver) 234 * @param command the adb shell command to run 235 * @param receiver the {@link IShellOutputReceiver} to direct shell output to. 236 * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as 237 * specified in <code>timeUnit</code> 238 * @param maxTimeToOutputShellResponse the maximum amount of time during which the command is 239 * allowed to not output any response; unit as specified in <code>timeUnit</code> 240 * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code> 241 * @param retryAttempts the maximum number of times to retry command if it fails due to a 242 * exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var> are 243 * performed without success. 244 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 245 * recovered. 246 * @see TimeUtil 247 */ 248 public void executeShellCommand( 249 String command, 250 IShellOutputReceiver receiver, 251 long maxTimeoutForCommand, 252 long maxTimeToOutputShellResponse, 253 TimeUnit timeUnit, 254 int retryAttempts) 255 throws DeviceNotAvailableException; 256 257 /** 258 * Helper method which executes a adb shell command and returns output as a {@link String}. 259 * 260 * @param command the adb shell command to run 261 * @return the shell output 262 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 263 * recovered. 264 */ 265 public String executeShellCommand(String command) throws DeviceNotAvailableException; 266 267 /** 268 * Helper method which executes a adb shell command and returns the results as a {@link 269 * CommandResult} properly populated with the command status output, stdout and stderr. 270 * 271 * @param command The command that should be run. 272 * @return The result in {@link CommandResult}. 273 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 274 * recovered. 275 */ 276 public CommandResult executeShellV2Command(String command) throws DeviceNotAvailableException; 277 278 /** 279 * Executes a adb shell command, with more parameters to control command behavior. 280 * 281 * @see #executeShellV2Command(String) 282 * @param command the adb shell command to run 283 * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as 284 * specified in <code>timeUnit</code> 285 * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code> 286 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 287 * recovered. 288 * @see TimeUtil 289 */ 290 public CommandResult executeShellV2Command( 291 String command, final long maxTimeoutForCommand, final TimeUnit timeUnit) 292 throws DeviceNotAvailableException; 293 294 /** 295 * Executes a adb shell command, with more parameters to control command behavior. 296 * 297 * @see #executeShellV2Command(String) 298 * @param command the adb shell command to run 299 * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as 300 * specified in <code>timeUnit</code> 301 * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code> 302 * @param retryAttempts the maximum number of times to retry command if it fails due to a 303 * exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var> are 304 * performed without success. 305 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 306 * recovered. 307 * @see TimeUtil 308 */ 309 public CommandResult executeShellV2Command( 310 String command, 311 final long maxTimeoutForCommand, 312 final TimeUnit timeUnit, 313 int retryAttempts) 314 throws DeviceNotAvailableException; 315 316 /** 317 * Helper method which executes a adb command as a system command. 318 * <p/> 319 * {@link #executeShellCommand(String)} should be used instead wherever possible, as that 320 * method provides better failure detection and performance. 321 * 322 * @param commandArgs the adb command and arguments to run 323 * @return the stdout from command. <code>null</code> if command failed to execute. 324 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 325 * recovered. 326 */ 327 public String executeAdbCommand(String... commandArgs) throws DeviceNotAvailableException; 328 329 /** 330 * Helper method which executes a fastboot command as a system command with a default timeout 331 * of 2 minutes. 332 * <p/> 333 * Expected to be used when device is already in fastboot mode. 334 * 335 * @param commandArgs the fastboot command and arguments to run 336 * @return the CommandResult containing output of command 337 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 338 * recovered. 339 */ 340 public CommandResult executeFastbootCommand(String... commandArgs) 341 throws DeviceNotAvailableException; 342 343 /** 344 * Helper method which executes a fastboot command as a system command. 345 * <p/> 346 * Expected to be used when device is already in fastboot mode. 347 * 348 * @param timeout the time in milliseconds before the command expire 349 * @param commandArgs the fastboot command and arguments to run 350 * @return the CommandResult containing output of command 351 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 352 * recovered. 353 */ 354 public CommandResult executeFastbootCommand(long timeout, String... commandArgs) 355 throws DeviceNotAvailableException; 356 357 /** 358 * Helper method which executes a long running fastboot command as a system command. 359 * <p/> 360 * Identical to {@link #executeFastbootCommand(String...)} except uses a longer timeout. 361 * 362 * @param commandArgs the fastboot command and arguments to run 363 * @return the CommandResult containing output of command 364 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 365 * recovered. 366 */ 367 public CommandResult executeLongFastbootCommand(String... commandArgs) 368 throws DeviceNotAvailableException; 369 370 /** 371 * Get whether to use fastboot erase or fastboot format to wipe a partition on the device. 372 * 373 * @return {@code true} if fastboot erase will be used or {@code false} if fastboot format will 374 * be used. 375 * @see #fastbootWipePartition(String) 376 */ 377 public boolean getUseFastbootErase(); 378 379 /** 380 * Set whether to use fastboot erase or fastboot format to wipe a partition on the device. 381 * 382 * @param useFastbootErase {@code true} if fastboot erase should be used or {@code false} if 383 * fastboot format should be used. 384 * @see #fastbootWipePartition(String) 385 */ 386 public void setUseFastbootErase(boolean useFastbootErase); 387 388 /** 389 * Helper method which wipes a partition for the device. 390 * <p/> 391 * If {@link #getUseFastbootErase()} is {@code true}, then fastboot erase will be used to wipe 392 * the partition. The device must then create a filesystem the next time the device boots. 393 * Otherwise, fastboot format is used which will create a new filesystem on the device. 394 * <p/> 395 * Expected to be used when device is already in fastboot mode. 396 * 397 * @param partition the partition to wipe 398 * @return the CommandResult containing output of command 399 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 400 * recovered. 401 */ 402 public CommandResult fastbootWipePartition(String partition) throws DeviceNotAvailableException; 403 404 /** 405 * Runs instrumentation tests, and provides device recovery. 406 * 407 * <p>If connection with device is lost before test run completes, and recovery succeeds, all 408 * listeners will be informed of testRunFailed and "false" will be returned. The test command 409 * will not be rerun. It is left to callers to retry if necessary. 410 * 411 * <p>If connection with device is lost before test run completes, and recovery fails, all 412 * listeners will be informed of testRunFailed and DeviceNotAvailableException will be thrown. 413 * 414 * @param runner the {@link IRemoteAndroidTestRunner} which runs the tests 415 * @param listeners the test result listeners 416 * @return <code>true</code> if test command completed. <code>false</code> if it failed to 417 * complete due to device communication exception, but recovery succeeded 418 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 419 * recovered. ie test command failed to complete and recovery failed. 420 */ 421 public boolean runInstrumentationTests( 422 IRemoteAndroidTestRunner runner, Collection<ITestLifeCycleReceiver> listeners) 423 throws DeviceNotAvailableException; 424 425 /** 426 * Convenience method for performing {@link #runInstrumentationTests(IRemoteAndroidTestRunner, 427 * Collection)} with one or more listeners passed as parameters. 428 * 429 * @param runner the {@link IRemoteAndroidTestRunner} which runs the tests 430 * @param listeners the test result listener(s) 431 * @return <code>true</code> if test command completed. <code>false</code> if it failed to 432 * complete, but recovery succeeded 433 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 434 * recovered. ie test command failed to complete and recovery failed. 435 */ 436 public boolean runInstrumentationTests( 437 IRemoteAndroidTestRunner runner, ITestLifeCycleReceiver... listeners) 438 throws DeviceNotAvailableException; 439 440 /** 441 * Same as {@link ITestDevice#runInstrumentationTests(IRemoteAndroidTestRunner, Collection)} but 442 * runs the test for the given user. 443 */ 444 public boolean runInstrumentationTestsAsUser( 445 IRemoteAndroidTestRunner runner, 446 int userId, 447 Collection<ITestLifeCycleReceiver> listeners) 448 throws DeviceNotAvailableException; 449 450 /** 451 * Same as {@link ITestDevice#runInstrumentationTests(IRemoteAndroidTestRunner, 452 * ITestLifeCycleReceiver...)} but runs the test for a given user. 453 */ 454 public boolean runInstrumentationTestsAsUser( 455 IRemoteAndroidTestRunner runner, int userId, ITestLifeCycleReceiver... listeners) 456 throws DeviceNotAvailableException; 457 458 /** 459 * Check whether platform on device supports runtime permission granting 460 * @return True if runtime permission are supported, false otherwise. 461 * @throws DeviceNotAvailableException 462 */ 463 public boolean isRuntimePermissionSupported() throws DeviceNotAvailableException; 464 465 /** 466 * Retrieves a file off device. 467 * 468 * @param remoteFilePath the absolute path to file on device. 469 * @param localFile the local file to store contents in. If non-empty, contents will be 470 * replaced. 471 * @return <code>true</code> if file was retrieved successfully. <code>false</code> otherwise. 472 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 473 * recovered. 474 */ 475 public boolean pullFile(String remoteFilePath, File localFile) 476 throws DeviceNotAvailableException; 477 478 /** 479 * Retrieves a file off device, stores it in a local temporary {@link File}, and returns that 480 * {@code File}. 481 * 482 * @param remoteFilePath the absolute path to file on device. 483 * @return A {@link File} containing the contents of the device file, or {@code null} if the 484 * copy failed for any reason (including problems with the host filesystem) 485 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 486 * recovered. 487 */ 488 public File pullFile(String remoteFilePath) throws DeviceNotAvailableException; 489 490 /** 491 * Retrieves a file off device, and returns the contents. 492 * 493 * @param remoteFilePath the absolute path to file on device. 494 * @return A {@link String} containing the contents of the device file, or {@code null} if the 495 * copy failed for any reason (including problems with the host filesystem) 496 */ 497 public String pullFileContents(String remoteFilePath) throws DeviceNotAvailableException; 498 499 /** 500 * A convenience method to retrieve a file from the device's external storage, stores it in a 501 * local temporary {@link File}, and return a reference to that {@code File}. 502 * 503 * @param remoteFilePath the path to file on device, relative to the device's external storage 504 * mountpoint 505 * @return A {@link File} containing the contents of the device file, or {@code null} if the 506 * copy failed for any reason (including problems with the host filesystem) 507 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 508 * recovered. 509 */ 510 public File pullFileFromExternal(String remoteFilePath) throws DeviceNotAvailableException; 511 512 /** 513 * Recursively pull directory contents from device. 514 * 515 * @param deviceFilePath the absolute file path of the remote source 516 * @param localDir the local directory to pull files into 517 * @return <code>true</code> if file was pulled successfully. <code>false</code> otherwise. 518 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 519 * recovered. 520 */ 521 public boolean pullDir(String deviceFilePath, File localDir) 522 throws DeviceNotAvailableException; 523 524 /** 525 * Push a file to device 526 * 527 * @param localFile the local file to push 528 * @param deviceFilePath the remote destination absolute file path 529 * @return <code>true</code> if file was pushed successfully. <code>false</code> otherwise. 530 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 531 * recovered. 532 */ 533 public boolean pushFile(File localFile, String deviceFilePath) 534 throws DeviceNotAvailableException; 535 536 /** 537 * Push file created from a string to device 538 * 539 * @param contents the contents of the file to push 540 * @param deviceFilePath the remote destination absolute file path 541 * @return <code>true</code> if string was pushed successfully. <code>false</code> otherwise. 542 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 543 * recovered. 544 */ 545 public boolean pushString(String contents, String deviceFilePath) 546 throws DeviceNotAvailableException; 547 548 /** 549 * Recursively push directory contents to device. 550 * 551 * @param localDir the local directory to push 552 * @param deviceFilePath the absolute file path of the remote destination 553 * @return <code>true</code> if file was pushed successfully. <code>false</code> otherwise. 554 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 555 * recovered. 556 */ 557 public boolean pushDir(File localDir, String deviceFilePath) 558 throws DeviceNotAvailableException; 559 560 /** 561 * Incrementally syncs the contents of a local file directory to device. 562 * <p/> 563 * Decides which files to push by comparing timestamps of local files with their remote 564 * equivalents. Only 'newer' or non-existent files will be pushed to device. Thus overhead 565 * should be relatively small if file set on device is already up to date. 566 * <p/> 567 * Hidden files (with names starting with ".") will be ignored. 568 * <p/> 569 * Example usage: syncFiles("/tmp/files", "/sdcard") will created a /sdcard/files directory if 570 * it doesn't already exist, and recursively push the /tmp/files contents to /sdcard/files. 571 * 572 * @param localFileDir the local file directory containing files to recursively push. 573 * @param deviceFilePath the remote destination absolute file path root. All directories in thos 574 * file path must be readable. ie pushing to /data/local/tmp when adb is not root 575 * will fail 576 * @return <code>true</code> if files were synced successfully. <code>false</code> otherwise. 577 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 578 * recovered. 579 */ 580 public boolean syncFiles(File localFileDir, String deviceFilePath) 581 throws DeviceNotAvailableException; 582 583 /** 584 * Helper method to determine if file on device exists. 585 * 586 * @param deviceFilePath the absolute path of file on device to check 587 * @return <code>true</code> if file exists, <code>false</code> otherwise. 588 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 589 * recovered. 590 */ 591 public boolean doesFileExist(String deviceFilePath) throws DeviceNotAvailableException; 592 593 /** 594 * Retrieve a reference to a remote file on device. 595 * 596 * @param path the file path to retrieve. Can be an absolute path or path relative to '/'. (ie 597 * both "/system" and "system" syntax is supported) 598 * @return the {@link IFileEntry} or <code>null</code> if file at given <var>path</var> cannot 599 * be found 600 * @throws DeviceNotAvailableException 601 */ 602 public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException; 603 604 /** 605 * Return True if the path on the device is a directory, false otherwise. 606 * 607 * @throws DeviceNotAvailableException 608 */ 609 public boolean isDirectory(String deviceFilePath) throws DeviceNotAvailableException; 610 611 /** 612 * Alternative to using {@link IFileEntry} that sometimes won't work because of permissions. 613 * 614 * @param deviceFilePath is the path on the device where to do the search 615 * @return Array of string containing all the file in a path on the device. 616 * @throws DeviceNotAvailableException 617 */ 618 public String[] getChildren(String deviceFilePath) throws DeviceNotAvailableException; 619 620 /** 621 * Helper method to determine amount of free space on device external storage. 622 * 623 * @return the amount of free space in KB 624 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 625 * recovered. 626 */ 627 public long getExternalStoreFreeSpace() throws DeviceNotAvailableException; 628 629 /** 630 * Helper method to determine amount of free space on device partition. 631 * 632 * @return the amount of free space in KB 633 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 634 * recovered. 635 */ 636 public long getPartitionFreeSpace(String partition) throws DeviceNotAvailableException; 637 638 /** 639 * Returns a mount point. 640 * <p/> 641 * Queries the device directly if the cached info in {@link IDevice} is not available. 642 * <p/> 643 * TODO: move this behavior to {@link IDevice#getMountPoint(String)} 644 * 645 * @param mountName the name of the mount point 646 * @return the mount point or <code>null</code> 647 * @see IDevice#getMountPoint(String) 648 */ 649 public String getMountPoint(String mountName); 650 651 /** 652 * Returns a parsed version of the information in /proc/mounts on the device 653 * 654 * @return A {@link List} of {@link MountPointInfo} containing the information in "/proc/mounts" 655 */ 656 public List<MountPointInfo> getMountPointInfo() throws DeviceNotAvailableException; 657 658 /** 659 * Returns a {@link MountPointInfo} corresponding to the specified mountpoint path, or 660 * <code>null</code> if that path has nothing mounted or otherwise does not appear in 661 * /proc/mounts as a mountpoint. 662 * 663 * @return A {@link List} of {@link MountPointInfo} containing the information in "/proc/mounts" 664 * @see #getMountPointInfo() 665 */ 666 public MountPointInfo getMountPointInfo(String mountpoint) throws DeviceNotAvailableException; 667 668 /** 669 * Start capturing logcat output from device in the background. 670 * <p/> 671 * Will have no effect if logcat output is already being captured. 672 * Data can be later retrieved via getLogcat. 673 * <p/> 674 * When the device is no longer in use, {@link #stopLogcat()} must be called. 675 * <p/> 676 * {@link #startLogcat()} and {@link #stopLogcat()} do not normally need to be called when 677 * within a TF invocation context, as the TF framework will start and stop logcat. 678 */ 679 public void startLogcat(); 680 681 /** 682 * Stop capturing logcat output from device, and discard currently saved logcat data. 683 * <p/> 684 * Will have no effect if logcat output is not being captured. 685 */ 686 public void stopLogcat(); 687 688 /** 689 * Deletes any accumulated logcat data. 690 * <p/> 691 * This is useful for cases when you want to ensure {@link ITestDevice#getLogcat()} only returns 692 * log data produced after a certain point (such as after flashing a new device build, etc). 693 */ 694 public void clearLogcat(); 695 696 /** 697 * Grabs a snapshot stream of the logcat data. 698 * 699 * <p>Works in two modes: 700 * <li>If the logcat is currently being captured in the background, will return up to {@link 701 * TestDeviceOptions#getMaxLogcatDataSize()} bytes of the current contents of the background 702 * logcat capture 703 * <li>Otherwise, will return a static dump of the logcat data if device is currently responding 704 */ 705 @MustBeClosed 706 public InputStreamSource getLogcat(); 707 708 /** 709 * Grabs a snapshot stream of captured logcat data starting the date provided. The time on the 710 * device should be used {@link #getDeviceDate}. 711 * 712 * <p> 713 * 714 * @param date in millisecond since epoch format of when to start the snapshot until present. 715 * (can be be obtained using 'date +%s') 716 */ 717 @MustBeClosed 718 public InputStreamSource getLogcatSince(long date); 719 720 /** 721 * Grabs a snapshot stream of the last <code>maxBytes</code> of captured logcat data. 722 * 723 * <p>Useful for cases when you want to capture frequent snapshots of the captured logcat data 724 * without incurring the potentially big disk space penalty of getting the entire {@link 725 * #getLogcat()} snapshot. 726 * 727 * @param maxBytes the maximum amount of data to return. Should be an amount that can 728 * comfortably fit in memory 729 */ 730 @MustBeClosed 731 public InputStreamSource getLogcat(int maxBytes); 732 733 /** 734 * Get a dump of the current logcat for device. Unlike {@link #getLogcat()}, this method will 735 * always return a static dump of the logcat. 736 * 737 * <p>Has the disadvantage that nothing will be returned if device is not reachable. 738 * 739 * @return a {@link InputStreamSource} of the logcat data. An empty stream is returned if fail 740 * to capture logcat data. 741 */ 742 @MustBeClosed 743 public InputStreamSource getLogcatDump(); 744 745 /** 746 * Perform instructions to configure device for testing that after every boot. 747 * <p/> 748 * Should be called after device is fully booted/available 749 * <p/> 750 * In normal circumstances this method doesn't need to be called explicitly, as 751 * implementations should perform these steps automatically when performing a reboot. 752 * <p/> 753 * Where it may need to be called is when device reboots due to other events (eg when a 754 * fastboot update command has completed) 755 * 756 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 757 * recovered. 758 */ 759 public void postBootSetup() throws DeviceNotAvailableException; 760 761 /** 762 * Reboots the device into bootloader mode. 763 * <p/> 764 * Blocks until device is in bootloader mode. 765 * 766 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 767 * recovered. 768 */ 769 public void rebootIntoBootloader() throws DeviceNotAvailableException; 770 771 /** 772 * Reboots the device into adb mode. 773 * <p/> 774 * Blocks until device becomes available. 775 * 776 * @throws DeviceNotAvailableException if device is not available after reboot 777 */ 778 public void reboot() throws DeviceNotAvailableException; 779 780 /** 781 * Reboots the device into adb recovery mode. 782 * <p/> 783 * Blocks until device enters recovery 784 * 785 * @throws DeviceNotAvailableException if device is not available after reboot 786 */ 787 public void rebootIntoRecovery() throws DeviceNotAvailableException; 788 789 /** 790 * An alternate to {@link #reboot()} that only blocks until device is online ie visible to adb. 791 * 792 * @throws DeviceNotAvailableException if device is not available after reboot 793 */ 794 public void rebootUntilOnline() throws DeviceNotAvailableException; 795 796 /** 797 * Issues a command to reboot device and returns on command complete and when device is no 798 * longer visible to adb. 799 * 800 * @throws DeviceNotAvailableException 801 */ 802 public void nonBlockingReboot() throws DeviceNotAvailableException; 803 804 /** 805 * Turns on adb root. If the "enable-root" setting is "false", will log a message and 806 * return without enabling root. 807 * <p/> 808 * Enabling adb root may cause device to disconnect from adb. This method will block until 809 * device is available. 810 * 811 * @return <code>true</code> if successful. 812 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 813 * recovered. 814 */ 815 public boolean enableAdbRoot() throws DeviceNotAvailableException; 816 817 /** 818 * Turns off adb root. 819 * <p/> 820 * Disabling adb root may cause device to disconnect from adb. This method will block until 821 * device is available. 822 * 823 * @return <code>true</code> if successful. 824 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 825 * recovered. 826 */ 827 public boolean disableAdbRoot() throws DeviceNotAvailableException; 828 829 /** 830 * @return <code>true</code> if device currently has adb root, <code>false</code> otherwise. 831 * 832 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 833 * recovered. 834 */ 835 public boolean isAdbRoot() throws DeviceNotAvailableException; 836 837 /** 838 * Encrypts the device. 839 * <p/> 840 * Encrypting the device may be done inplace or with a wipe. Inplace encryption will not wipe 841 * any data on the device but normally takes a couple orders of magnitude longer than the wipe. 842 * <p/> 843 * This method will reboot the device if it is not already encrypted and will block until device 844 * is online. Also, it will not decrypt the device after the reboot. Therefore, the device 845 * might not be fully booted and/or ready to be tested when this method returns. 846 * 847 * @param inplace if the encryption process should take inplace and the device should not be 848 * wiped. 849 * @return <code>true</code> if successful. 850 * @throws DeviceNotAvailableException if device is not available after reboot. 851 * @throws UnsupportedOperationException if encryption is not supported on the device. 852 */ 853 public boolean encryptDevice(boolean inplace) throws DeviceNotAvailableException, 854 UnsupportedOperationException; 855 856 /** 857 * Unencrypts the device. 858 * <p/> 859 * Unencrypting the device may cause device to be wiped and may reboot device. This method will 860 * block until device is available and ready for testing. Requires fastboot inorder to wipe the 861 * userdata partition. 862 * 863 * @return <code>true</code> if successful. 864 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 865 * recovered. 866 * @throws UnsupportedOperationException if encryption is not supported on the device. 867 */ 868 public boolean unencryptDevice() throws DeviceNotAvailableException, 869 UnsupportedOperationException; 870 871 /** 872 * Unlocks the device if the device is in an encrypted state. 873 * </p> 874 * This method may restart the framework but will not call {@link #postBootSetup()}. Therefore, 875 * the device might not be fully ready to be tested when this method returns. 876 * 877 * @return <code>true</code> if successful or if the device is unencrypted. 878 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 879 * recovered. 880 * @throws UnsupportedOperationException if encryption is not supported on the device. 881 */ 882 public boolean unlockDevice() throws DeviceNotAvailableException, 883 UnsupportedOperationException; 884 885 /** 886 * Returns if the device is encrypted. 887 * 888 * @return <code>true</code> if the device is encrypted. 889 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 890 * recovered. 891 */ 892 public boolean isDeviceEncrypted() throws DeviceNotAvailableException; 893 894 /** 895 * Returns if encryption is supported on the device. 896 * 897 * @return <code>true</code> if the device supports encryption. 898 * @throws DeviceNotAvailableException 899 */ 900 public boolean isEncryptionSupported() throws DeviceNotAvailableException; 901 902 /** 903 * Waits for the device to be responsive and available for testing. 904 * 905 * @param waitTime the time in ms to wait 906 * @throws DeviceNotAvailableException if device is still unresponsive after waitTime expires. 907 */ 908 public void waitForDeviceAvailable(final long waitTime) throws DeviceNotAvailableException; 909 910 /** 911 * Waits for the device to be responsive and available for testing. Uses default timeout. 912 * 913 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 914 * recovered. 915 */ 916 public void waitForDeviceAvailable() throws DeviceNotAvailableException; 917 918 /** 919 * Blocks until device is visible via adb. 920 * <p/> 921 * Note the device may not necessarily be responsive to commands on completion. Use 922 * {@link #waitForDeviceAvailable()} instead. 923 * 924 * @param waitTime the time in ms to wait 925 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 926 * recovered. 927 */ 928 public void waitForDeviceOnline(final long waitTime) throws DeviceNotAvailableException; 929 930 /** 931 * Blocks until device is visible via adb. Uses default timeout 932 * <p/> 933 * Note the device may not necessarily be responsive to commands on completion. Use 934 * {@link #waitForDeviceAvailable()} instead. 935 * 936 * @throws DeviceNotAvailableException if connection with device is lost and cannot be 937 * recovered. 938 */ 939 public void waitForDeviceOnline() throws DeviceNotAvailableException; 940 941 /** 942 * Blocks for the device to be not available ie missing from adb 943 * 944 * @param waitTime the time in ms to wait 945 * @return <code>true</code> if device becomes not available before time expires. 946 * <code>false</code> otherwise 947 */ 948 public boolean waitForDeviceNotAvailable(final long waitTime); 949 950 /** 951 * Blocks for the device to be in the 'adb recovery' state (note this is distinct from 952 * {@link IDeviceRecovery}). 953 * 954 * @param waitTime the time in ms to wait 955 * @return <code>true</code> if device boots into recovery before time expires. 956 * <code>false</code> otherwise 957 */ 958 public boolean waitForDeviceInRecovery(final long waitTime); 959 960 /** 961 * Waits for device to be responsive to a basic adb shell command. 962 * 963 * @param waitTime the time in ms to wait 964 * @return <code>true</code> if device becomes responsive before <var>waitTime</var> elapses. 965 */ 966 public boolean waitForDeviceShell(final long waitTime); 967 968 /** 969 * Blocks until the device's boot complete flag is set. 970 * 971 * @param timeOut time in msecs to wait for the flag to be set 972 * @return true if device's boot complete flag is set within the timeout 973 * @throws DeviceNotAvailableException 974 */ 975 public boolean waitForBootComplete(long timeOut) throws DeviceNotAvailableException; 976 977 /** 978 * Set the {@link IDeviceRecovery} to use for this device. Should be set when device is first 979 * allocated. 980 * 981 * @param recovery the {@link IDeviceRecovery} 982 */ 983 public void setRecovery(IDeviceRecovery recovery); 984 985 /** 986 * Set the current recovery mode to use for the device. 987 * <p/> 988 * Used to control what recovery method to use when a device communication problem is 989 * encountered. Its recommended to only use this method sparingly when needed (for example, 990 * when framework is down, etc 991 * 992 * @param mode whether 'recover till online only' mode should be on or not. 993 */ 994 public void setRecoveryMode(RecoveryMode mode); 995 996 /** 997 * Get the current recovery mode used for the device. 998 * 999 * @return the current recovery mode used for the device. 1000 */ 1001 public RecoveryMode getRecoveryMode(); 1002 1003 /** 1004 * Get the device's state. 1005 */ 1006 public TestDeviceState getDeviceState(); 1007 1008 /** 1009 * @return <code>true</code> if device is connected to adb-over-tcp, <code>false</code> 1010 * otherwise. 1011 */ 1012 public boolean isAdbTcp(); 1013 1014 /** 1015 * Switch device to adb-over-tcp mode. 1016 * 1017 * @return the tcp serial number or <code>null</code> if device could not be switched 1018 * @throws DeviceNotAvailableException 1019 */ 1020 public String switchToAdbTcp() throws DeviceNotAvailableException; 1021 1022 /** 1023 * Switch device to adb over usb mode. 1024 * 1025 * @return <code>true</code> if switch was successful, <code>false</code> otherwise. 1026 * @throws DeviceNotAvailableException 1027 */ 1028 public boolean switchToAdbUsb() throws DeviceNotAvailableException; 1029 1030 /** 1031 * Get the stream of emulator stdout and stderr 1032 * @return emulator output 1033 */ 1034 public InputStreamSource getEmulatorOutput(); 1035 1036 /** 1037 * Close and delete the emulator output. 1038 */ 1039 public void stopEmulatorOutput(); 1040 1041 /** 1042 * Get the device API Level. Defaults to {@link #UNKNOWN_API_LEVEL}. 1043 * 1044 * @return an integer indicating the API Level of device 1045 * @throws DeviceNotAvailableException 1046 */ 1047 public int getApiLevel() throws DeviceNotAvailableException; 1048 1049 /** 1050 * Helper to get the time difference between the device and a given {@link Date}. Use Epoch time 1051 * internally. 1052 * 1053 * @return the difference in milliseconds 1054 */ 1055 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException; 1056 1057 /** 1058 * Sets the date on device 1059 * <p> 1060 * Note: setting date on device requires root 1061 * @param date specify a particular date; will use host date if <code>null</code> 1062 * @throws DeviceNotAvailableException 1063 */ 1064 public void setDate(Date date) throws DeviceNotAvailableException; 1065 1066 /** 1067 * Return the date of the device in millisecond since epoch. 1068 * 1069 * <p> 1070 * 1071 * @return the date of the device in epoch format. 1072 * @throws DeviceNotAvailableException 1073 */ 1074 public long getDeviceDate() throws DeviceNotAvailableException; 1075 1076 /** 1077 * Make the system partition on the device writable. May reboot the device. 1078 * @throws DeviceNotAvailableException 1079 */ 1080 public void remountSystemWritable() throws DeviceNotAvailableException; 1081 1082 /** 1083 * Returns the key type used to sign the device image 1084 * <p> 1085 * Typically Android devices may be signed with test-keys (like in AOSP) or release-keys 1086 * (controlled by individual device manufacturers) 1087 * @return The signing key if found, null otherwise. 1088 * @throws DeviceNotAvailableException 1089 */ 1090 public String getBuildSigningKeys() throws DeviceNotAvailableException; 1091 1092 /** 1093 * Retrieves a bugreport from the device. 1094 * <p/> 1095 * The implementation of this is guaranteed to continue to work on a device without an sdcard 1096 * (or where the sdcard is not yet mounted). 1097 * 1098 * @return An {@link InputStreamSource} which will produce the bugreport contents on demand. In 1099 * case of failure, the {@code InputStreamSource} will produce an empty 1100 * {@link InputStream}. 1101 */ 1102 public InputStreamSource getBugreport(); 1103 1104 /** 1105 * Retrieves a bugreportz from the device. Zip format bugreport contains the main bugreport 1106 * and other log files that are useful for debugging. 1107 * <p/> 1108 * Only supported for 'adb version' > 1.0.36 1109 * 1110 * @return a {@link InputStreamSource} of the zip file containing the bugreportz, return null 1111 * in case of failure. 1112 */ 1113 public InputStreamSource getBugreportz(); 1114 1115 /** 1116 * Helper method to take a bugreport and log it to the reporters. 1117 * 1118 * @param dataName name under which the bugreport will be reported. 1119 * @param listener an {@link ITestLogger} to log the bugreport. 1120 * @return True if the logging was successful, false otherwise. 1121 */ 1122 public boolean logBugreport(String dataName, ITestLogger listener); 1123 1124 /** 1125 * Take a bugreport and returns it inside a {@link Bugreport} object to handle it. Return null 1126 * in case of issue. 1127 * </p> 1128 * File referenced in the Bugreport object need to be cleaned via {@link Bugreport#close()}. 1129 */ 1130 public Bugreport takeBugreport(); 1131 1132 /** 1133 * Get the device class. 1134 * 1135 * @return the {@link String} device class. 1136 */ 1137 public String getDeviceClass(); 1138 1139 /** 1140 * Extra steps for device specific required setup that will be executed on the device prior 1141 * to the invocation flow. 1142 */ 1143 public void preInvocationSetup(IBuildInfo info) 1144 throws TargetSetupError, DeviceNotAvailableException; 1145 1146 /** 1147 * Extra steps for device specific required clean up that will be executed after the invocation 1148 * is done. 1149 */ 1150 public void postInvocationTearDown(); 1151 1152 /** 1153 * Return true if the device is headless (no screen), false otherwise. 1154 */ 1155 public boolean isHeadless() throws DeviceNotAvailableException; 1156 1157 /** 1158 * Return a {@link DeviceDescriptor} from the device information to get info on it without 1159 * passing the actual device object. 1160 */ 1161 public DeviceDescriptor getDeviceDescriptor(); 1162 1163 /** 1164 * Helper method runs the "ps" command and returns list of USER, PID and NAME of all the 1165 * processes. 1166 * 1167 * @return List of ProcessInfo objects 1168 */ 1169 public List<ProcessInfo> getProcesses() throws DeviceNotAvailableException; 1170 1171 /** 1172 * Helper method runs the "ps" command and returns USER, PID and NAME of the given process name. 1173 * 1174 * @return ProcessInfo of given processName 1175 */ 1176 public ProcessInfo getProcessByName(String processName) throws DeviceNotAvailableException; 1177 1178 /** Returns the pid of the service or null if something went wrong. */ 1179 public String getProcessPid(String process) throws DeviceNotAvailableException; 1180 1181 /** 1182 * Log a message in the logcat of the device. This is a safe call that will not throw even if 1183 * the logging fails. 1184 * 1185 * @param tag The tag under which we log our message in the logcat. 1186 * @param level The debug level of the message in the logcat. 1187 * @param format The message format. 1188 * @param args the args to be replaced via String.format(). 1189 */ 1190 public void logOnDevice(String tag, LogLevel level, String format, Object... args); 1191 } 1192