17850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/* 27850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Copyright (C) 2009 The Android Open Source Project 37850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * 47850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Licensed under the Apache License, Version 2.0 (the "License"); 57850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * you may not use this file except in compliance with the License. 67850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * You may obtain a copy of the License at 77850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * 87850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * http://www.apache.org/licenses/LICENSE-2.0 97850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * 107850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Unless required by applicable law or agreed to in writing, software 117850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * distributed under the License is distributed on an "AS IS" BASIS, 127850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * See the License for the specific language governing permissions and 147850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * limitations under the License. 157850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */ 167850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 17969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.compackage vogar.android; 187850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 197029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport com.google.common.base.Supplier; 205b644afaebd7afc43f75010b7c32f02129638a49bdc@google.comimport com.google.common.collect.Iterables; 217850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.File; 225b644afaebd7afc43f75010b7c32f02129638a49bdc@google.comimport java.util.ArrayList; 236a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.comimport java.util.Collections; 246a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.comimport java.util.HashSet; 255b644afaebd7afc43f75010b7c32f02129638a49bdc@google.comimport java.util.List; 26f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport java.util.Set; 27969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.Action; 28c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.comimport vogar.Variant; 29969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.Classpath; 30f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.Mode; 31c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.comimport vogar.ModeId; 32f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.Run; 33f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.comimport vogar.commands.VmCommandBuilder; 34db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.comimport vogar.tasks.RunActionTask; 352c37ef5a628067f4d7e5a5c69a7314647939a5e1jessewilson@google.comimport vogar.tasks.Task; 367850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 377850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/** 38c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com * Execute actions on an Android device or emulator using "app_process" or the runtime directly. 397850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */ 40c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.compublic final class DeviceRuntime implements Mode { 41c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com private final Run run; 42c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com private final ModeId modeId; 437029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin private final Supplier<String> deviceUserNameSupplier; 44db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com 457029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin public DeviceRuntime(Run run, ModeId modeId, Variant variant, 467029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin Supplier<String> deviceUserNameSupplier) { 477029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin this.deviceUserNameSupplier = deviceUserNameSupplier; 48c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com if (!modeId.isDevice() || !modeId.supportsVariant(variant)) { 49c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com throw new IllegalArgumentException("Unsupported mode:" + modeId + 50c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com " or variant: " + variant); 51c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com } 52db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com this.run = run; 53c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com this.modeId = modeId; 54d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com } 55d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com 56db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com @Override public Set<Task> installTasks() { 576a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com Set<Task> result = new HashSet<Task>(); 587850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com // dex everything on the classpath and push it to the device. 59f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com for (File classpathElement : run.classpath.getElements()) { 604b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller addCreateDexJarAndPushTasks(result, run.basenameOfJar(classpathElement), 612c37ef5a628067f4d7e5a5c69a7314647939a5e1jessewilson@google.com classpathElement, null); 627850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 636a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com return result; 647850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 657850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 666a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com @Override public Set<Task> installActionTasks(Action action, File jar) { 676a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com Set<Task> result = new HashSet<Task>(); 684b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller addCreateDexJarAndPushTasks(result, action.getName(), jar, action); 696a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com return result; 706a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com } 716a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com 72db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com @Override public Task executeActionTask(Action action, boolean useLargeTimeout) { 73db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com return new RunActionTask(run, action, useLargeTimeout); 74db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com } 75db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com 76f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com @Override public VmCommandBuilder newVmCommandBuilder(Action action, File workingDirectory) { 775b644afaebd7afc43f75010b7c32f02129638a49bdc@google.com List<String> vmCommand = new ArrayList<String>(); 78db82cde9016d812b26b6c79e375fdf60ead1d9fajessewilson@google.com Iterables.addAll(vmCommand, run.invokeWith()); 79f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com vmCommand.add(run.vmCommand); 805762c9cb967f90629e48ba67e6ff03ce7c48c834enh@google.com 81c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com // If you edit this, see also HostRuntime... 82f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com VmCommandBuilder vmCommandBuilder = new VmCommandBuilder(run.log) 83411cb1fb67241125203629229600ecbd821eb9c7Paul Duffin .env("ANDROID_DATA", run.getAndroidDataPath()) 84411cb1fb67241125203629229600ecbd821eb9c7Paul Duffin .workingDirectory(workingDirectory) 855b644afaebd7afc43f75010b7c32f02129638a49bdc@google.com .vmCommand(vmCommand) 86f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com .vmArgs("-Duser.home=" + run.deviceUserHome) 870e5c70d64d0a68bd48f6389563565290bbff4914Roland Levillain // Use the same command line limit (4096) as adb (see 880e5c70d64d0a68bd48f6389563565290bbff4914Roland Levillain // _adb_connect in system/core/adb/adb_client.cpp). 890e5c70d64d0a68bd48f6389563565290bbff4914Roland Levillain .maxLength(4096); 909712658a463c437f5437bcd981e7e6beacac0dc5Neil Fuller if (run.debugPort != null) { 919712658a463c437f5437bcd981e7e6beacac0dc5Neil Fuller vmCommandBuilder.vmArgs("-Xcompiler-option", "--debuggable"); 929712658a463c437f5437bcd981e7e6beacac0dc5Neil Fuller } 939712658a463c437f5437bcd981e7e6beacac0dc5Neil Fuller 94c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com if (modeId == ModeId.APP_PROCESS) { 95c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com return vmCommandBuilder 96c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com .vmArgs(action.getUserDir().getPath()) 97c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com .classpathViaProperty(true); 98c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com } 99c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com 100c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com vmCommandBuilder 1017029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin .vmArgs("-Duser.name=" + deviceUserNameSupplier.get()) 1027850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com .vmArgs("-Duser.language=en") 103c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com .vmArgs("-Duser.region=US"); 104c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com 105f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally if (!run.benchmark && run.checkJni) { 1065762c9cb967f90629e48ba67e6ff03ce7c48c834enh@google.com vmCommandBuilder.vmArgs("-Xcheck:jni"); 107e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com } 1085762c9cb967f90629e48ba67e6ff03ce7c48c834enh@google.com // dalvikvm defaults to no limit, but the framework sets the limit at 2000. 1095762c9cb967f90629e48ba67e6ff03ce7c48c834enh@google.com vmCommandBuilder.vmArgs("-Xjnigreflimit:2000"); 110e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com return vmCommandBuilder; 1117850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 1127850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com 1136a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com @Override public Set<Task> cleanupTasks(Action action) { 1140eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com return Collections.singleton(run.target.rmTask(action.getUserDir())); 1156a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com } 1166a0f4cdb51f57b4b38f9ee1ed9f44f1afc9f6da6jessewilson@google.com 117f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com @Override public Classpath getRuntimeClasspath(Action action) { 1187850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com Classpath result = new Classpath(); 1190eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com result.addAll(run.targetDexFile(action.getName())); 120f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com if (!run.benchmark) { 121f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com for (File classpathElement : run.classpath.getElements()) { 1220eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com result.addAll(run.targetDexFile(run.basenameOfJar(classpathElement))); 123e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com } 1247850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 125f39d9a39bc81bc5750c53fabd2bb9d3bdd1e389abdc@google.com // Note we intentionally do not add run.resourceClasspath on 126f39d9a39bc81bc5750c53fabd2bb9d3bdd1e389abdc@google.com // the device since it contains host path names. 1277850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com return result; 1287850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com } 1294b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller 1304b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller private void addCreateDexJarAndPushTasks( 1314b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller Set<Task> tasks, String name, File jar, Action action) { 1324b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller File localDex = run.localDexFile(name); 1334b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller File deviceDex = run.targetDexFile(name); 1344b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller Task createDexJarTask = newCreateDexJarTask(run.classpath, jar, name, action, localDex); 1354b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller tasks.add(createDexJarTask); 1364b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller tasks.add(run.target.pushTask(localDex, deviceDex).afterSuccess(createDexJarTask)); 1374b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller } 1384b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller 1394b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller private Task newCreateDexJarTask(Classpath classpath, File classpathElement, String name, 1404b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller Action action, File localDex) { 1414b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller Task dex; 1424b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller if (run.useJack) { 1434b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller dex = new JackDexTask(run, classpath, run.benchmark, name, classpathElement, 14439f93c4843a86ba62c7c9bd975911562b8a298f9Neil Fuller action, localDex); 1454b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller } else { 1464b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller dex = new DexTask(run.androidSdk, classpath, run.benchmark, name, classpathElement, 147388fcad5269758e893c6982fa9e4c2fbb474460aNeil Fuller action, localDex, run.multidex); 1484b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller } 1494b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller return dex; 1504b2e7ab15323b2b057e8bb7b0cf361bb2ab880e0Neil Fuller } 1517850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com} 152