• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.Log.LogLevel;
19 import com.android.tradefed.config.Option;
20 import com.android.tradefed.util.ArrayUtil;
21 
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28 
29 /**
30  * Container for {@link ITestDevice} {@link Option}s
31  */
32 public class TestDeviceOptions {
33 
34     public enum InstanceType {
35         /** A device that we remotely access via ssh and adb connect */
36         GCE,
37         REMOTE_AVD,
38         /**
39          * A remote device inside an emulator that we access via ssh to the instance hosting the
40          * emulator then adb connect.
41          */
42         CUTTLEFISH,
43         REMOTE_NESTED_AVD,
44         /** An android emulator. */
45         EMULATOR,
46         /** Chrome OS VM (betty) */
47         CHEEPS,
48     }
49 
50     public static final int DEFAULT_ADB_PORT = 5555;
51     public static final String INSTANCE_TYPE_OPTION = "instance-type";
52 
53     /** Do not provide a setter method for that Option as it might be misused. */
54     @Option(name = "enable-root", description = "enable adb root on boot.")
55     private boolean mEnableAdbRoot = true;
56 
57     @Option(name = "disable-keyguard",
58             description = "attempt to disable keyguard once boot is complete.")
59     private boolean mDisableKeyguard = true;
60 
61     @Option(name = "enable-logcat", description =
62             "Enable background logcat capture when invocation is running.")
63     private boolean mEnableLogcat = true;
64 
65     @Option(name = "max-tmp-logcat-file", description =
66         "The maximum size of tmp logcat data to retain, in bytes. " +
67         "Only used if --enable-logcat is set")
68     private long mMaxLogcatDataSize = 20 * 1024 * 1024;
69 
70     @Option(name = "logcat-options", description =
71             "Options to be passed down to logcat command, if unspecified, \"-v threadtime\" will " +
72             "be used. Only used if --enable-logcat is set")
73     private String mLogcatOptions = null;
74 
75     @Option(name = "fastboot-timeout", description =
76             "time in ms to wait for a device to boot into fastboot.")
77     private int mFastbootTimeout = 1 * 60 * 1000;
78 
79     @Option(name = "adb-recovery-timeout", description =
80             "time in ms to wait for a device to boot into recovery.")
81     private int mAdbRecoveryTimeout = 1 * 60 * 1000;
82 
83     @Option(name = "reboot-timeout", description =
84             "time in ms to wait for a device to reboot to full system.")
85     private int mRebootTimeout = 2 * 60 * 1000;
86 
87     @Option(name = "use-fastboot-erase", description =
88             "use fastboot erase instead of fastboot format to wipe partitions")
89     private boolean mUseFastbootErase = false;
90 
91     @Option(name = "unencrypt-reboot-timeout", description = "time in ms to wait for the device to "
92             + "format the filesystem and reboot after unencryption")
93     private int mUnencryptRebootTimeout = 0;
94 
95     @Option(name = "online-timeout", description = "default time in ms to wait for the device to "
96             + "be visible on adb.", isTimeVal = true)
97     private long mOnlineTimeout = 1 * 60 * 1000;
98 
99     @Option(name = "available-timeout", description = "default time in ms to wait for the device "
100             + "to be available aka fully boot.")
101     private long mAvailableTimeout = 6 * 60 * 1000;
102 
103     @Option(name = "conn-check-url",
104             description = "default URL to be used for connectivity checks.")
105     private String mConnCheckUrl = "http://www.google.com";
106 
107     @Option(name = "wifi-attempts",
108             description = "default number of attempts to connect to wifi network.")
109     private int mWifiAttempts = 5;
110 
111     @Option(name = "wifi-retry-wait-time",
112             description = "the base wait time in ms between wifi connect retries. "
113             + "The actual wait time would be a multiple of this value.")
114     private int mWifiRetryWaitTime = 60 * 1000;
115 
116     @Option(
117         name = "max-wifi-connect-time",
118         isTimeVal = true,
119         description = "the maximum amount of time to attempt to connect to wifi."
120     )
121     private long mMaxWifiConnectTime = 10 * 60 * 1000;
122 
123     @Option(name = "wifi-exponential-retry",
124             description = "Change the wifi connection retry strategy from a linear wait time into"
125                     + " a binary exponential back-offs when retrying.")
126     private boolean mWifiExpoRetryEnabled = true;
127 
128     @Option(name = "wifiutil-apk-path", description = "path to the wifiutil APK file")
129     private String mWifiUtilAPKPath = null;
130 
131     @Option(name = "post-boot-command",
132             description = "shell command to run after reboots during invocation")
133     private List<String> mPostBootCommands = new ArrayList<String>();
134 
135     @Option(name = "disable-reboot",
136             description = "disables device reboots globally, making them no-ops")
137     private boolean mDisableReboot = false;
138 
139     @Option(name = "cutoff-battery", description =
140             "the minimum battery level required to continue the invocation. Scale: 0-100")
141     private Integer mCutoffBattery = null;
142 
143     @Option(
144         name = "use-content-provider",
145         description =
146                 "Allow to disable the use of the content provider at the device level. "
147                         + "This results in falling back to standard adb push/pull."
148     )
149     private boolean mUseContentProvider = true;
150 
151     // ====================== Options Related to Virtual Devices ======================
152     @Option(
153             name = INSTANCE_TYPE_OPTION,
154             description = "The type of virtual device instance to create")
155     private InstanceType mInstanceType = InstanceType.GCE;
156 
157     @Option(
158             name = "gce-boot-timeout",
159             description = "timeout to wait in ms for GCE to be online.",
160             isTimeVal = true)
161     private long mGceCmdTimeout = 30 * 60 * 1000; // 30 minutes.
162 
163     @Option(name = "gce-driver-path", description = "path of the binary to launch GCE devices")
164     private File mAvdDriverBinary = null;
165 
166     @Option(
167             name = "gce-driver-config-path",
168             description = "path of the config to use to launch GCE devices.")
169     private File mAvdConfigFile = null;
170 
171     @Option(
172             name = "gce-driver-config-test-resource-name",
173             description = "Test resource name of the config to use to launch GCE devices.")
174     private String mAvdConfigTestResourceName;
175 
176     @Option(
177             name = "gce-driver-service-account-json-key-path",
178             description = "path to the service account json key location.")
179     private File mJsonKeyFile = null;
180 
181     @Option(
182             name = "gce-private-key-path",
183             description = "path to the ssh key private key location.")
184     private File mSshPrivateKeyPath = new File("~/.ssh/id_rsa");
185 
186     @Option(name = "gce-driver-log-level", description = "Log level for gce driver")
187     private LogLevel mGceDriverLogLevel = LogLevel.DEBUG;
188 
189     @Option(
190         name = "gce-driver-param",
191         description = "Additional args to pass to gce driver as parameters."
192     )
193     private List<String> mGceDriverParams = new ArrayList<>();
194 
195     @Deprecated
196     @Option(
197         name = "gce-driver-build-id-param",
198         description =
199                 "The parameter to be paired with "
200                         + "build id from build info when passed down to gce driver"
201     )
202     private String mGceDriverBuildIdParam = "build_id";
203 
204     @Option(name = "gce-account", description = "email account to use with GCE driver.")
205     private String mGceAccount = null;
206 
207     @Option(
208         name = "max-gce-attempt",
209         description = "Maximum number of attempts to start Gce before throwing an exception."
210     )
211     private int mGceMaxAttempt = 1;
212 
213     @Option(
214             name = "skip-gce-teardown",
215             description =
216                     "Whether or not to skip the GCE tear down. Skipping tear down will "
217                             + "result in the instance being left.")
218     private boolean mSkipTearDown = false;
219 
220     @Option(
221             name = "wait-gce-teardown",
222             description = "Whether or not to block on gce teardown before proceeding.")
223     private boolean mWaitForGceTearDown = false;
224 
225     @Option(
226             name = "instance-user",
227             description =
228                     "The account to be used to interact with the "
229                             + "outer layer of the GCE VM, e.g. to SSH in")
230     private String mInstanceUser = "root";
231 
232     @Option(
233             name = "remote-adb-port",
234             description = "The port on remote instance where the adb " + "server listens to.")
235     private int mRemoteAdbPort = DEFAULT_ADB_PORT;
236 
237     @Option(
238             name = "base-host-image",
239             description = "The base image to be used for the GCE VM to host emulator.")
240     private String mBaseImage = null;
241 
242     @Option(
243         name = "remote-fetch-file-pattern",
244         description =
245                 "Only for remote VM devices. Allows to specify patterns to fetch file on the "
246                         + "remote VM via scp. Pattern must follow the scp notations."
247     )
248     private Set<String> mRemoteFetchFilePattern = new HashSet<>();
249 
250     // END ====================== Options Related to Virtual Devices ======================
251 
252     /** Check whether adb root should be enabled on boot for this device */
isEnableAdbRoot()253     public boolean isEnableAdbRoot() {
254         return mEnableAdbRoot;
255     }
256 
257     /**
258      * Check whether or not we should attempt to disable the keyguard once boot has completed
259      */
isDisableKeyguard()260     public boolean isDisableKeyguard() {
261         return mDisableKeyguard;
262     }
263 
264     /**
265      * Set whether or not we should attempt to disable the keyguard once boot has completed
266      */
setDisableKeyguard(boolean disableKeyguard)267     public void setDisableKeyguard(boolean disableKeyguard) {
268         mDisableKeyguard = disableKeyguard;
269     }
270 
271     /**
272      * Get the approximate maximum size of a tmp logcat data to retain, in bytes.
273      */
getMaxLogcatDataSize()274     public long getMaxLogcatDataSize() {
275         return mMaxLogcatDataSize;
276     }
277 
278     /**
279      * Set the approximate maximum size of a tmp logcat to retain, in bytes
280      */
setMaxLogcatDataSize(long maxLogcatDataSize)281     public void setMaxLogcatDataSize(long maxLogcatDataSize) {
282         mMaxLogcatDataSize = maxLogcatDataSize;
283     }
284 
285     /**
286      * @return the timeout to boot into fastboot mode in msecs.
287      */
getFastbootTimeout()288     public int getFastbootTimeout() {
289         return mFastbootTimeout;
290     }
291 
292     /**
293      * @param fastbootTimeout the timout in msecs to boot into fastboot mode.
294      */
setFastbootTimeout(int fastbootTimeout)295     public void setFastbootTimeout(int fastbootTimeout) {
296         mFastbootTimeout = fastbootTimeout;
297     }
298 
299     /**
300      * @return the timeout in msecs to boot into recovery mode.
301      */
getAdbRecoveryTimeout()302     public int getAdbRecoveryTimeout() {
303         return mAdbRecoveryTimeout;
304     }
305 
306     /**
307      * @param adbRecoveryTimeout the timeout in msecs to boot into recovery mode.
308      */
setAdbRecoveryTimeout(int adbRecoveryTimeout)309     public void setAdbRecoveryTimeout(int adbRecoveryTimeout) {
310         mAdbRecoveryTimeout = adbRecoveryTimeout;
311     }
312 
313     /**
314      * @return the timeout in msecs for the full system boot.
315      */
getRebootTimeout()316     public int getRebootTimeout() {
317         return mRebootTimeout;
318     }
319 
320     /**
321      * @param rebootTimeout the timeout in msecs for the system to fully boot.
322      */
setRebootTimeout(int rebootTimeout)323     public void setRebootTimeout(int rebootTimeout) {
324         mRebootTimeout = rebootTimeout;
325     }
326 
327     /**
328      * @return whether to use fastboot erase instead of fastboot format to wipe partitions.
329      */
getUseFastbootErase()330     public boolean getUseFastbootErase() {
331         return mUseFastbootErase;
332     }
333 
334     /**
335      * @param useFastbootErase whether to use fastboot erase instead of fastboot format to wipe
336      * partitions.
337      */
setUseFastbootErase(boolean useFastbootErase)338     public void setUseFastbootErase(boolean useFastbootErase) {
339         mUseFastbootErase = useFastbootErase;
340     }
341 
342     /**
343      * @return the timeout in msecs for the filesystem to be formatted and the device to reboot
344      * after unencryption.
345      */
getUnencryptRebootTimeout()346     public int getUnencryptRebootTimeout() {
347         return mUnencryptRebootTimeout;
348     }
349 
350     /**
351      * @param unencryptRebootTimeout the timeout in msecs for the filesystem to be formatted and
352      * the device to reboot after unencryption.
353      */
setUnencryptRebootTimeout(int unencryptRebootTimeout)354     public void setUnencryptRebootTimeout(int unencryptRebootTimeout) {
355         mUnencryptRebootTimeout = unencryptRebootTimeout;
356     }
357 
358     /**
359      * @return the default time in ms to to wait for a device to be online.
360      */
getOnlineTimeout()361     public long getOnlineTimeout() {
362         return mOnlineTimeout;
363     }
364 
setOnlineTimeout(long onlineTimeout)365     public void setOnlineTimeout(long onlineTimeout) {
366         mOnlineTimeout = onlineTimeout;
367     }
368 
369     /**
370      * @return the default time in ms to to wait for a device to be available.
371      */
getAvailableTimeout()372     public long getAvailableTimeout() {
373         return mAvailableTimeout;
374     }
375 
376     /**
377      * @return the default URL to be used for connectivity tests.
378      */
getConnCheckUrl()379     public String getConnCheckUrl() {
380         return mConnCheckUrl;
381     }
382 
setConnCheckUrl(String url)383     public void setConnCheckUrl(String url) {
384       mConnCheckUrl = url;
385     }
386 
387     /**
388      * @return true if background logcat capture is enabled
389      */
isLogcatCaptureEnabled()390     public boolean isLogcatCaptureEnabled() {
391         return mEnableLogcat;
392     }
393 
394     /**
395      * @return the default number of attempts to connect to wifi network.
396      */
getWifiAttempts()397     public int getWifiAttempts() {
398         return mWifiAttempts;
399     }
400 
setWifiAttempts(int wifiAttempts)401     public void setWifiAttempts(int wifiAttempts) {
402         mWifiAttempts = wifiAttempts;
403     }
404 
405     /**
406      * @return the base wait time between wifi connect retries.
407      */
getWifiRetryWaitTime()408     public int getWifiRetryWaitTime() {
409         return mWifiRetryWaitTime;
410     }
411 
412     /** @return the maximum time to attempt to connect to wifi. */
getMaxWifiConnectTime()413     public long getMaxWifiConnectTime() {
414         return mMaxWifiConnectTime;
415     }
416 
417     /**
418      * @return a list of shell commands to run after reboots.
419      */
getPostBootCommands()420     public List<String> getPostBootCommands() {
421         return mPostBootCommands;
422     }
423 
424     /**
425      * @return the minimum battery level to continue the invocation.
426      */
getCutoffBattery()427     public Integer getCutoffBattery() {
428         return mCutoffBattery;
429     }
430 
431     /**
432      * set the minimum battery level to continue the invocation.
433      */
setCutoffBattery(int cutoffBattery)434     public void setCutoffBattery(int cutoffBattery) {
435         if (cutoffBattery < 0 || cutoffBattery > 100) {
436             // Prevent impossible value.
437             throw new RuntimeException(String.format("Battery cutoff wasn't changed,"
438                     + "the value %s isn't within possible range (0-100).", cutoffBattery));
439         }
440         mCutoffBattery = cutoffBattery;
441     }
442 
443     /**
444      * @return the configured logcat options
445      */
getLogcatOptions()446     public String getLogcatOptions() {
447         return mLogcatOptions;
448     }
449 
450     /**
451      * Set the options to be passed down to logcat
452      */
setLogcatOptions(String logcatOptions)453     public void setLogcatOptions(String logcatOptions) {
454         mLogcatOptions = logcatOptions;
455     }
456 
457     /**
458      * @return if device reboot should be disabled
459      */
shouldDisableReboot()460     public boolean shouldDisableReboot() {
461         return mDisableReboot;
462     }
463 
464     /**
465      * @return if the exponential retry strategy should be used.
466      */
isWifiExpoRetryEnabled()467     public boolean isWifiExpoRetryEnabled() {
468         return mWifiExpoRetryEnabled;
469     }
470 
471     /** @return the wifiutil apk path */
getWifiUtilAPKPath()472     public String getWifiUtilAPKPath() {
473         return mWifiUtilAPKPath;
474     }
475 
476     /** Returns the instance type of virtual device that should be created */
getInstanceType()477     public InstanceType getInstanceType() {
478         return mInstanceType;
479     }
480 
481     /** Returns whether or not the Tradefed content provider can be used to push/pull files. */
shouldUseContentProvider()482     public boolean shouldUseContentProvider() {
483         return mUseContentProvider;
484     }
485 
486     // =========================== Getter and Setter for Virtual Devices
487     /** Return the Gce Avd timeout for the instance to come online. */
getGceCmdTimeout()488     public long getGceCmdTimeout() {
489         return mGceCmdTimeout;
490     }
491 
492     /** Set the Gce Avd timeout for the instance to come online. */
setGceCmdTimeout(long gceCmdTimeout)493     public void setGceCmdTimeout(long gceCmdTimeout) {
494         mGceCmdTimeout = gceCmdTimeout;
495     }
496 
497     /** Return the path to the binary to start the Gce Avd instance. */
getAvdDriverBinary()498     public File getAvdDriverBinary() {
499         return mAvdDriverBinary;
500     }
501 
502     /** Set the path to the binary to start the Gce Avd instance. */
setAvdDriverBinary(File avdDriverBinary)503     public void setAvdDriverBinary(File avdDriverBinary) {
504         mAvdDriverBinary = avdDriverBinary;
505     }
506 
507     /** Return the Gce Avd config file to start the instance. */
getAvdConfigFile()508     public File getAvdConfigFile() {
509         return mAvdConfigFile;
510     }
511 
512     /** Set the Gce Avd config file to start the instance. */
setAvdConfigFile(File avdConfigFile)513     public void setAvdConfigFile(File avdConfigFile) {
514         mAvdConfigFile = avdConfigFile;
515     }
516 
517     /** Return the Gce Avd config test resource name to start the instance. */
getAvdConfigTestResourceName()518     public String getAvdConfigTestResourceName() {
519         return mAvdConfigTestResourceName;
520     }
521 
522     /** @return the service account json key file. */
getSerivceAccountJsonKeyFile()523     public File getSerivceAccountJsonKeyFile() {
524         return mJsonKeyFile;
525     }
526 
527     /**
528      * Set the service account json key file.
529      *
530      * @param jsonKeyFile the key file.
531      */
setServiceAccountJsonKeyFile(File jsonKeyFile)532     public void setServiceAccountJsonKeyFile(File jsonKeyFile) {
533         mJsonKeyFile = jsonKeyFile;
534     }
535 
536     /** Return the path of the ssh key to use for operations with the Gce Avd instance. */
getSshPrivateKeyPath()537     public File getSshPrivateKeyPath() {
538         return mSshPrivateKeyPath;
539     }
540 
541     /** Set the path of the ssh key to use for operations with the Gce Avd instance. */
setSshPrivateKeyPath(File sshPrivateKeyPath)542     public void setSshPrivateKeyPath(File sshPrivateKeyPath) {
543         mSshPrivateKeyPath = sshPrivateKeyPath;
544     }
545 
546     /** Return the log level of the Gce Avd driver. */
getGceDriverLogLevel()547     public LogLevel getGceDriverLogLevel() {
548         return mGceDriverLogLevel;
549     }
550 
551     /** Set the log level of the Gce Avd driver. */
setGceDriverLogLevel(LogLevel mGceDriverLogLevel)552     public void setGceDriverLogLevel(LogLevel mGceDriverLogLevel) {
553         this.mGceDriverLogLevel = mGceDriverLogLevel;
554     }
555 
556     /** Return the additional GCE driver parameters provided via option */
getGceDriverParams()557     public List<String> getGceDriverParams() {
558         return mGceDriverParams;
559     }
560 
561     /** Set the GCE driver parameter that should be paired with the build id from build info */
setGceDriverBuildIdParam(String gceDriverBuildIdParam)562     public void setGceDriverBuildIdParam(String gceDriverBuildIdParam) {
563         mGceDriverBuildIdParam = gceDriverBuildIdParam;
564     }
565 
566     /** Return the GCE driver parameter that should be paired with the build id from build info */
getGceDriverBuildIdParam()567     public String getGceDriverBuildIdParam() {
568         return mGceDriverBuildIdParam;
569     }
570 
571     /** Return the gce email account to use with the driver */
getGceAccount()572     public String getGceAccount() {
573         return mGceAccount;
574     }
575 
576     /** Return the max number of attempts to start a gce device */
getGceMaxAttempt()577     public int getGceMaxAttempt() {
578         if (mGceMaxAttempt < 1) {
579             throw new RuntimeException("--max-gce-attempt cannot be bellow 1 attempt.");
580         }
581         return mGceMaxAttempt;
582     }
583 
584     /** Set the max number of attempts to start a gce device */
setGceMaxAttempt(int gceMaxAttempt)585     public void setGceMaxAttempt(int gceMaxAttempt) {
586         mGceMaxAttempt = gceMaxAttempt;
587     }
588 
589     /** Returns true if GCE tear down should be skipped. False otherwise. */
shouldSkipTearDown()590     public boolean shouldSkipTearDown() {
591         return mSkipTearDown;
592     }
593 
594     /** Returns true if we should block on GCE tear down completion before proceeding. */
waitForGceTearDown()595     public boolean waitForGceTearDown() {
596         return mWaitForGceTearDown;
597     }
598 
599     /** Returns the instance type of GCE virtual device that should be created */
getInstanceUser()600     public String getInstanceUser() {
601         return mInstanceUser;
602     }
603 
604     /** Returns the remote port in instance that the adb server listens to */
getRemoteAdbPort()605     public int getRemoteAdbPort() {
606         return mRemoteAdbPort;
607     }
608 
609     /** Returns the base image name to be used for the current instance */
getBaseImage()610     public String getBaseImage() {
611         return mBaseImage;
612     }
613 
614     /** Returns the list of pattern to attempt to fetch via scp. */
getRemoteFetchFilePattern()615     public Set<String> getRemoteFetchFilePattern() {
616         return mRemoteFetchFilePattern;
617     }
618 
getCreateCommandByInstanceType(InstanceType type)619     public static String getCreateCommandByInstanceType(InstanceType type) {
620         switch (type) {
621             case CHEEPS:
622             case GCE:
623             case REMOTE_AVD:
624                 return "create";
625             case CUTTLEFISH:
626             case REMOTE_NESTED_AVD:
627                 return "create_cf";
628             case EMULATOR:
629                 return "create_gf";
630         }
631         throw new RuntimeException("Unexpected InstanceType: " + type);
632     }
633 
getExtraParamsByInstanceType(InstanceType type, String baseImage)634     public static List<String> getExtraParamsByInstanceType(InstanceType type, String baseImage) {
635         if (InstanceType.EMULATOR.equals(type)) {
636             // TODO(b/119440413) remove when base image can be passed via extra gce driver params
637             List<String> params = ArrayUtil.list();
638             if (baseImage != null) {
639                 params.add("--base_image");
640                 params.add(baseImage);
641             }
642             return params;
643         }
644         return Collections.emptyList();
645     }
646 }
647