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.io.OutputStream;
40 import java.util.Collection;
41 import java.util.Date;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Set;
45 import java.util.concurrent.TimeUnit;
46 
47 import javax.annotation.Nullable;
48 
49 /**
50  * Provides an reliable and slightly higher level API to a ddmlib {@link IDevice}.
51  * <p/>
52  * Retries device commands for a configurable amount, and provides a device recovery
53  * interface for devices which are unresponsive.
54  */
55 public interface INativeDevice {
56 
57     /**
58      * Default value when API Level cannot be detected
59      */
60     public final static int UNKNOWN_API_LEVEL = -1;
61 
62     /**
63      * Set the {@link TestDeviceOptions} for the device
64      */
setOptions(TestDeviceOptions options)65     public void setOptions(TestDeviceOptions options);
66 
67     /**
68      * Returns a reference to the associated ddmlib {@link IDevice}.
69      * <p/>
70      * A new {@link IDevice} may be allocated by DDMS each time the device disconnects and
71      * reconnects from adb. Thus callers should not keep a reference to the {@link IDevice},
72      * because that reference may become stale.
73      *
74      * @return the {@link IDevice}
75      */
getIDevice()76     public IDevice getIDevice();
77 
78     /**
79      * Convenience method to get serial number of this device.
80      *
81      * @return the {@link String} serial number
82      */
getSerialNumber()83     public String getSerialNumber();
84 
85     /**
86      * Retrieve the given property value from the device.
87      *
88      * @param name the property name
89      * @return the property value or <code>null</code> if it does not exist
90      * @throws DeviceNotAvailableException
91      */
getProperty(String name)92     public String getProperty(String name) throws DeviceNotAvailableException;
93 
94     /**
95      * Returns integer value of the given property from the device.
96      *
97      * @param name the property name
98      * @param defaultValue default value to return if property is empty or doesn't exist.
99      * @return the property value or {@code defaultValue} if the property is empty, doesn't exist,
100      *     or doesn't have an integer value.
101      */
getIntProperty(String name, long defaultValue)102     public long getIntProperty(String name, long defaultValue) throws DeviceNotAvailableException;
103 
104     /**
105      * Returns boolean value of the given property.
106      *
107      * @param name the property name
108      * @param defaultValue default value to return if property is empty or doesn't exist.
109      * @return {@code true} if the property has value {@code "1"}, {@code "y"}, {@code "yes"},
110      *     {@code "on"}, or {@code "true"}, {@code false} if the property has value of {@code "0"},
111      *     {@code "n"}, {@code "no"}, {@code "off"}, {@code "false"}, or {@code defaultValue}
112      *     otherwise.
113      */
getBooleanProperty(String name, boolean defaultValue)114     public boolean getBooleanProperty(String name, boolean defaultValue)
115             throws DeviceNotAvailableException;
116 
117     /**
118      * Sets the given property value on the device. Requires adb root is true.
119      *
120      * @param propKey The key targeted to be set.
121      * @param propValue The property value to be set.
122      * @return returns <code>True</code> if the setprop command was successful, False otherwise.
123      * @throws DeviceNotAvailableException
124      */
setProperty(String propKey, String propValue)125     public boolean setProperty(String propKey, String propValue) throws DeviceNotAvailableException;
126 
127     /**
128      * Retrieve the given fastboot variable value from the device.
129      *
130      * @param variableName the variable name
131      * @return the property value or <code>null</code> if it does not exist
132      * @throws DeviceNotAvailableException, UnsupportedOperationException
133      */
getFastbootVariable(String variableName)134     public String getFastbootVariable(String variableName)
135             throws DeviceNotAvailableException, UnsupportedOperationException;
136 
137     /**
138      * Convenience method to get the bootloader version of this device.
139      * <p/>
140      * Will attempt to retrieve bootloader version from the device's current state. (ie if device
141      * is in fastboot mode, it will attempt to retrieve version from fastboot)
142      *
143      * @return the {@link String} bootloader version or <code>null</code> if it cannot be found
144      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
145      *             recovered.
146      */
getBootloaderVersion()147     public String getBootloaderVersion() throws DeviceNotAvailableException;
148 
149     /**
150      * Convenience method to get baseband (radio) version of this device. Getting the radio version
151      * is device specific, so it might not return the correct information for all devices. This
152      * method relies on the gsm.version.baseband propery to return the correct version information.
153      * This is not accurate for some CDMA devices and the version returned here might not match
154      * the version reported from fastboot and might not return the version for the CDMA radio.
155      * TL;DR this method only reports accurate version if the gsm.version.baseband property is the
156      * same as the version returned by <code>fastboot getvar version-baseband</code>.
157      *
158      * @return the {@link String} baseband version or <code>null</code> if it cannot be determined
159      *          (device has no radio or version string cannot be read)
160      * @throws DeviceNotAvailableException if the connection with the device is lost and cannot
161      *          be recovered.
162      */
getBasebandVersion()163     public String getBasebandVersion() throws DeviceNotAvailableException;
164 
165     /**
166      * Convenience method to get the product type of this device.
167      * <p/>
168      * This method will work if device is in either adb or fastboot mode.
169      *
170      * @return the {@link String} product type name. Will not be null
171      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
172      *             recovered, or if product type can not be determined
173      */
getProductType()174     public String getProductType() throws DeviceNotAvailableException;
175 
176     /**
177      * Convenience method to get the product variant of this device.
178      * <p/>
179      * This method will work if device is in either adb or fastboot mode.
180      *
181      * @return the {@link String} product variant name or <code>null</code> if it cannot be
182      *         determined
183      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
184      *             recovered.
185      */
getProductVariant()186     public String getProductVariant() throws DeviceNotAvailableException;
187 
188     /**
189      * Convenience method to get the product type of this device when its in fastboot mode.
190      * <p/>
191      * This method should only be used if device should be in fastboot. Its a bit safer variant
192      * than the generic {@link #getProductType()} method in this case, because ITestDevice
193      * will know to recover device into fastboot if device is in incorrect state or is
194      * unresponsive.
195      *
196      * @return the {@link String} product type name or <code>null</code> if it cannot be determined
197      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
198      *             recovered.
199      */
getFastbootProductType()200     public String getFastbootProductType() throws DeviceNotAvailableException;
201 
202     /**
203      * Convenience method to get the product type of this device when its in fastboot mode.
204      * <p/>
205      * This method should only be used if device should be in fastboot. Its a bit safer variant
206      * than the generic {@link #getProductType()} method in this case, because ITestDevice
207      * will know to recover device into fastboot if device is in incorrect state or is
208      * unresponsive.
209      *
210      * @return the {@link String} product type name or <code>null</code> if it cannot be determined
211      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
212      *             recovered.
213      */
getFastbootProductVariant()214     public String getFastbootProductVariant() throws DeviceNotAvailableException;
215 
216     /**
217      * Retrieve the alias of the build that the device is currently running.
218      *
219      * <p>Build alias is usually a more readable string than build id (typically a number for
220      * Nexus builds). For example, final Android 4.2 release has build alias JDQ39, and build id
221      * 573038
222      * @return the build alias or fall back to build id if it could not be retrieved
223      * @throws DeviceNotAvailableException
224      */
getBuildAlias()225     public String getBuildAlias() throws DeviceNotAvailableException;
226 
227     /**
228      * Retrieve the build the device is currently running.
229      *
230      * @return the build id or {@link IBuildInfo#UNKNOWN_BUILD_ID} if it could not be retrieved
231      * @throws DeviceNotAvailableException
232      */
getBuildId()233     public String getBuildId() throws DeviceNotAvailableException;
234 
235     /**
236      * Retrieve the build flavor for the device.
237      *
238      * @return the build flavor or null if it could not be retrieved
239      * @throws DeviceNotAvailableException
240      */
getBuildFlavor()241     public String getBuildFlavor() throws DeviceNotAvailableException;
242 
243     /**
244      * Executes the given adb shell command, retrying multiple times if command fails.
245      * <p/>
246      * A simpler form of
247      * {@link #executeShellCommand(String, IShellOutputReceiver, long, TimeUnit, int)} with
248      * default values.
249      *
250      * @param command the adb shell command to run
251      * @param receiver the {@link IShellOutputReceiver} to direct shell output to.
252      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
253      *             recovered.
254      */
executeShellCommand(String command, IShellOutputReceiver receiver)255     public void executeShellCommand(String command, IShellOutputReceiver receiver)
256         throws DeviceNotAvailableException;
257 
258     /**
259      * Executes a adb shell command, with more parameters to control command behavior.
260      *
261      * @see #executeShellCommand(String, IShellOutputReceiver)
262      * @param command the adb shell command to run
263      * @param receiver the {@link IShellOutputReceiver} to direct shell output to.
264      * @param maxTimeToOutputShellResponse the maximum amount of time during which the command is
265      *            allowed to not output any response; unit as specified in <code>timeUnit</code>
266      * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code>
267      * @param retryAttempts the maximum number of times to retry command if it fails due to a
268      *            exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var>
269      *            are performed without success.
270      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
271      *             recovered.
272      * @see TimeUtil
273      */
executeShellCommand(String command, IShellOutputReceiver receiver, long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts)274     public void executeShellCommand(String command, IShellOutputReceiver receiver,
275             long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts)
276                     throws DeviceNotAvailableException;
277 
278     /**
279      * Executes a adb shell command, with more parameters to control command behavior.
280      *
281      * @see #executeShellCommand(String, IShellOutputReceiver)
282      * @param command the adb shell command to run
283      * @param receiver the {@link IShellOutputReceiver} to direct shell output to.
284      * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as
285      *     specified in <code>timeUnit</code>
286      * @param maxTimeToOutputShellResponse the maximum amount of time during which the command is
287      *     allowed to not output any response; unit as specified in <code>timeUnit</code>
288      * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code>
289      * @param retryAttempts the maximum number of times to retry command if it fails due to a
290      *     exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var> are
291      *     performed without success.
292      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
293      *     recovered.
294      * @see TimeUtil
295      */
executeShellCommand( String command, IShellOutputReceiver receiver, long maxTimeoutForCommand, long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts)296     public void executeShellCommand(
297             String command,
298             IShellOutputReceiver receiver,
299             long maxTimeoutForCommand,
300             long maxTimeToOutputShellResponse,
301             TimeUnit timeUnit,
302             int retryAttempts)
303             throws DeviceNotAvailableException;
304 
305     /**
306      * Helper method which executes a adb shell command and returns output as a {@link String}.
307      *
308      * @param command the adb shell command to run
309      * @return the shell output
310      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
311      * recovered.
312      */
executeShellCommand(String command)313     public String executeShellCommand(String command) throws DeviceNotAvailableException;
314 
315     /**
316      * Helper method which executes a adb shell command and returns the results as a {@link
317      * CommandResult} properly populated with the command status output, stdout and stderr.
318      *
319      * @param command The command that should be run.
320      * @return The result in {@link CommandResult}.
321      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
322      *     recovered.
323      */
executeShellV2Command(String command)324     public CommandResult executeShellV2Command(String command) throws DeviceNotAvailableException;
325 
326     /**
327      * Helper method which executes an adb shell command and returns the results as a {@link
328      * CommandResult} properly populated with the command status output, stdout and stderr.
329      *
330      * @param command The command that should be run.
331      * @param pipeAsInput A {@link File} that will be piped as input to the command.
332      * @return The result in {@link CommandResult}.
333      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
334      *     recovered.
335      */
executeShellV2Command(String command, File pipeAsInput)336     public CommandResult executeShellV2Command(String command, File pipeAsInput)
337             throws DeviceNotAvailableException;
338 
339     /**
340      * Helper method which executes an adb shell command and returns the results as a {@link
341      * CommandResult} properly populated with the command status output, stdout and stderr.
342      *
343      * @param command The command that should be run.
344      * @param pipeToOutput {@link OutputStream} where the std output will be redirected.
345      * @return The result in {@link CommandResult}.
346      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
347      *     recovered.
348      */
executeShellV2Command(String command, OutputStream pipeToOutput)349     public CommandResult executeShellV2Command(String command, OutputStream pipeToOutput)
350             throws DeviceNotAvailableException;
351 
352     /**
353      * Executes a adb shell command, with more parameters to control command behavior.
354      *
355      * @see #executeShellV2Command(String)
356      * @param command the adb shell command to run
357      * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as
358      *     specified in <code>timeUnit</code>
359      * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code>
360      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
361      *     recovered.
362      * @see TimeUtil
363      */
executeShellV2Command( String command, final long maxTimeoutForCommand, final TimeUnit timeUnit)364     public CommandResult executeShellV2Command(
365             String command, final long maxTimeoutForCommand, final TimeUnit timeUnit)
366             throws DeviceNotAvailableException;
367 
368     /**
369      * Executes a adb shell command, with more parameters to control command behavior.
370      *
371      * @see #executeShellV2Command(String)
372      * @param command the adb shell command to run
373      * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as
374      *     specified in <code>timeUnit</code>
375      * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code>
376      * @param retryAttempts the maximum number of times to retry command if it fails due to a
377      *     exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var> are
378      *     performed without success.
379      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
380      *     recovered.
381      * @see TimeUtil
382      */
executeShellV2Command( String command, final long maxTimeoutForCommand, final TimeUnit timeUnit, int retryAttempts)383     public CommandResult executeShellV2Command(
384             String command,
385             final long maxTimeoutForCommand,
386             final TimeUnit timeUnit,
387             int retryAttempts)
388             throws DeviceNotAvailableException;
389 
390     /**
391      * Executes a adb shell command, with more parameters to control command behavior.
392      *
393      * @see #executeShellV2Command(String)
394      * @param command the adb shell command to run
395      * @param pipeAsInput A {@link File} that will be piped as input to the command.
396      * @param pipeToOutput {@link OutputStream} where the std output will be redirected.
397      * @param maxTimeoutForCommand the maximum timeout for the command to complete; unit as
398      *     specified in <code>timeUnit</code>
399      * @param timeUnit unit for <code>maxTimeToOutputShellResponse</code>
400      * @param retryAttempts the maximum number of times to retry command if it fails due to a
401      *     exception. DeviceNotResponsiveException will be thrown if <var>retryAttempts</var> are
402      *     performed without success.
403      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
404      *     recovered.
405      * @see TimeUtil
406      */
executeShellV2Command( String command, File pipeAsInput, OutputStream pipeToOutput, final long maxTimeoutForCommand, final TimeUnit timeUnit, int retryAttempts)407     public CommandResult executeShellV2Command(
408             String command,
409             File pipeAsInput,
410             OutputStream pipeToOutput,
411             final long maxTimeoutForCommand,
412             final TimeUnit timeUnit,
413             int retryAttempts)
414             throws DeviceNotAvailableException;
415 
416     /**
417      * Helper method which executes a adb command as a system command.
418      * <p/>
419      * {@link #executeShellCommand(String)} should be used instead wherever possible, as that
420      * method provides better failure detection and performance.
421      *
422      * @param commandArgs the adb command and arguments to run
423      * @return the stdout from command. <code>null</code> if command failed to execute.
424      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
425      * recovered.
426      */
executeAdbCommand(String... commandArgs)427     public String executeAdbCommand(String... commandArgs) throws DeviceNotAvailableException;
428 
429     /**
430      * Helper method which executes a adb command as a system command with a specified timeout.
431      *
432      * <p>{@link #executeShellCommand(String)} should be used instead wherever possible, as that
433      * method provides better failure detection and performance.
434      *
435      * @param timeout the time in milliseconds before the device is considered unresponsive, 0L for
436      *     no timeout
437      * @param commandArgs the adb command and arguments to run
438      * @return the stdout from command. <code>null</code> if command failed to execute.
439      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
440      *     recovered.
441      */
executeAdbCommand(long timeout, String... commandArgs)442     public String executeAdbCommand(long timeout, String... commandArgs)
443             throws DeviceNotAvailableException;
444 
445     /**
446      * Helper method which executes a fastboot command as a system command with a default timeout
447      * of 2 minutes.
448      * <p/>
449      * Expected to be used when device is already in fastboot mode.
450      *
451      * @param commandArgs the fastboot command and arguments to run
452      * @return the CommandResult containing output of command
453      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
454      * recovered.
455      */
executeFastbootCommand(String... commandArgs)456     public CommandResult executeFastbootCommand(String... commandArgs)
457             throws DeviceNotAvailableException;
458 
459     /**
460      * Helper method which executes a fastboot command as a system command.
461      * <p/>
462      * Expected to be used when device is already in fastboot mode.
463      *
464      * @param timeout the time in milliseconds before the command expire
465      * @param commandArgs the fastboot command and arguments to run
466      * @return the CommandResult containing output of command
467      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
468      * recovered.
469      */
executeFastbootCommand(long timeout, String... commandArgs)470     public CommandResult executeFastbootCommand(long timeout, String... commandArgs)
471             throws DeviceNotAvailableException;
472 
473     /**
474      * Helper method which executes a long running fastboot command as a system command.
475      * <p/>
476      * Identical to {@link #executeFastbootCommand(String...)} except uses a longer timeout.
477      *
478      * @param commandArgs the fastboot command and arguments to run
479      * @return the CommandResult containing output of command
480      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
481      * recovered.
482      */
executeLongFastbootCommand(String... commandArgs)483     public CommandResult executeLongFastbootCommand(String... commandArgs)
484             throws DeviceNotAvailableException;
485 
486     /**
487      * Get whether to use fastboot erase or fastboot format to wipe a partition on the device.
488      *
489      * @return {@code true} if fastboot erase will be used or {@code false} if fastboot format will
490      * be used.
491      * @see #fastbootWipePartition(String)
492      */
getUseFastbootErase()493     public boolean getUseFastbootErase();
494 
495     /**
496      * Set whether to use fastboot erase or fastboot format to wipe a partition on the device.
497      *
498      * @param useFastbootErase {@code true} if fastboot erase should be used or {@code false} if
499      * fastboot format should be used.
500      * @see #fastbootWipePartition(String)
501      */
setUseFastbootErase(boolean useFastbootErase)502     public void setUseFastbootErase(boolean useFastbootErase);
503 
504     /**
505      * Helper method which wipes a partition for the device.
506      * <p/>
507      * If {@link #getUseFastbootErase()} is {@code true}, then fastboot erase will be used to wipe
508      * the partition. The device must then create a filesystem the next time the device boots.
509      * Otherwise, fastboot format is used which will create a new filesystem on the device.
510      * <p/>
511      * Expected to be used when device is already in fastboot mode.
512      *
513      * @param partition the partition to wipe
514      * @return the CommandResult containing output of command
515      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
516      * recovered.
517      */
fastbootWipePartition(String partition)518     public CommandResult fastbootWipePartition(String partition) throws DeviceNotAvailableException;
519 
520     /**
521      * Runs instrumentation tests, and provides device recovery.
522      *
523      * <p>If connection with device is lost before test run completes, and recovery succeeds, all
524      * listeners will be informed of testRunFailed and "false" will be returned. The test command
525      * will not be rerun. It is left to callers to retry if necessary.
526      *
527      * <p>If connection with device is lost before test run completes, and recovery fails, all
528      * listeners will be informed of testRunFailed and DeviceNotAvailableException will be thrown.
529      *
530      * @param runner the {@link IRemoteAndroidTestRunner} which runs the tests
531      * @param listeners the test result listeners
532      * @return <code>true</code> if test command completed. <code>false</code> if it failed to
533      *     complete due to device communication exception, but recovery succeeded
534      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
535      *     recovered. ie test command failed to complete and recovery failed.
536      */
runInstrumentationTests( IRemoteAndroidTestRunner runner, Collection<ITestLifeCycleReceiver> listeners)537     public boolean runInstrumentationTests(
538             IRemoteAndroidTestRunner runner, Collection<ITestLifeCycleReceiver> listeners)
539             throws DeviceNotAvailableException;
540 
541     /**
542      * Convenience method for performing {@link #runInstrumentationTests(IRemoteAndroidTestRunner,
543      * Collection)} with one or more listeners passed as parameters.
544      *
545      * @param runner the {@link IRemoteAndroidTestRunner} which runs the tests
546      * @param listeners the test result listener(s)
547      * @return <code>true</code> if test command completed. <code>false</code> if it failed to
548      *     complete, but recovery succeeded
549      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
550      *     recovered. ie test command failed to complete and recovery failed.
551      */
runInstrumentationTests( IRemoteAndroidTestRunner runner, ITestLifeCycleReceiver... listeners)552     public boolean runInstrumentationTests(
553             IRemoteAndroidTestRunner runner, ITestLifeCycleReceiver... listeners)
554             throws DeviceNotAvailableException;
555 
556     /**
557      * Same as {@link ITestDevice#runInstrumentationTests(IRemoteAndroidTestRunner, Collection)} but
558      * runs the test for the given user.
559      */
runInstrumentationTestsAsUser( IRemoteAndroidTestRunner runner, int userId, Collection<ITestLifeCycleReceiver> listeners)560     public boolean runInstrumentationTestsAsUser(
561             IRemoteAndroidTestRunner runner,
562             int userId,
563             Collection<ITestLifeCycleReceiver> listeners)
564             throws DeviceNotAvailableException;
565 
566     /**
567      * Same as {@link ITestDevice#runInstrumentationTests(IRemoteAndroidTestRunner,
568      * ITestLifeCycleReceiver...)} but runs the test for a given user.
569      */
runInstrumentationTestsAsUser( IRemoteAndroidTestRunner runner, int userId, ITestLifeCycleReceiver... listeners)570     public boolean runInstrumentationTestsAsUser(
571             IRemoteAndroidTestRunner runner, int userId, ITestLifeCycleReceiver... listeners)
572             throws DeviceNotAvailableException;
573 
574     /**
575      * Check whether platform on device supports runtime permission granting
576      * @return True if runtime permission are supported, false otherwise.
577      * @throws DeviceNotAvailableException
578      */
isRuntimePermissionSupported()579     public boolean isRuntimePermissionSupported() throws DeviceNotAvailableException;
580 
581     /**
582      * Check whether platform on device supports app enumeration
583      * @return True if app enumeration is supported, false otherwise
584      * @throws DeviceNotAvailableException
585      */
isAppEnumerationSupported()586     public boolean isAppEnumerationSupported() throws DeviceNotAvailableException;
587 
588     /**
589      * Retrieves a file off device.
590      *
591      * @param remoteFilePath the absolute path to file on device.
592      * @param localFile the local file to store contents in. If non-empty, contents will be
593      *            replaced.
594      * @return <code>true</code> if file was retrieved successfully. <code>false</code> otherwise.
595      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
596      *             recovered.
597      */
pullFile(String remoteFilePath, File localFile)598     public boolean pullFile(String remoteFilePath, File localFile)
599             throws DeviceNotAvailableException;
600 
601     /**
602      * Retrieves a file off device, stores it in a local temporary {@link File}, and returns that
603      * {@code File}.
604      *
605      * @param remoteFilePath the absolute path to file on device.
606      * @return A {@link File} containing the contents of the device file, or {@code null} if the
607      *         copy failed for any reason (including problems with the host filesystem)
608      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
609      *             recovered.
610      */
pullFile(String remoteFilePath)611     public File pullFile(String remoteFilePath) throws DeviceNotAvailableException;
612 
613     /**
614      * Retrieves a file off device, and returns the contents.
615      *
616      * @param remoteFilePath the absolute path to file on device.
617      * @return A {@link String} containing the contents of the device file, or {@code null} if the
618      *         copy failed for any reason (including problems with the host filesystem)
619      */
pullFileContents(String remoteFilePath)620     public String pullFileContents(String remoteFilePath) throws DeviceNotAvailableException;
621 
622     /**
623      * A convenience method to retrieve a file from the device's external storage, stores it in a
624      * local temporary {@link File}, and return a reference to that {@code File}.
625      *
626      * @param remoteFilePath the path to file on device, relative to the device's external storage
627      *        mountpoint
628      * @return A {@link File} containing the contents of the device file, or {@code null} if the
629      *         copy failed for any reason (including problems with the host filesystem)
630      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
631      *             recovered.
632      */
pullFileFromExternal(String remoteFilePath)633     public File pullFileFromExternal(String remoteFilePath) throws DeviceNotAvailableException;
634 
635     /**
636      * Recursively pull directory contents from device.
637      *
638      * @param deviceFilePath the absolute file path of the remote source
639      * @param localDir the local directory to pull files into
640      * @return <code>true</code> if file was pulled successfully. <code>false</code> otherwise.
641      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
642      * recovered.
643      */
pullDir(String deviceFilePath, File localDir)644     public boolean pullDir(String deviceFilePath, File localDir)
645             throws DeviceNotAvailableException;
646 
647     /**
648      * Push a file to device
649      *
650      * @param localFile the local file to push
651      * @param deviceFilePath the remote destination absolute file path
652      * @return <code>true</code> if file was pushed successfully. <code>false</code> otherwise.
653      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
654      * recovered.
655      */
pushFile(File localFile, String deviceFilePath)656     public boolean pushFile(File localFile, String deviceFilePath)
657             throws DeviceNotAvailableException;
658 
659     /**
660      * Push file created from a string to device
661      *
662      * @param contents the contents of the file to push
663      * @param deviceFilePath the remote destination absolute file path
664      * @return <code>true</code> if string was pushed successfully. <code>false</code> otherwise.
665      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
666      * recovered.
667      */
pushString(String contents, String deviceFilePath)668     public boolean pushString(String contents, String deviceFilePath)
669             throws DeviceNotAvailableException;
670 
671     /**
672      * Recursively push directory contents to device.
673      *
674      * @param localDir the local directory to push
675      * @param deviceFilePath the absolute file path of the remote destination
676      * @return <code>true</code> if file was pushed successfully. <code>false</code> otherwise.
677      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
678      * recovered.
679      */
pushDir(File localDir, String deviceFilePath)680     public boolean pushDir(File localDir, String deviceFilePath)
681             throws DeviceNotAvailableException;
682 
683     /**
684      * Recursively push directory contents to device while excluding some directories that are
685      * filtered.
686      *
687      * @param localDir the local directory to push
688      * @param deviceFilePath the absolute file path of the remote destination
689      * @param excludedDirectories Set of excluded directories names that shouldn't be pushed.
690      * @return <code>true</code> if file was pushed successfully. <code>false</code> otherwise.
691      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
692      *     recovered.
693      */
pushDir(File localDir, String deviceFilePath, Set<String> excludedDirectories)694     public boolean pushDir(File localDir, String deviceFilePath, Set<String> excludedDirectories)
695             throws DeviceNotAvailableException;
696 
697     /**
698      * Incrementally syncs the contents of a local file directory to device.
699      * <p/>
700      * Decides which files to push by comparing timestamps of local files with their remote
701      * equivalents. Only 'newer' or non-existent files will be pushed to device. Thus overhead
702      * should be relatively small if file set on device is already up to date.
703      * <p/>
704      * Hidden files (with names starting with ".") will be ignored.
705      * <p/>
706      * Example usage: syncFiles("/tmp/files", "/sdcard") will created a /sdcard/files directory if
707      * it doesn't already exist, and recursively push the /tmp/files contents to /sdcard/files.
708      *
709      * @param localFileDir the local file directory containing files to recursively push.
710      * @param deviceFilePath the remote destination absolute file path root. All directories in thos
711      *            file path must be readable. ie pushing to /data/local/tmp when adb is not root
712      *            will fail
713      * @return <code>true</code> if files were synced successfully. <code>false</code> otherwise.
714      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
715      *             recovered.
716      */
syncFiles(File localFileDir, String deviceFilePath)717     public boolean syncFiles(File localFileDir, String deviceFilePath)
718             throws DeviceNotAvailableException;
719 
720     /**
721      * Helper method to determine if file on device exists.
722      *
723      * @param deviceFilePath the absolute path of file on device to check
724      * @return <code>true</code> if file exists, <code>false</code> otherwise.
725      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
726      * recovered.
727      */
doesFileExist(String deviceFilePath)728     public boolean doesFileExist(String deviceFilePath) throws DeviceNotAvailableException;
729 
730     /**
731      * Helper method to delete a file or directory on the device.
732      *
733      * @param deviceFilePath The absolute path of the file on the device.
734      * @throws DeviceNotAvailableException
735      */
deleteFile(String deviceFilePath)736     public void deleteFile(String deviceFilePath) throws DeviceNotAvailableException;
737 
738     /**
739      * Retrieve a reference to a remote file on device.
740      *
741      * @param path the file path to retrieve. Can be an absolute path or path relative to '/'. (ie
742      *            both "/system" and "system" syntax is supported)
743      * @return the {@link IFileEntry} or <code>null</code> if file at given <var>path</var> cannot
744      *         be found
745      * @throws DeviceNotAvailableException
746      */
getFileEntry(String path)747     public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException;
748 
749     /**
750      * Returns True if the file path on the device is an executable file, false otherwise.
751      *
752      * @throws DeviceNotAvailableException
753      */
isExecutable(String fullPath)754     public boolean isExecutable(String fullPath) throws DeviceNotAvailableException;
755 
756     /**
757      * Return True if the path on the device is a directory, false otherwise.
758      *
759      * @throws DeviceNotAvailableException
760      */
isDirectory(String deviceFilePath)761     public boolean isDirectory(String deviceFilePath) throws DeviceNotAvailableException;
762 
763     /**
764      * Alternative to using {@link IFileEntry} that sometimes won't work because of permissions.
765      *
766      * @param deviceFilePath is the path on the device where to do the search
767      * @return Array of string containing all the file in a path on the device.
768      * @throws DeviceNotAvailableException
769      */
getChildren(String deviceFilePath)770     public String[] getChildren(String deviceFilePath) throws DeviceNotAvailableException;
771 
772     /**
773      * Helper method to determine amount of free space on device external storage.
774      *
775      * @return the amount of free space in KB
776      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
777      * recovered.
778      */
getExternalStoreFreeSpace()779     public long getExternalStoreFreeSpace() throws DeviceNotAvailableException;
780 
781     /**
782      * Helper method to determine amount of free space on device partition.
783      *
784      * @return the amount of free space in KB
785      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
786      *     recovered.
787      */
getPartitionFreeSpace(String partition)788     public long getPartitionFreeSpace(String partition) throws DeviceNotAvailableException;
789 
790     /**
791      * Returns a mount point.
792      * <p/>
793      * Queries the device directly if the cached info in {@link IDevice} is not available.
794      * <p/>
795      * TODO: move this behavior to {@link IDevice#getMountPoint(String)}
796      *
797      * @param mountName the name of the mount point
798      * @return the mount point or <code>null</code>
799      * @see IDevice#getMountPoint(String)
800      */
getMountPoint(String mountName)801     public String getMountPoint(String mountName);
802 
803     /**
804      * Returns a parsed version of the information in /proc/mounts on the device
805      *
806      * @return A {@link List} of {@link MountPointInfo} containing the information in "/proc/mounts"
807      */
getMountPointInfo()808     public List<MountPointInfo> getMountPointInfo() throws DeviceNotAvailableException;
809 
810     /**
811      * Returns a {@link MountPointInfo} corresponding to the specified mountpoint path, or
812      * <code>null</code> if that path has nothing mounted or otherwise does not appear in
813      * /proc/mounts as a mountpoint.
814      *
815      * @return A {@link List} of {@link MountPointInfo} containing the information in "/proc/mounts"
816      * @see #getMountPointInfo()
817      */
getMountPointInfo(String mountpoint)818     public MountPointInfo getMountPointInfo(String mountpoint) throws DeviceNotAvailableException;
819 
820     /**
821      * Start capturing logcat output from device in the background.
822      * <p/>
823      * Will have no effect if logcat output is already being captured.
824      * Data can be later retrieved via getLogcat.
825      * <p/>
826      * When the device is no longer in use, {@link #stopLogcat()} must be called.
827      * <p/>
828      * {@link #startLogcat()} and {@link #stopLogcat()} do not normally need to be called when
829      * within a TF invocation context, as the TF framework will start and stop logcat.
830      */
startLogcat()831     public void startLogcat();
832 
833     /**
834      * Stop capturing logcat output from device, and discard currently saved logcat data.
835      * <p/>
836      * Will have no effect if logcat output is not being captured.
837      */
stopLogcat()838     public void stopLogcat();
839 
840     /**
841      * Deletes any accumulated logcat data.
842      * <p/>
843      * This is useful for cases when you want to ensure {@link ITestDevice#getLogcat()} only returns
844      * log data produced after a certain point (such as after flashing a new device build, etc).
845      */
clearLogcat()846     public void clearLogcat();
847 
848     /**
849      * Grabs a snapshot stream of the logcat data.
850      *
851      * <p>Works in two modes:
852      * <li>If the logcat is currently being captured in the background, will return up to {@link
853      *     TestDeviceOptions#getMaxLogcatDataSize()} bytes of the current contents of the background
854      *     logcat capture
855      * <li>Otherwise, will return a static dump of the logcat data if device is currently responding
856      */
857     @MustBeClosed
getLogcat()858     public InputStreamSource getLogcat();
859 
860     /**
861      * Grabs a snapshot stream of captured logcat data starting the date provided. The time on the
862      * device should be used {@link #getDeviceDate}.
863      *
864      * <p>
865      *
866      * @param date in millisecond since epoch format of when to start the snapshot until present.
867      *     (can be be obtained using 'date +%s')
868      */
869     @MustBeClosed
getLogcatSince(long date)870     public InputStreamSource getLogcatSince(long date);
871 
872     /**
873      * Grabs a snapshot stream of the last <code>maxBytes</code> of captured logcat data.
874      *
875      * <p>Useful for cases when you want to capture frequent snapshots of the captured logcat data
876      * without incurring the potentially big disk space penalty of getting the entire {@link
877      * #getLogcat()} snapshot.
878      *
879      * @param maxBytes the maximum amount of data to return. Should be an amount that can
880      *     comfortably fit in memory
881      */
882     @MustBeClosed
getLogcat(int maxBytes)883     public InputStreamSource getLogcat(int maxBytes);
884 
885     /**
886      * Get a dump of the current logcat for device. Unlike {@link #getLogcat()}, this method will
887      * always return a static dump of the logcat.
888      *
889      * <p>Has the disadvantage that nothing will be returned if device is not reachable.
890      *
891      * @return a {@link InputStreamSource} of the logcat data. An empty stream is returned if fail
892      *     to capture logcat data.
893      */
894     @MustBeClosed
getLogcatDump()895     public InputStreamSource getLogcatDump();
896 
897     /**
898      * Perform instructions to configure device for testing that after every boot.
899      * <p/>
900      * Should be called after device is fully booted/available
901      * <p/>
902      * In normal circumstances this method doesn't need to be called explicitly, as
903      * implementations should perform these steps automatically when performing a reboot.
904      * <p/>
905      * Where it may need to be called is when device reboots due to other events (eg when a
906      * fastboot update command has completed)
907      *
908      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
909      * recovered.
910      */
postBootSetup()911     public void postBootSetup() throws DeviceNotAvailableException;
912 
913     /**
914      * Reboots the device into bootloader mode.
915      * <p/>
916      * Blocks until device is in bootloader mode.
917      *
918      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
919      * recovered.
920      */
rebootIntoBootloader()921     public void rebootIntoBootloader() throws DeviceNotAvailableException;
922 
923     /**
924      * Returns true if device is in {@link TestDeviceState#FASTBOOT} or {@link
925      * TestDeviceState#FASTBOOTD}.
926      */
isStateBootloaderOrFastbootd()927     public boolean isStateBootloaderOrFastbootd();
928 
929     /**
930      * Reboots the device into adb mode.
931      * <p/>
932      * Blocks until device becomes available.
933      *
934      * @throws DeviceNotAvailableException if device is not available after reboot
935      */
reboot()936     public void reboot() throws DeviceNotAvailableException;
937 
938     /**
939      * Reboots the device into adb mode with given {@code reason} to be persisted across reboot.
940      *
941      * <p>Blocks until device becomes available.
942      *
943      * <p>Last reboot reason can be obtained by querying {@code sys.boot.reason} propety.
944      *
945      * @param reason a reason for this reboot, or {@code null} if no reason is specified.
946      * @throws DeviceNotAvailableException if device is not available after reboot
947      */
reboot(@ullable String reason)948     public void reboot(@Nullable String reason) throws DeviceNotAvailableException;
949 
950     /**
951      * Reboots the device into fastbootd mode.
952      *
953      * <p>Blocks until device is in fastbootd mode.
954      *
955      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
956      *     recovered.
957      */
rebootIntoFastbootd()958     public void rebootIntoFastbootd() throws DeviceNotAvailableException;
959 
960     /**
961      * Reboots only userspace part of device.
962      *
963      * <p>Blocks until device becomes available.
964      *
965      * <p>WARNING. Userspace reboot is currently under active development, use it on your own risk.
966      *
967      * @throws DeviceNotAvailableException if device is not available after reboot
968      */
969     // TODO(ioffe): link to docs around userspace reboot when they are available.
rebootUserspace()970     public void rebootUserspace() throws DeviceNotAvailableException;
971 
972     /**
973      * Reboots the device into adb recovery mode.
974      * <p/>
975      * Blocks until device enters recovery
976      *
977      * @throws DeviceNotAvailableException if device is not available after reboot
978      */
rebootIntoRecovery()979     public void rebootIntoRecovery() throws DeviceNotAvailableException;
980 
981     /**
982      * Reboots the device into adb sideload mode (note that this is a special mode under recovery)
983      *
984      * <p>Blocks until device enters sideload mode
985      *
986      * @throws DeviceNotAvailableException if device is not in sideload after reboot
987      */
rebootIntoSideload()988     public void rebootIntoSideload() throws DeviceNotAvailableException;
989 
990     /**
991      * Reboots the device into adb sideload mode (note that this is a special mode under recovery)
992      *
993      * <p>Blocks until device enters sideload mode
994      *
995      * @param autoReboot whether to automatically reboot the device after sideload
996      * @throws DeviceNotAvailableException if device is not in sideload after reboot
997      */
rebootIntoSideload(boolean autoReboot)998     public void rebootIntoSideload(boolean autoReboot) throws DeviceNotAvailableException;
999 
1000     /**
1001      * An alternate to {@link #reboot()} that only blocks until device is online ie visible to adb.
1002      *
1003      * @throws DeviceNotAvailableException if device is not available after reboot
1004      */
rebootUntilOnline()1005     public void rebootUntilOnline() throws DeviceNotAvailableException;
1006 
1007     /**
1008      * An alternate to {@link #reboot()} that only blocks until device is online ie visible to adb.
1009      *
1010      * @param reason a reason for this reboot, or {@code null} if no reason is specified.
1011      * @throws DeviceNotAvailableException if device is not available after reboot
1012      * @see #reboot(String)
1013      */
rebootUntilOnline(@ullable String reason)1014     public void rebootUntilOnline(@Nullable String reason) throws DeviceNotAvailableException;
1015 
1016     /**
1017      * An alternate to {@link #rebootUserspace()} ()} that only blocks until device is online ie
1018      * visible to adb.
1019      *
1020      * @throws DeviceNotAvailableException if device is not available after reboot
1021      */
rebootUserspaceUntilOnline()1022     public void rebootUserspaceUntilOnline() throws DeviceNotAvailableException;
1023 
1024     /**
1025      * Issues a command to reboot device and returns on command complete and when device is no
1026      * longer visible to adb.
1027      *
1028      * @throws DeviceNotAvailableException
1029      */
nonBlockingReboot()1030     public void nonBlockingReboot() throws DeviceNotAvailableException;
1031 
1032     /**
1033      * Turns on adb root. If the "enable-root" setting is "false", will log a message and
1034      * return without enabling root.
1035      * <p/>
1036      * Enabling adb root may cause device to disconnect from adb. This method will block until
1037      * device is available.
1038      *
1039      * @return <code>true</code> if successful.
1040      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1041      * recovered.
1042      */
enableAdbRoot()1043     public boolean enableAdbRoot() throws DeviceNotAvailableException;
1044 
1045     /**
1046      * Turns off adb root.
1047      * <p/>
1048      * Disabling adb root may cause device to disconnect from adb. This method will block until
1049      * device is available.
1050      *
1051      * @return <code>true</code> if successful.
1052      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1053      * recovered.
1054      */
disableAdbRoot()1055     public boolean disableAdbRoot() throws DeviceNotAvailableException;
1056 
1057     /**
1058      * @return <code>true</code> if device currently has adb root, <code>false</code> otherwise.
1059      *
1060      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1061      * recovered.
1062      */
isAdbRoot()1063     public boolean isAdbRoot() throws DeviceNotAvailableException;
1064 
1065     /**
1066      * Encrypts the device.
1067      * <p/>
1068      * Encrypting the device may be done inplace or with a wipe.  Inplace encryption will not wipe
1069      * any data on the device but normally takes a couple orders of magnitude longer than the wipe.
1070      * <p/>
1071      * This method will reboot the device if it is not already encrypted and will block until device
1072      * is online.  Also, it will not decrypt the device after the reboot.  Therefore, the device
1073      * might not be fully booted and/or ready to be tested when this method returns.
1074      *
1075      * @param inplace if the encryption process should take inplace and the device should not be
1076      * wiped.
1077      * @return <code>true</code> if successful.
1078      * @throws DeviceNotAvailableException if device is not available after reboot.
1079      * @throws UnsupportedOperationException if encryption is not supported on the device.
1080      */
encryptDevice(boolean inplace)1081     public boolean encryptDevice(boolean inplace) throws DeviceNotAvailableException,
1082             UnsupportedOperationException;
1083 
1084     /**
1085      * Unencrypts the device.
1086      * <p/>
1087      * Unencrypting the device may cause device to be wiped and may reboot device. This method will
1088      * block until device is available and ready for testing.  Requires fastboot inorder to wipe the
1089      * userdata partition.
1090      *
1091      * @return <code>true</code> if successful.
1092      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1093      * recovered.
1094      * @throws UnsupportedOperationException if encryption is not supported on the device.
1095      */
unencryptDevice()1096     public boolean unencryptDevice() throws DeviceNotAvailableException,
1097             UnsupportedOperationException;
1098 
1099     /**
1100      * Unlocks the device if the device is in an encrypted state.
1101      * </p>
1102      * This method may restart the framework but will not call {@link #postBootSetup()}. Therefore,
1103      * the device might not be fully ready to be tested when this method returns.
1104      *
1105      * @return <code>true</code> if successful or if the device is unencrypted.
1106      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1107      * recovered.
1108      * @throws UnsupportedOperationException if encryption is not supported on the device.
1109      */
unlockDevice()1110     public boolean unlockDevice() throws DeviceNotAvailableException,
1111             UnsupportedOperationException;
1112 
1113     /**
1114      * Returns if the device is encrypted.
1115      *
1116      * @return <code>true</code> if the device is encrypted.
1117      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1118      * recovered.
1119      */
isDeviceEncrypted()1120     public boolean isDeviceEncrypted() throws DeviceNotAvailableException;
1121 
1122     /**
1123      * Returns if encryption is supported on the device.
1124      *
1125      * @return <code>true</code> if the device supports encryption.
1126      * @throws DeviceNotAvailableException
1127      */
isEncryptionSupported()1128     public boolean isEncryptionSupported() throws DeviceNotAvailableException;
1129 
1130     /**
1131      * Waits for the device to be responsive and available for testing.
1132      *
1133      * @param waitTime the time in ms to wait
1134      * @throws DeviceNotAvailableException if device is still unresponsive after waitTime expires.
1135      */
waitForDeviceAvailable(final long waitTime)1136     public void waitForDeviceAvailable(final long waitTime) throws DeviceNotAvailableException;
1137 
1138     /**
1139      * Waits for the device to be responsive and available for testing.  Uses default timeout.
1140      *
1141      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1142      * recovered.
1143      */
waitForDeviceAvailable()1144     public void waitForDeviceAvailable() throws DeviceNotAvailableException;
1145 
1146     /**
1147      * Blocks until device is visible via adb.
1148      * <p/>
1149      * Note the device may not necessarily be responsive to commands on completion. Use
1150      * {@link #waitForDeviceAvailable()} instead.
1151      *
1152      * @param waitTime the time in ms to wait
1153      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1154      * recovered.
1155      */
waitForDeviceOnline(final long waitTime)1156     public void waitForDeviceOnline(final long waitTime) throws DeviceNotAvailableException;
1157 
1158     /**
1159      * Blocks until device is visible via adb.  Uses default timeout
1160      * <p/>
1161      * Note the device may not necessarily be responsive to commands on completion. Use
1162      * {@link #waitForDeviceAvailable()} instead.
1163      *
1164      * @throws DeviceNotAvailableException if connection with device is lost and cannot be
1165      * recovered.
1166      */
waitForDeviceOnline()1167     public void waitForDeviceOnline() throws DeviceNotAvailableException;
1168 
1169     /**
1170      * Blocks for the device to be not available ie missing from adb
1171      *
1172      * @param waitTime the time in ms to wait
1173      * @return <code>true</code> if device becomes not available before time expires.
1174      *         <code>false</code> otherwise
1175      */
waitForDeviceNotAvailable(final long waitTime)1176     public boolean waitForDeviceNotAvailable(final long waitTime);
1177 
1178     /**
1179      * Blocks for the device to be in the 'adb recovery' state (note this is distinct from
1180      * {@link IDeviceRecovery}).
1181      *
1182      * @param waitTime the time in ms to wait
1183      * @return <code>true</code> if device boots into recovery before time expires.
1184      *         <code>false</code> otherwise
1185      */
waitForDeviceInRecovery(final long waitTime)1186     public boolean waitForDeviceInRecovery(final long waitTime);
1187 
1188     /**
1189      * Blocks for the device to be in the 'adb sideload' state
1190      *
1191      * @param waitTime the time in ms to wait
1192      * @return <code>true</code> if device boots into sideload before time expires. <code>false
1193      *     </code> otherwise
1194      */
waitForDeviceInSideload(final long waitTime)1195     public boolean waitForDeviceInSideload(final long waitTime);
1196 
1197     /**
1198      * Waits for device to be responsive to a basic adb shell command.
1199      *
1200      * @param waitTime the time in ms to wait
1201      * @return <code>true</code> if device becomes responsive before <var>waitTime</var> elapses.
1202      */
waitForDeviceShell(final long waitTime)1203     public boolean waitForDeviceShell(final long waitTime);
1204 
1205     /**
1206      * Blocks until the device's boot complete flag is set.
1207      *
1208      * @param timeOut time in msecs to wait for the flag to be set
1209      * @return true if device's boot complete flag is set within the timeout
1210      * @throws DeviceNotAvailableException
1211      */
waitForBootComplete(long timeOut)1212     public boolean waitForBootComplete(long timeOut) throws DeviceNotAvailableException;
1213 
1214     /**
1215      * Set the {@link IDeviceRecovery} to use for this device. Should be set when device is first
1216      * allocated.
1217      *
1218      * @param recovery the {@link IDeviceRecovery}
1219      */
setRecovery(IDeviceRecovery recovery)1220     public void setRecovery(IDeviceRecovery recovery);
1221 
1222     /**
1223      * Set the current recovery mode to use for the device.
1224      * <p/>
1225      * Used to control what recovery method to use when a device communication problem is
1226      * encountered. Its recommended to only use this method sparingly when needed (for example,
1227      * when framework is down, etc
1228      *
1229      * @param mode whether 'recover till online only' mode should be on or not.
1230      */
setRecoveryMode(RecoveryMode mode)1231     public void setRecoveryMode(RecoveryMode mode);
1232 
1233     /**
1234      * Get the current recovery mode used for the device.
1235      *
1236      * @return the current recovery mode used for the device.
1237      */
getRecoveryMode()1238     public RecoveryMode getRecoveryMode();
1239 
1240     /**
1241      * Get the device's state.
1242      */
getDeviceState()1243     public TestDeviceState getDeviceState();
1244 
1245     /**
1246      * @return <code>true</code> if device is connected to adb-over-tcp, <code>false</code>
1247      * otherwise.
1248      */
isAdbTcp()1249     public boolean isAdbTcp();
1250 
1251     /**
1252      * Switch device to adb-over-tcp mode.
1253      *
1254      * @return the tcp serial number or <code>null</code> if device could not be switched
1255      * @throws DeviceNotAvailableException
1256      */
switchToAdbTcp()1257     public String switchToAdbTcp() throws DeviceNotAvailableException;
1258 
1259     /**
1260      * Switch device to adb over usb mode.
1261      *
1262      * @return <code>true</code> if switch was successful, <code>false</code> otherwise.
1263      * @throws DeviceNotAvailableException
1264      */
switchToAdbUsb()1265     public boolean switchToAdbUsb() throws DeviceNotAvailableException;
1266 
1267     /**
1268      * Get the stream of emulator stdout and stderr
1269      * @return emulator output
1270      */
getEmulatorOutput()1271     public InputStreamSource getEmulatorOutput();
1272 
1273     /**
1274      * Close and delete the emulator output.
1275      */
stopEmulatorOutput()1276     public void stopEmulatorOutput();
1277 
1278     /**
1279      * Get the device API Level. Defaults to {@link #UNKNOWN_API_LEVEL}.
1280      *
1281      * @return an integer indicating the API Level of device
1282      * @throws DeviceNotAvailableException
1283      */
getApiLevel()1284     public int getApiLevel() throws DeviceNotAvailableException;
1285 
1286     /**
1287      * Get the device's first launched API Level. Defaults to {@link #UNKNOWN_API_LEVEL}.
1288      *
1289      * @return an integer indicating the first launched API Level of device
1290      * @throws DeviceNotAvailableException
1291      */
getLaunchApiLevel()1292     public int getLaunchApiLevel() throws DeviceNotAvailableException;
1293 
1294     /**
1295      * Check whether or not a feature is currently supported given a minimally supported level. This
1296      * method takes into account unreleased features yet, before API level is raised.
1297      *
1298      * @param strictMinLevel The strict min possible level that supports the feature.
1299      * @return True if the level is supported. False otherwise.
1300      * @throws DeviceNotAvailableException
1301      */
checkApiLevelAgainstNextRelease(int strictMinLevel)1302     public boolean checkApiLevelAgainstNextRelease(int strictMinLevel)
1303             throws DeviceNotAvailableException;
1304 
1305     /**
1306      * Helper to get the time difference between the device and a given {@link Date}. Use Epoch time
1307      * internally.
1308      *
1309      * @return the difference in milliseconds
1310      */
getDeviceTimeOffset(Date date)1311     public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException;
1312 
1313     /**
1314      * Sets the date on device
1315      * <p>
1316      * Note: setting date on device requires root
1317      * @param date specify a particular date; will use host date if <code>null</code>
1318      * @throws DeviceNotAvailableException
1319      */
setDate(Date date)1320     public void setDate(Date date) throws DeviceNotAvailableException;
1321 
1322     /**
1323      * Return the date of the device in millisecond since epoch.
1324      *
1325      * <p>
1326      *
1327      * @return the date of the device in epoch format.
1328      * @throws DeviceNotAvailableException
1329      */
getDeviceDate()1330     public long getDeviceDate() throws DeviceNotAvailableException;
1331 
1332     /**
1333      * Make the system partition on the device writable. May reboot the device.
1334      * @throws DeviceNotAvailableException
1335      */
remountSystemWritable()1336     public void remountSystemWritable() throws DeviceNotAvailableException;
1337 
1338     /**
1339      * Make the vendor partition on the device writable. May reboot the device.
1340      *
1341      * @throws DeviceNotAvailableException
1342      */
remountVendorWritable()1343     public void remountVendorWritable() throws DeviceNotAvailableException;
1344 
1345     /**
1346      * Returns the key type used to sign the device image
1347      * <p>
1348      * Typically Android devices may be signed with test-keys (like in AOSP) or release-keys
1349      * (controlled by individual device manufacturers)
1350      * @return The signing key if found, null otherwise.
1351      * @throws DeviceNotAvailableException
1352      */
getBuildSigningKeys()1353     public String getBuildSigningKeys() throws DeviceNotAvailableException;
1354 
1355     /**
1356      * Retrieves a bugreport from the device.
1357      * <p/>
1358      * The implementation of this is guaranteed to continue to work on a device without an sdcard
1359      * (or where the sdcard is not yet mounted).
1360      *
1361      * @return An {@link InputStreamSource} which will produce the bugreport contents on demand.  In
1362      *         case of failure, the {@code InputStreamSource} will produce an empty
1363      *         {@link InputStream}.
1364      */
getBugreport()1365     public InputStreamSource getBugreport();
1366 
1367     /**
1368      * Retrieves a bugreportz from the device. Zip format bugreport contains the main bugreport
1369      * and other log files that are useful for debugging.
1370      * <p/>
1371      * Only supported for 'adb version' > 1.0.36
1372      *
1373      * @return a {@link InputStreamSource} of the zip file containing the bugreportz, return null
1374      *         in case of failure.
1375      */
getBugreportz()1376     public InputStreamSource getBugreportz();
1377 
1378     /**
1379      * Helper method to take a bugreport and log it to the reporters.
1380      *
1381      * @param dataName name under which the bugreport will be reported.
1382      * @param listener an {@link ITestLogger} to log the bugreport.
1383      * @return True if the logging was successful, false otherwise.
1384      */
logBugreport(String dataName, ITestLogger listener)1385     public boolean logBugreport(String dataName, ITestLogger listener);
1386 
1387     /**
1388      * Take a bugreport and returns it inside a {@link Bugreport} object to handle it. Return null
1389      * in case of issue.
1390      * </p>
1391      * File referenced in the Bugreport object need to be cleaned via {@link Bugreport#close()}.
1392      */
takeBugreport()1393     public Bugreport takeBugreport();
1394 
1395     /**
1396      * Get the device class.
1397      *
1398      * @return the {@link String} device class.
1399      */
getDeviceClass()1400     public String getDeviceClass();
1401 
1402     /**
1403      * Extra steps for device specific required setup that will be executed on the device prior to
1404      * the invocation flow.
1405      *
1406      * @param info The {@link IBuildInfo} of the device.
1407      * @throws TargetSetupError
1408      * @throws DeviceNotAvailableException
1409      */
preInvocationSetup(IBuildInfo info)1410     public default void preInvocationSetup(IBuildInfo info)
1411             throws TargetSetupError, DeviceNotAvailableException {
1412         // Empty default implementation.
1413     }
1414 
1415     /**
1416      * Extra steps for device specific required clean up that will be executed after the invocation
1417      * is done.
1418      *
1419      * @deprecated Use {@link #postInvocationTearDown(Throwable)} instead.
1420      */
1421     @Deprecated
postInvocationTearDown()1422     public default void postInvocationTearDown() {
1423         postInvocationTearDown(null);
1424     }
1425 
1426     /**
1427      * Extra steps for device specific required clean up that will be executed after the invocation
1428      * is done.
1429      *
1430      * @param invocationException if any, the final exception raised by the invocation failure.
1431      */
postInvocationTearDown(Throwable invocationException)1432     public void postInvocationTearDown(Throwable invocationException);
1433 
1434     /**
1435      * Return true if the device is headless (no screen), false otherwise.
1436      */
isHeadless()1437     public boolean isHeadless() throws DeviceNotAvailableException;
1438 
1439     /**
1440      * Return a {@link DeviceDescriptor} from the device information to get info on it without
1441      * passing the actual device object.
1442      */
getDeviceDescriptor()1443     public DeviceDescriptor getDeviceDescriptor();
1444 
1445     /**
1446      * Returns a cached {@link DeviceDescriptor} if the device is allocated, otherwise returns the
1447      * current {@link DeviceDescriptor}.
1448      */
getCachedDeviceDescriptor()1449     public DeviceDescriptor getCachedDeviceDescriptor();
1450 
1451     /**
1452      * Helper method runs the "pidof" and "stat" command and returns {@link ProcessInfo} object with
1453      * PID and process start time of the given process.
1454      *
1455      * @param processName the proces name String.
1456      * @return ProcessInfo of given processName
1457      */
getProcessByName(String processName)1458     public ProcessInfo getProcessByName(String processName) throws DeviceNotAvailableException;
1459 
1460     /**
1461      * Helper method collects the boot history map with boot time and boot reason.
1462      *
1463      * @return Map of boot time (UTC time in second since Epoch) and boot reason
1464      */
getBootHistory()1465     public Map<Long, String> getBootHistory() throws DeviceNotAvailableException;
1466 
1467     /**
1468      * Helper method collects the boot history map with boot time and boot reason since the given
1469      * time since epoch from device and the time unit specified. The current device utcEpochTime in
1470      * Millisecond can be obtained by method {@link #getDeviceDate}.
1471      *
1472      * @param utcEpochTime the device time since Epoch.
1473      * @param timeUnit the time unit <code>TimeUnit</code>.
1474      * @return Map of boot time (UTC time in second since Epoch) and boot reason
1475      */
getBootHistorySince(long utcEpochTime, TimeUnit timeUnit)1476     public Map<Long, String> getBootHistorySince(long utcEpochTime, TimeUnit timeUnit)
1477             throws DeviceNotAvailableException;
1478 
1479     /**
1480      * Returns the pid of the service or null if something went wrong.
1481      *
1482      * @param process The proces name String.
1483      */
getProcessPid(String process)1484     public String getProcessPid(String process) throws DeviceNotAvailableException;
1485 
1486     /**
1487      * Helper method to check whether device soft-restarted since the UTC time since epoch from
1488      * device and its {@link TimeUnit}. Soft-Restart refers to system_server restarted outside of a
1489      * device hard reboot (for example: requested reboot). The current device utcEpochTime in
1490      * Milliseccond can be obtained by method {@link #getDeviceDate}.
1491      *
1492      * @param utcEpochTime the device time in second since epoch.
1493      * @param timeUnit the time unit <code>TimeUnit</code> for the given utcEpochTime.
1494      * @return {@code true} if device soft-restarted
1495      * @throws RuntimeException if device has abnormal boot reason
1496      * @throws DeviceNotAvailableException
1497      */
deviceSoftRestartedSince(long utcEpochTime, TimeUnit timeUnit)1498     public boolean deviceSoftRestartedSince(long utcEpochTime, TimeUnit timeUnit)
1499             throws DeviceNotAvailableException;
1500 
1501     /**
1502      * Helper method to check if device soft-restarted by comparing current system_server with
1503      * previous system_server {@link ProcessInfo}. Use {@link #getProcessByName} to get {@link
1504      * ProcessInfo}.
1505      *
1506      * @param prevSystemServerProcess the previous system_server process {@link ProcessInfo}.
1507      * @return {@code true} if device soft-restarted
1508      * @throws RuntimeException if device has abnormal boot reason
1509      * @throws DeviceNotAvailableException
1510      */
deviceSoftRestarted(ProcessInfo prevSystemServerProcess)1511     public boolean deviceSoftRestarted(ProcessInfo prevSystemServerProcess)
1512             throws DeviceNotAvailableException;
1513 
1514     /**
1515      * Log a message in the logcat of the device. This is a safe call that will not throw even if
1516      * the logging fails.
1517      *
1518      * @param tag The tag under which we log our message in the logcat.
1519      * @param level The debug level of the message in the logcat.
1520      * @param format The message format.
1521      * @param args the args to be replaced via String.format().
1522      */
logOnDevice(String tag, LogLevel level, String format, Object... args)1523     public void logOnDevice(String tag, LogLevel level, String format, Object... args);
1524 
1525     /** Returns total physical memory size in bytes or -1 in case of internal error */
getTotalMemory()1526     public long getTotalMemory();
1527 
1528     /** Returns the current battery level of a device or Null if battery level unavailable. */
getBattery()1529     public Integer getBattery();
1530 
1531     /**
1532      * Returns the last time Tradefed APIs triggered a reboot in milliseconds since EPOCH as
1533      * returned by {@link System#currentTimeMillis()}.
1534      */
getLastExpectedRebootTimeMillis()1535     public long getLastExpectedRebootTimeMillis();
1536 
1537     /**
1538      * Fetch and return the list of tombstones from the devices. Requires root.
1539      *
1540      * <p>method is best-effort so if one tombstone fails to be pulled for any reason it will be
1541      * missing from the list. Only a {@link DeviceNotAvailableException} will terminate the method
1542      * early.
1543      *
1544      * @return A list of tombstone files, empty if no tombstone.
1545      * @see <a href="https://source.android.com/devices/tech/debug">Tombstones documentation</a>
1546      */
getTombstones()1547     public List<File> getTombstones() throws DeviceNotAvailableException;
1548 
1549 
1550 }
1551