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.command;
17 
18 import com.android.tradefed.config.ConfigurationException;
19 import com.android.tradefed.config.Option;
20 import com.android.tradefed.config.Option.Importance;
21 import com.android.tradefed.config.OptionCopier;
22 import com.android.tradefed.device.metric.AutoLogCollector;
23 import com.android.tradefed.log.LogUtil.CLog;
24 import com.android.tradefed.util.UniqueMultiMap;
25 
26 import java.io.File;
27 import java.time.Duration;
28 import java.util.ArrayList;
29 import java.util.LinkedHashMap;
30 import java.util.LinkedHashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34 
35 /**
36  * Implementation of {@link ICommandOptions}.
37  */
38 public class CommandOptions implements ICommandOptions {
39 
40     @Option(name = "help", description =
41         "display the help text for the most important/critical options.",
42         importance = Importance.ALWAYS)
43     private boolean mHelpMode = false;
44 
45     @Option(name = "help-all", description = "display the full help text for all options.",
46             importance = Importance.ALWAYS)
47     private boolean mFullHelpMode = false;
48 
49     public static final String DRY_RUN_OPTION = "dry-run";
50     public static final String NOISY_DRY_RUN_OPTION = "noisy-dry-run";
51 
52     @Option(
53         name = DRY_RUN_OPTION,
54         description =
55                 "build but don't actually run the command.  Intended as a quick check "
56                         + "to ensure that a command is runnable.",
57         importance = Importance.ALWAYS
58     )
59     private boolean mDryRunMode = false;
60 
61     @Option(
62         name = NOISY_DRY_RUN_OPTION,
63         description =
64                 "build but don't actually run the command.  This version prints the "
65                         + "command to the console.  Intended for cmdfile debugging.",
66         importance = Importance.ALWAYS
67     )
68     private boolean mNoisyDryRunMode = false;
69 
70     @Option(name = "min-loop-time", description =
71             "the minimum invocation time in ms when in loop mode.")
72     private Long mMinLoopTime = 10L * 60L * 1000L;
73 
74     public static final String TEST_TAG_OPTION = "test-tag";
75 
76     @Option(name = TEST_TAG_OPTION, description = "Identifier for the invocation during reporting.")
77     private String mTestTag = "stub";
78 
79     @Option(name = "test-tag-suffix", description = "suffix for test-tag. appended to test-tag to "
80             + "represents some variants of one test.")
81     private String mTestTagSuffix = null;
82 
83     @Option(name = "loop", description = "keep running continuously.",
84             importance = Importance.ALWAYS)
85     private boolean mLoopMode = false;
86 
87     @Option(name = "max-loops", description = "the maximum number of loops.")
88     private long mMaxLoopCount = Long.MAX_VALUE;
89 
90     @Option(name = "all-devices", description =
91             "fork this command to run on all connected devices.")
92     private boolean mAllDevices = false;
93 
94     @Option(name = "bugreport-on-invocation-ended", description =
95             "take a bugreport when the test invocation has ended")
96     private boolean mTakeBugreportOnInvocationEnded = false;
97 
98     @Option(name = "bugreportz-on-invocation-ended", description = "Attempt to take a bugreportz "
99             + "instead of bugreport during the test invocation final bugreport.")
100     private boolean mTakeBugreportzOnInvocationEnded = false;
101 
102     @Option(
103             name = "disable-conditional-bugreport",
104             description =
105                     "Disable the optimization to capture ANR instead of bugreport if no failure.")
106     private boolean mDisableConditionalBugreport = false;
107 
108     @Option(name = "invocation-timeout", description =
109             "the maximum time to wait for an invocation to terminate before attempting to force"
110             + "stop it.", isTimeVal = true)
111     private long mInvocationTimeout = 0;
112 
113     @Option(name = "shard-count", description =
114             "the number of total shards to run. Without --shard-index option, this will cause " +
115             "the command to spawn multiple shards in the current TF instance. With --shard-index " +
116             "option, it will cause the command to run a single shard of tests only.")
117     private Integer mShardCount;
118 
119     @Option(name = "shard-index", description =
120             "the index of shard to run. Only set if shard-count > 1 and the value is in range " +
121             "[0, shard-count)")
122     private Integer mShardIndex;
123 
124     @Option(name = "optimize-mainline-test", description =
125             "Whether or not to optimize the list of test modules for mainline.")
126     private boolean mOptimizeMainlineTest;
127 
128     @Option(
129         name = "enable-token-sharding",
130         description = "Whether or not to allow sharding with the token support enabled."
131     )
132     private boolean mTokenSharding = false;
133 
134     @Option(
135         name = "dynamic-sharding",
136         description =
137                 "Allow to dynamically move IRemoteTest from one shard to another. Only for local "
138                         + "sharding."
139     )
140     private boolean mDynamicSharding = true;
141 
142     @Option(
143             name = "remote-dynamic-sharding",
144             description =
145                     "Enable use of the dynamic sharding service to load balance across multiple"
146                             + " hosts.")
147     private boolean mRemoteDynamicSharding = false;
148 
149     @Option(
150             name = "use-even-module-sharding",
151             description =
152                     "Enable use of a strategy that attempts to distribute number of "
153                             + "modules evenly across shards")
154     private boolean mEvenModuleSharding = false;
155 
156     public static final String INVOCATION_DATA = "invocation-data";
157 
158     @Option(
159             name = INVOCATION_DATA,
160             description =
161                     "A map of values that describe the invocation, these values will be added to"
162                             + " the invocation context.")
163     private UniqueMultiMap<String, String> mInvocationData = new UniqueMultiMap<>();
164 
165     public static final String USE_SANDBOX = "use-sandbox";
166     public static final String ENABLE_SANDBOX_TEST_MODE = "sandbox-test-mode";
167     public static final String USE_REMOTE_SANDBOX = "use-remote-sandbox";
168 
169     @Option(
170             name = "remote-files",
171             description = "A list of files references to store in build info")
172     private Set<String> mRemoteFiles = new LinkedHashSet<>();
173 
174     @Option(
175         name = USE_SANDBOX,
176         description = "Set if the invocation should use a sandbox to run or not."
177     )
178     private boolean mUseSandbox = false;
179 
180     @Option(
181             name = ENABLE_SANDBOX_TEST_MODE,
182             description =
183                     "Sandbox test mode where the sandbox will use itself to generate another layer "
184                             + "of sandboxing. This is used for the sandbox to validate itself.")
185     private boolean mSandboxTestMode = false;
186 
187     @Option(
188         name = USE_REMOTE_SANDBOX,
189         description = "Whether or not to trigger --use-sandbox in the remote invocation."
190     )
191     private boolean mUseRemoteSandbox = false;
192 
193     @Option(
194             name = "deviceless-remote-exec",
195             description = "Whether or not to trigger --null-deviec in the remote invocation.")
196     private boolean mDevicelessRemoteExecution = false;
197 
198     @Deprecated
199     @Option(
200             name = "parallel-remote-setup",
201             description =
202                     "For remote sharded invocation, whether or not to attempt the setup in"
203                             + " parallel.")
204     private boolean mUseParallelRemoteSetup = false;
205 
206     @Option(
207             name = "parallel-pre-invocation-setup",
208             description = "Whether to execute pre-invocation setup in parallel.")
209     private boolean mUseParallelPreInvocationSetup = false;
210 
211     @Option(
212             name = "parallel-pre-invocation-setup-timeout",
213             description = "Timeout for parallel pre-invocation setup.")
214     private Duration mParallelPreInvocationSetupTimeout = Duration.ofMinutes(30L);
215 
216     @Option(name = "parallel-setup", description = "Whether to attempt the setup in parallel.")
217     private boolean mUseParallelSetup = false;
218 
219     @Option(name = "parallel-setup-timeout", description = "Timeout to use during parallel setup.")
220     private Duration mParallelSetupTimeout = Duration.ofMinutes(30L);
221 
222     @Option(
223             name = "replicate-parent-setup",
224             description =
225                     "For remote sharded invocation, whether or not to replicate parent setup on "
226                             + "all devices.")
227     private boolean mReplicateParentSetup = false;
228 
229     @Option(
230         name = "report-module-progression",
231         description = "For remote invocation, whether or not to report progress at module level."
232     )
233     private boolean mReportModuleProgression = false;
234 
235     @Deprecated
236     @Option(
237             name = "extra-postsubmit-remote-instance",
238             description =
239                     "Option that allows to run more instances in the remote VM in postsubmit. "
240                             + "Used for experimentation.")
241     private int mExtraRemoteInstancePostsubmit = 0;
242 
243     @Option(
244         name = "auto-collect",
245         description =
246                 "Specify a set of collectors that will be automatically managed by the harness "
247                         + "to collect logs."
248     )
249     private Set<AutoLogCollector> mAutoCollectors = new LinkedHashSet<>();
250 
251     @Option(
252             name = "experiment-enabled",
253             description = "A feature flag used to enable experimental flags.")
254     private boolean mExperimentEnabled = false;
255 
256     @Option(
257             name = "experimental-flags",
258             description = "Map of experimental flags that can be used for feature gating projects.")
259     private Map<String, String> mExperimentalFlags = new LinkedHashMap<>();
260 
261     @Deprecated
262     @Option(
263         name = "logcat-on-failure",
264         description = "take a logcat snapshot on every test failure."
265     )
266     private boolean mLogcatOnFailure = false;
267 
268     @Deprecated
269     @Option(name = "screenshot-on-failure", description = "Take a screenshot on every test failure")
270     private boolean mScreenshotOnFailure = false;
271 
272     @Option(
273         name = "host-log-suffix",
274         description = "Suffix to add to Tradefed host_log before logging it."
275     )
276     private String mHostLogSuffix = null;
277 
278     @Option(
279             name = "early-device-release",
280             description = "Feature flag to release the device as soon as done with it.")
281     private boolean mEnableEarlyDeviceRelease = true;
282 
283     @Option(
284             name = "delegated-early-device-release",
285             description =
286                     "Feature flag to enable early device release when running in delegated mode.")
287     private boolean mEnableDelegatedEarlyDeviceRelease = true;
288 
289     @Option(
290             name = "dynamic-download-args",
291             description =
292                     "Extra args passed to the IRemoteFileResolver interface for dynamic download "
293                             + "in the queryArgs.")
294     private Map<String, String> mDynamicDownloadArgs = new LinkedHashMap<>();
295 
296     @Option(
297             name = "report-counted-test-cases",
298             description = "Whether or not to report the number of test cases per test types.")
299     private boolean mCountTestCases = true;
300 
301     @Option(
302             name = "report-passed-tests",
303             description = "Whether or not to report the passed tests in a file.")
304     private boolean mReportPassedTests = true;
305 
306     @Option(
307             name = "filter-previous-passed",
308             description = "Feature flag to test filtering previously passed tests.")
309     private boolean mTestFilterPassed = true;
310 
311     @Option(
312             name = "report-invocation-complete-logs",
313             description = "Whether or not to attempt to report the logs until invocationComplete.")
314     private boolean mReportInvocationCompleteLogs = true;
315 
316     @Option(
317             name = "disable-invocation-setup-and-teardown",
318             description = "Disable the pre-invocation setup and post-invocation teardown phases.")
319     private boolean mDisableInvocationSetupAndTeardown = false;
320 
321     @Option(
322             name = "multi-device-count",
323             description = "The number of devices for multi-device tests. For a new feature "
324                                   + "under developing, not for other uses.")
325     private Integer mMultiDeviceCount;
326 
327     @Option(name = "enable-tracing", description = "Enable test invocation tracing.")
328     private boolean mTracingEnabled = true;
329 
330     public static final String JDK_FOLDER_OPTION_NAME = "jdk-folder-for-subprocess";
331 
332     @Option(
333             name = "parallel-dynamic-download",
334             description = "Enable parallel download of dynamic files when supported.")
335     private boolean mEnableParallelDynamicDownload = false;
336 
337     @Option(
338             name = JDK_FOLDER_OPTION_NAME,
339             description =
340                     "Whenever the java execution is forked to another subprocess, use this jdk"
341                             + " folder instead of current one.")
342     private File mJdkFolder;
343 
344     /**
345      * Set the help mode for the config.
346      * <p/>
347      * Exposed for testing.
348      */
setHelpMode(boolean helpMode)349     void setHelpMode(boolean helpMode) {
350         mHelpMode = helpMode;
351     }
352 
353     /**
354      * {@inheritDoc}
355      */
356     @Override
isHelpMode()357     public boolean isHelpMode() {
358         return mHelpMode;
359     }
360 
361     /**
362      * {@inheritDoc}
363      */
364     @Override
isFullHelpMode()365     public boolean isFullHelpMode() {
366         return mFullHelpMode;
367     }
368 
369     /**
370      * Set the dry run mode for the config.
371      * <p/>
372      * Exposed for testing.
373      */
setDryRunMode(boolean dryRunMode)374     void setDryRunMode(boolean dryRunMode) {
375         mDryRunMode = dryRunMode;
376     }
377 
378     /**
379      * {@inheritDoc}
380      */
381     @Override
isDryRunMode()382     public boolean isDryRunMode() {
383         return mDryRunMode || mNoisyDryRunMode;
384     }
385 
386     /**
387      * {@inheritDoc}
388      */
389     @Override
isNoisyDryRunMode()390     public boolean isNoisyDryRunMode() {
391         return mNoisyDryRunMode;
392     }
393 
394     /**
395      * Set the loop mode for the config.
396      */
397     @Override
setLoopMode(boolean loopMode)398     public void setLoopMode(boolean loopMode) {
399         mLoopMode = loopMode;
400     }
401 
402     /**
403      * {@inheritDoc}
404      */
405     @Override
isLoopMode()406     public boolean isLoopMode() {
407         return mLoopMode;
408     }
409 
410     /**
411      * Set the min loop time for the config.
412      * <p/>
413      * Exposed for testing.
414      */
setMinLoopTime(long loopTime)415     void setMinLoopTime(long loopTime) {
416         mMinLoopTime = loopTime;
417     }
418 
419     /**
420      * {@inheritDoc}
421      */
422     @Override
getLoopTime()423     public long getLoopTime() {
424         return mMinLoopTime;
425     }
426 
427     @Override
getMaxLoopCount()428     public long getMaxLoopCount() {
429         return mMaxLoopCount;
430     }
431 
432     @Override
clone()433     public ICommandOptions clone() {
434         CommandOptions clone = new CommandOptions();
435         try {
436             OptionCopier.copyOptions(this, clone);
437         } catch (ConfigurationException e) {
438             CLog.e("failed to clone command options: %s", e.getMessage());
439         }
440         return clone;
441     }
442 
443     /**
444      * {@inheritDoc}
445      */
446     @Override
runOnAllDevices()447     public boolean runOnAllDevices() {
448         return mAllDevices;
449     }
450 
451     /**
452      * {@inheritDoc}
453      */
454     @Override
takeBugreportOnInvocationEnded()455     public boolean takeBugreportOnInvocationEnded() {
456         return mTakeBugreportOnInvocationEnded;
457     }
458 
459     /** {@inheritDoc} */
460     @Override
setBugreportOnInvocationEnded(boolean takeBugreport)461     public void setBugreportOnInvocationEnded(boolean takeBugreport) {
462         mTakeBugreportOnInvocationEnded = takeBugreport;
463     }
464 
465     /**
466      * {@inheritDoc}
467      */
468     @Override
takeBugreportzOnInvocationEnded()469     public boolean takeBugreportzOnInvocationEnded() {
470         return mTakeBugreportzOnInvocationEnded;
471     }
472 
473     /** {@inheritDoc} */
474     @Override
setBugreportzOnInvocationEnded(boolean takeBugreportz)475     public void setBugreportzOnInvocationEnded(boolean takeBugreportz) {
476         mTakeBugreportzOnInvocationEnded = takeBugreportz;
477     }
478 
479     /** {@inheritDoc} */
480     @Override
isConditionalBugreportDisabled()481     public boolean isConditionalBugreportDisabled() {
482         return mDisableConditionalBugreport;
483     }
484 
485     /**
486      * {@inheritDoc}
487      */
488     @Override
getInvocationTimeout()489     public long getInvocationTimeout() {
490         return mInvocationTimeout;
491     }
492 
493     /**
494      * {@inheritDoc}
495      */
496     @Override
setInvocationTimeout(Long invocationTimeout)497     public void setInvocationTimeout(Long invocationTimeout) {
498         mInvocationTimeout = invocationTimeout;
499     }
500 
501     /**
502      * {@inheritDoc}
503      */
504     @Override
getOptimizeMainlineTest()505     public boolean getOptimizeMainlineTest() {
506         return mOptimizeMainlineTest;
507     }
508 
509     /**
510      * {@inheritDoc}
511      */
512     @Override
getShardCount()513     public Integer getShardCount() {
514         return mShardCount;
515     }
516 
517     /**
518      * {@inheritDoc}
519      */
520     @Override
setShardCount(Integer shardCount)521     public void setShardCount(Integer shardCount) {
522         mShardCount = shardCount;
523     }
524 
525     /**
526      * {@inheritDoc}
527      */
528     @Override
getShardIndex()529     public Integer getShardIndex() {
530         return mShardIndex;
531     }
532 
533     /**
534      * {@inheritDoc}
535      */
536     @Override
setShardIndex(Integer shardIndex)537     public void setShardIndex(Integer shardIndex) {
538         mShardIndex = shardIndex;
539     }
540 
541     /** {@inheritDoc} */
542     @Override
shouldUseTokenSharding()543     public boolean shouldUseTokenSharding() {
544         return mTokenSharding;
545     }
546 
547     /**
548      * {@inheritDoc}
549      */
550     @Override
setTestTag(String testTag)551     public void setTestTag(String testTag) {
552        mTestTag = testTag;
553     }
554 
555     /**
556      * {@inheritDoc}
557      */
558     @Override
getTestTag()559     public String getTestTag() {
560         return mTestTag;
561     }
562 
563     /**
564      * {@inheritDoc}
565      */
566     @Override
getTestTagSuffix()567     public String getTestTagSuffix() {
568         return mTestTagSuffix;
569     }
570 
571     /** {@inheritDoc} */
572     @Override
shouldUseDynamicSharding()573     public boolean shouldUseDynamicSharding() {
574         return mDynamicSharding;
575     }
576 
577     /** {@inheritDoc} */
578     @Override
getInvocationData()579     public UniqueMultiMap<String, String> getInvocationData() {
580         return mInvocationData;
581     }
582 
583     /** {@inheritDoc} */
584     @Override
getRemoteFiles()585     public Set<String> getRemoteFiles() {
586         return mRemoteFiles;
587     }
588 
589     /** {@inheritDoc} */
590     @Override
shouldUseSandboxing()591     public boolean shouldUseSandboxing() {
592         return mUseSandbox;
593     }
594 
595     /** {@inheritDoc} */
596     @Override
setShouldUseSandboxing(boolean use)597     public void setShouldUseSandboxing(boolean use) {
598         mUseSandbox = use;
599     }
600 
601     /** {@inheritDoc} */
602     @Override
shouldUseSandboxTestMode()603     public boolean shouldUseSandboxTestMode() {
604         return mSandboxTestMode;
605     }
606 
607     /** {@inheritDoc} */
608     @Override
setUseSandboxTestMode(boolean use)609     public void setUseSandboxTestMode(boolean use) {
610         mSandboxTestMode = use;
611     }
612 
613     /** {@inheritDoc} */
614     @Override
shouldUseRemoteSandboxMode()615     public boolean shouldUseRemoteSandboxMode() {
616         return mUseRemoteSandbox;
617     }
618 
619     /** {@inheritDoc} */
620     @Override
isRemoteInvocationDeviceless()621     public boolean isRemoteInvocationDeviceless() {
622         return mDevicelessRemoteExecution;
623     }
624 
625     /** {@inheritDoc} */
626     @Override
getAutoLogCollectors()627     public Set<AutoLogCollector> getAutoLogCollectors() {
628         return mAutoCollectors;
629     }
630 
631     /** {@inheritDoc} */
632     @Override
setAutoLogCollectors(Set<AutoLogCollector> autoLogCollectors)633     public void setAutoLogCollectors(Set<AutoLogCollector> autoLogCollectors) {
634         mAutoCollectors = autoLogCollectors;
635     }
636 
637     /** {@inheritDoc} */
638     @Override
isExperimentEnabled()639     public boolean isExperimentEnabled() {
640         return mExperimentEnabled;
641     }
642 
643     /** {@inheritDoc} */
644     @Override
getExperimentalFlags()645     public Map<String, String> getExperimentalFlags() {
646         return mExperimentalFlags;
647     }
648 
649     /** {@inheritDoc} */
650     @Override
captureScreenshotOnFailure()651     public boolean captureScreenshotOnFailure() {
652         return mScreenshotOnFailure;
653     }
654 
655     /** {@inheritDoc} */
656     @Override
captureLogcatOnFailure()657     public boolean captureLogcatOnFailure() {
658         return mLogcatOnFailure;
659     }
660 
661     /** {@inheritDoc} */
662     @Override
getHostLogSuffix()663     public String getHostLogSuffix() {
664         return mHostLogSuffix;
665     }
666 
667     /** {@inheritDoc} */
668     @Override
setHostLogSuffix(String suffix)669     public void setHostLogSuffix(String suffix) {
670         mHostLogSuffix = suffix;
671     }
672     /** {@inheritDoc} */
673     @Override
shouldUseParallelRemoteSetup()674     public boolean shouldUseParallelRemoteSetup() {
675         return mUseParallelRemoteSetup;
676     }
677 
678     /** {@inheritDoc} */
679     @Override
shouldUseParallelPreInvocationSetup()680     public boolean shouldUseParallelPreInvocationSetup() {
681         return mUseParallelPreInvocationSetup;
682     }
683 
684     /** {@inheritDoc} */
685     @Override
getParallelPreInvocationSetupTimeout()686     public Duration getParallelPreInvocationSetupTimeout() {
687         return mParallelPreInvocationSetupTimeout;
688     }
689     /** {@inheritDoc} */
690     @Override
shouldUseParallelSetup()691     public boolean shouldUseParallelSetup() {
692         return mUseParallelSetup;
693     }
694 
695     /** {@inheritDoc} */
696     @Override
getParallelSetupTimeout()697     public Duration getParallelSetupTimeout() {
698         return mParallelSetupTimeout;
699     }
700 
701     /** {@inheritDoc} */
702     @Override
shouldUseReplicateSetup()703     public boolean shouldUseReplicateSetup() {
704         return mReplicateParentSetup;
705     }
706 
707     /** {@inheritDoc} */
708     @Override
setReplicateSetup(boolean replicate)709     public void setReplicateSetup(boolean replicate) {
710         mReplicateParentSetup = replicate;
711     }
712 
713     /** {@inheritDoc} */
714     @Override
shouldReportModuleProgression()715     public boolean shouldReportModuleProgression() {
716         return mReportModuleProgression;
717     }
718 
719     /** {@inheritDoc} */
720     @Override
getExtraRemotePostsubmitInstance()721     public int getExtraRemotePostsubmitInstance() {
722         return mExtraRemoteInstancePostsubmit;
723     }
724 
725     /** {@inheritDoc} */
726     @Override
earlyDeviceRelease()727     public boolean earlyDeviceRelease() {
728         return mEnableEarlyDeviceRelease;
729     }
730 
731     /** {@inheritDoc} */
732     @Override
delegatedEarlyDeviceRelease()733     public boolean delegatedEarlyDeviceRelease() {
734         return mEnableDelegatedEarlyDeviceRelease;
735     }
736 
737     /** {@inheritDoc} */
738     @Override
setDelegatedEarlyDeviceRelease(boolean earlyRelease)739     public void setDelegatedEarlyDeviceRelease(boolean earlyRelease) {
740         mEnableDelegatedEarlyDeviceRelease = earlyRelease;
741     }
742 
743     /** {@inheritDoc} */
744     @Override
getDynamicDownloadArgs()745     public Map<String, String> getDynamicDownloadArgs() {
746         return mDynamicDownloadArgs;
747     }
748 
749     /** {@inheritDoc} */
750     @Override
reportTestCaseCount()751     public boolean reportTestCaseCount() {
752         return mCountTestCases;
753     }
754 
755     /** {@inheritDoc} */
756     @Override
setReportTestCaseCount(boolean report)757     public void setReportTestCaseCount(boolean report) {
758         mCountTestCases = report;
759     }
760 
761     /** {@inheritDoc} */
762     @Override
reportPassedTests()763     public boolean reportPassedTests() {
764         return mReportPassedTests;
765     }
766 
767     /** {@inheritDoc} */
768     @Override
filterPreviousPassedTests()769     public boolean filterPreviousPassedTests() {
770         return mTestFilterPassed;
771     }
772 
773     /** {@inheritDoc} */
774     @Override
reportInvocationComplete()775     public boolean reportInvocationComplete() {
776         return mReportInvocationCompleteLogs;
777     }
778 
779     /** {@inheritDoc} */
780     @Override
setReportInvocationComplete(boolean reportInvocationCompleteLogs)781     public void setReportInvocationComplete(boolean reportInvocationCompleteLogs) {
782         mReportInvocationCompleteLogs = reportInvocationCompleteLogs;
783     }
784 
785     /** {@inheritDoc} */
786     @Override
reportingTags()787     public List<String> reportingTags() {
788         List<String> tags = new ArrayList<>();
789         // Convert a few of the enabled features into easily consumable tag that can be displayed
790         // to see if a feature is enabled.
791         if (mAutoCollectors.contains(AutoLogCollector.DEVICE_TRACE)) {
792             tags.add("device_tracing_enable");
793         }
794         return tags;
795     }
796 
797     /** {@inheritDoc} */
798     @Override
shouldDisableInvocationSetupAndTeardown()799     public boolean shouldDisableInvocationSetupAndTeardown() {
800         return mDisableInvocationSetupAndTeardown;
801     }
802 
803     /** {@inheritDoc} */
804     @Override
getMultiDeviceCount()805     public Integer getMultiDeviceCount() {
806         return mMultiDeviceCount;
807     }
808 
809     /** {@inheritDoc} */
810     @Override
setMultiDeviceCount(int count)811     public void setMultiDeviceCount(int count) {
812         mMultiDeviceCount = count;
813     }
814 
815     /** {@inheritDoc} */
816     @Override
isTracingEnabled()817     public boolean isTracingEnabled() {
818         return mTracingEnabled;
819     }
820 
821     /** {@inheritDoc} */
822     @Override
getJdkFolderForSubprocess()823     public File getJdkFolderForSubprocess() {
824         return mJdkFolder;
825     }
826 
827     /** {@inheritDoc} */
828     @Override
shouldRemoteDynamicShard()829     public boolean shouldRemoteDynamicShard() {
830         return mRemoteDynamicSharding;
831     }
832 
833     /** {@inheritDoc} */
834     @Override
setShouldRemoteDynamicShard(boolean shouldRemoteDynamicShard)835     public void setShouldRemoteDynamicShard(boolean shouldRemoteDynamicShard) {
836         mRemoteDynamicSharding = shouldRemoteDynamicShard;
837     }
838 
839     /** {@inheritDoc} */
840     @Override
shouldUseEvenModuleSharding()841     public boolean shouldUseEvenModuleSharding() {
842         return mEvenModuleSharding;
843     }
844 
845     /** {@inheritDoc} */
846     @Override
setShouldUseEvenModuleSharding(boolean useEvenModuleSharding)847     public void setShouldUseEvenModuleSharding(boolean useEvenModuleSharding) {
848         mEvenModuleSharding = useEvenModuleSharding;
849     }
850 }
851