1f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com/*
2f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * Copyright (C) 2011 The Android Open Source Project
3f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com *
4f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * you may not use this file except in compliance with the License.
6f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * You may obtain a copy of the License at
7f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com *
8f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com *
10f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * Unless required by applicable law or agreed to in writing, software
11f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * See the License for the specific language governing permissions and
14f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com * limitations under the License.
15f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com */
16f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
17f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.compackage vogar;
18f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
19db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.comimport com.google.common.base.Splitter;
20f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.io.File;
21f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.io.IOException;
22f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.net.URL;
23db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.comimport java.util.Collections;
24f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.util.Date;
250eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.comimport java.util.HashSet;
26f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.util.List;
270eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.comimport java.util.Set;
28f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.util.UUID;
29f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.android.ActivityMode;
30eddaebb1f85ac0ed0dba621f2136baf10e8f5296jessewilson@google.comimport vogar.android.AdbTarget;
31f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.android.AndroidSdk;
32f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.android.DeviceFileCache;
33c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.comimport vogar.android.DeviceRuntime;
34c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.comimport vogar.android.HostRuntime;
35f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.commands.Mkdir;
36f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.commands.Rm;
37f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.tasks.TaskQueue;
38f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.util.Strings;
39f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
40f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.compublic final class Run {
410eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    /** A list of generic names that we avoid when naming generated files. */
420eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    private static final Set<String> BANNED_NAMES = new HashSet<String>();
430eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    static {
440eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        BANNED_NAMES.add("classes");
450eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        BANNED_NAMES.add("javalib");
460eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    }
470eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com
48f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File xmlReportsDirectory;
49f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File resultsDir;
50f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean recordResults;
51f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final ExpectationStore expectationStore;
52f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Date date;
53f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final String invokeWith;
54f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File keystore;
55f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Log log;
56f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Classpath classpath;
57f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Classpath buildClasspath;
585379730d1295c75e2b7b1c6d193e74ba5f54cf17enh@google.com    public final Classpath resourceClasspath;
59f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final List<File> sourcepath;
60f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Mkdir mkdir;
61f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Rm rm;
62f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final int firstMonitorPort;
63f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final int timeoutSeconds;
64f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean profile;
65f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean profileBinary;
66f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final int profileDepth;
67f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final int profileInterval;
68f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean profileThreadGroup;
69f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File profileFile;
70f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File javaHome;
71f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Integer debugPort;
72f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final List<String> javacArgs;
73f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean benchmark;
74f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File runnerDir;
75f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean cleanBefore;
76f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean cleanAfter;
77f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File localTemp;
783b3cf36f62d25eb950f0bf95071a82b83e730a58jessewilson@google.com    public final int maxConcurrentActions;
79f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File deviceUserHome;
80f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Console console;
81f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final int smallTimeoutSeconds;
82f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com    public final String vmCommand;
83f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com    public final String dalvikCache;
84f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final List<String> additionalVmArgs;
85f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final List<String> targetArgs;
86f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final boolean useBootClasspath;
87f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final int largeTimeoutSeconds;
88f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final RetrievedFilesFilter retrievedFiles;
89f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Driver driver;
90f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final Mode mode;
91db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com    public final Target target;
92f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final AndroidSdk androidSdk;
93f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final XmlReportPrinter reportPrinter;
94f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final JarSuggestions jarSuggestions;
95f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final ClassFileIndex classFileIndex;
96f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final OutcomeStore outcomeStore;
97f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final TaskQueue taskQueue;
98cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray    public final boolean testOnly;
99f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
100f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public Run(Vogar vogar) throws IOException {
101f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.console = vogar.stream
102f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                ? new Console.StreamingConsole()
103f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                : new Console.MultiplexingConsole();
1045ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray        console.setUseColor(
1055ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray            vogar.color, vogar.passColor, vogar.skipColor, vogar.failColor, vogar.warnColor);
106f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        console.setAnsi(vogar.ansi);
107f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        console.setIndent(vogar.indent);
108f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        console.setVerbose(vogar.verbose);
1090eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com
110f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.localTemp = new File("/tmp/vogar/" + UUID.randomUUID());
111f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.log = console;
1120eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com
1130eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        if (vogar.sshHost != null) {
1140eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com            this.target = new SshTarget(vogar.sshHost, log);
115c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        } else if (vogar.modeId.isLocal()) {
1160eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com            this.target = new LocalTarget(this);
1170eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        } else {
1180eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com            this.target = new AdbTarget(this);
1190eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        }
1200eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com
121f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        this.vmCommand = vogar.vmCommand;
122f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        this.dalvikCache = vogar.dalvikCache;
123f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.additionalVmArgs = vogar.vmArgs;
124f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.benchmark = vogar.benchmark;
125f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.cleanBefore = vogar.cleanBefore;
126f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.cleanAfter = vogar.cleanAfter;
127f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.date = new Date();
128f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.debugPort = vogar.debugPort;
1290eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        this.runnerDir = vogar.deviceDir != null
1300eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com                ? new File(vogar.deviceDir, "run")
1310eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com                : new File(target.defaultDeviceDir(), "run");
1320eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        this.deviceUserHome = new File(runnerDir, "user.home");
133f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.mkdir = new Mkdir(console);
134f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.rm = new Rm(console);
135f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.firstMonitorPort = vogar.firstMonitorPort;
136f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.invokeWith = vogar.invokeWith;
137f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.javacArgs = vogar.javacArgs;
138f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.javaHome = vogar.javaHome;
139f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.largeTimeoutSeconds = vogar.timeoutSeconds * Vogar.LARGE_TIMEOUT_MULTIPLIER;
140c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        this.maxConcurrentActions = (vogar.stream || vogar.modeId == ModeId.ACTIVITY)
141f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                    ? 1
142f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                    : Vogar.NUM_PROCESSORS;
143f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.timeoutSeconds = vogar.timeoutSeconds;
144f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.smallTimeoutSeconds = vogar.timeoutSeconds;
145f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.sourcepath = vogar.sourcepath;
1465379730d1295c75e2b7b1c6d193e74ba5f54cf17enh@google.com        this.resourceClasspath = Classpath.of(vogar.resourceClasspath);
147f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.useBootClasspath = vogar.useBootClasspath;
148f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.targetArgs = vogar.targetArgs;
149f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.xmlReportsDirectory = vogar.xmlReportsDirectory;
150f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.profile = vogar.profile;
151f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.profileBinary = vogar.profileBinary;
152f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.profileFile = vogar.profileFile;
153f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.profileDepth = vogar.profileDepth;
154f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.profileInterval = vogar.profileInterval;
155f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.profileThreadGroup = vogar.profileThreadGroup;
156f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.recordResults = vogar.recordResults;
157f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.resultsDir =  vogar.resultsDir == null
158f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                ? new File(vogar.vogarDir, "results")
159f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                : vogar.resultsDir;
160f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.keystore = localFile("activity", "vogar.keystore");
161f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.classpath = Classpath.of(vogar.classpath);
162f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.classpath.addAll(vogarJar());
163cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray        this.testOnly = vogar.testOnly;
164f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
165c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        if (vogar.modeId.requiresAndroidSdk()) {
166c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            androidSdk = new AndroidSdk(log, mkdir, vogar.modeId);
167eddaebb1f85ac0ed0dba621f2136baf10e8f5296jessewilson@google.com            androidSdk.setCaches(new HostFileCache(log, mkdir),
168eddaebb1f85ac0ed0dba621f2136baf10e8f5296jessewilson@google.com                    new DeviceFileCache(log, runnerDir, androidSdk));
169eddaebb1f85ac0ed0dba621f2136baf10e8f5296jessewilson@google.com        } else {
170eddaebb1f85ac0ed0dba621f2136baf10e8f5296jessewilson@google.com            androidSdk = null;
171eddaebb1f85ac0ed0dba621f2136baf10e8f5296jessewilson@google.com        }
172f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
1735a8fd4b1d6c046471c7b951680cace3eec723fe7Nicolas Geoffray        expectationStore = ExpectationStore.parse(
1745a8fd4b1d6c046471c7b951680cace3eec723fe7Nicolas Geoffray            console, vogar.expectationFiles, vogar.modeId, vogar.variant);
175f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        if (vogar.openBugsCommand != null) {
176f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            expectationStore.loadBugStatuses(new CommandBugDatabase(log, vogar.openBugsCommand));
177f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        }
178f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
179c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        this.mode = createMode(vogar.modeId, vogar.variant);
180f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
181f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.buildClasspath = Classpath.of(vogar.buildClasspath);
182c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        if (vogar.modeId.requiresAndroidSdk()) {
183c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            buildClasspath.addAll(androidSdk.getCompilationClasspath());
184f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        }
185f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
186f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.classFileIndex = new ClassFileIndex(log, mkdir, vogar.jarSearchDirs);
187f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        if (vogar.suggestClasspaths) {
188f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            classFileIndex.createIndex();
189f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        }
190f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
191f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.retrievedFiles = new RetrievedFilesFilter(profile, profileFile);
192f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.reportPrinter = new XmlReportPrinter(xmlReportsDirectory, expectationStore, date);
193f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.jarSuggestions = new JarSuggestions();
194f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.outcomeStore = new OutcomeStore(log, mkdir, rm, resultsDir, recordResults,
195f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com                expectationStore, date);
196f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        this.driver = new Driver(this);
1973b3cf36f62d25eb950f0bf95071a82b83e730a58jessewilson@google.com        this.taskQueue = new TaskQueue(console, maxConcurrentActions);
198f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
199f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
200c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com    private Mode createMode(ModeId modeId, Variant variant) {
201c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        switch (modeId) {
202c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case JVM:
203c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com                return new JavaVm(this);
204c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case HOST:
205c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case HOST_DALVIK:
206c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case HOST_ART_KITKAT:
207c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com                return new HostRuntime(this, modeId, variant);
208c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case DEVICE:
209c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case DEVICE_DALVIK:
210c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case DEVICE_ART_KITKAT:
211c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case APP_PROCESS:
212c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com                return new DeviceRuntime(this, modeId, variant);
213c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            case ACTIVITY:
214c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com                return new ActivityMode(this);
215c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            default:
216c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com                throw new IllegalArgumentException("Unsupported mode: " + modeId);
217c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        }
218c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com    }
219c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com
220f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public final File localFile(Object... path) {
221f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        return new File(localTemp + "/" + Strings.join("/", path));
222f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
223f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
224f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    private File vogarJar() {
225f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        URL jarUrl = Vogar.class.getResource("/vogar/Vogar.class");
226f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        if (jarUrl == null) {
227f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            // should we add an option for IDE users, to use a user-specified vogar.jar?
228f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            throw new IllegalStateException("Vogar cannot find its own .jar");
229f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        }
230f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
231f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        /*
232f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com         * Parse a URI like jar:file:/Users/jessewilson/vogar/vogar.jar!/vogar/Vogar.class
233f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com         * to yield a .jar file like /Users/jessewilson/vogar/vogar.jar.
234f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com         */
235f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        String url = jarUrl.toString();
236f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        int bang = url.indexOf("!");
237f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        String JAR_URI_PREFIX = "jar:file:";
238f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        if (url.startsWith(JAR_URI_PREFIX) && bang != -1) {
239f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            return new File(url.substring(JAR_URI_PREFIX.length(), bang));
240f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        } else {
241f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            throw new IllegalStateException("Vogar cannot find the .jar file in " + jarUrl);
242f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        }
243f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
244f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
2456a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com    public final File hostJar(Object nameOrAction) {
2466a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com        return localFile(nameOrAction, nameOrAction + ".jar");
2476a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com    }
2486a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com
249f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    /**
250f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com     * Returns a path for a Java tool such as java, javac, jar where
251f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com     * the Java home is used if present, otherwise assumes it will
252f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com     * come from the path.
253f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com     */
254f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public String javaPath(String tool) {
255f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        return (javaHome == null)
256f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            ? tool
257f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com            : new File(new File(javaHome, "bin"), tool).getPath();
258f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
259f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
2600eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    public File targetDexFile(String name) {
2610eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        return new File(runnerDir, name + ".dex.jar");
262f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
263f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
264db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com    public File localDexFile(String name) {
2650eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        return localFile(name, name + ".dex.jar");
2660eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    }
2670eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com
2680eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    /**
2690eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com     * Returns a recognizable readable name for the given generated .jar file,
2700eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com     * appropriate for use in naming derived files.
2710eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com     *
2720eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com     * @param file a product of the android build system, such as
27350e898cf2b0a57fe7eddb02efc5df5658a03b322nfuller@google.com     *     "out/core-libart_intermediates/javalib.jar".
27450e898cf2b0a57fe7eddb02efc5df5658a03b322nfuller@google.com     * @return a recognizable base name like "core-libart_intermediates".
2750eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com     */
2760eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    public String basenameOfJar(File file) {
2770eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        String name = file.getName().replaceAll("\\.jar$", "");
2780eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        while (BANNED_NAMES.contains(name)) {
2790eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com            file = file.getParentFile();
2800eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com            name = file.getName();
2810eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        }
2820eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        return name;
283db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com    }
284db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com
285f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public File vogarTemp() {
286f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        return new File(runnerDir, "tmp");
287f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
288f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com
289f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public File dalvikCache() {
290f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        return new File(runnerDir.getParentFile(), dalvikCache);
291f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    }
2926a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com
2936a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com    /**
2946a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com     * Returns an environment variable assignment to configure where the VM will
2956a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com     * store its dexopt files. This must be set on production devices and is
2966a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com     * optional for development devices.
2976a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com     */
2986a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com    public String getAndroidData() {
2996a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com        // The VM wants the parent directory of a directory named "dalvik-cache"
3006a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com        return "ANDROID_DATA=" + dalvikCache().getParentFile();
3016a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com    }
302db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com
303db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com    /**
304db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com     * Returns a parsed list of the --invoke-with command and its
305db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com     * arguments, or an empty list if no --invoke-with was provided.
306db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com     */
307db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com    public Iterable<String> invokeWith() {
308db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com        if (invokeWith == null) {
309db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com            return Collections.emptyList();
310db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com        }
311db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com        return Splitter.onPattern("\\s+").omitEmptyStrings().split(invokeWith);
312db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com    }
313f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com}
314