Home | History | Annotate | Download | only in device
      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