Skip to content
Permalink
Browse files

Merge pull request #12 from jberkel/master

[FIXED JENKINS-13906] Allow user to specify target abi / system image
  • Loading branch information...
orrc committed Jun 26, 2012
2 parents 26c3b57 + a3472a4 commit 7a3d75b5d45f15406b8fc652035b4d392758e07f
@@ -75,6 +75,7 @@
@Exported public final String screenDensity;
@Exported public final String screenResolution;
@Exported public final String deviceLocale;
@Exported public final String targetAbi;
@Exported public final String sdCardSize;
@Exported public final HardwareProperty[] hardwareProperties;

@@ -94,7 +95,7 @@ public AndroidEmulator(String avdName, String osVersion, String screenDensity,
String screenResolution, String deviceLocale, String sdCardSize,
HardwareProperty[] hardwareProperties, boolean wipeData, boolean showWindow,
boolean useSnapshots, boolean deleteAfterBuild, int startupDelay,
String commandLineOptions) {
String commandLineOptions, String targetAbi) {
this.avdName = avdName;
this.osVersion = osVersion;
this.screenDensity = screenDensity;
@@ -108,6 +109,7 @@ public AndroidEmulator(String avdName, String osVersion, String screenDensity,
this.deleteAfterBuild = deleteAfterBuild;
this.startupDelay = Math.abs(startupDelay);
this.commandLineOptions = commandLineOptions;
this.targetAbi = targetAbi;
}

public boolean getUseNamedEmulator() {
@@ -207,7 +209,7 @@ public Environment setUp(AbstractBuild build, final Launcher launcher, BuildList
try {
emuConfig = EmulatorConfig.create(avdName, osVersion, screenDensity,
screenResolution, deviceLocale, sdCardSize, wipeData, showWindow, useSnapshots,
commandLineOptions);
commandLineOptions, targetAbi);
} catch (IllegalArgumentException e) {
log(logger, Messages.EMULATOR_CONFIGURATION_BAD(e.getLocalizedMessage()));
build.setResult(Result.NOT_BUILT);
@@ -770,6 +772,7 @@ public BuildWrapper newInstance(StaplerRequest req, JSONObject formData) throws
String screenResolution = null;
String deviceLocale = null;
String sdCardSize = null;
String targetAbi = null;
List<HardwareProperty> hardware = new ArrayList<HardwareProperty>();
boolean wipeData = false;
boolean showWindow = true;
@@ -792,6 +795,7 @@ public BuildWrapper newInstance(StaplerRequest req, JSONObject formData) throws
sdCardSize = sdCardSize.toUpperCase().replaceAll("[ B]", "");
}
hardware = req.bindJSONToList(HardwareProperty.class, emulatorData.get("hardwareProperties"));
targetAbi = Util.fixEmptyAndTrim(emulatorData.getString("targetAbi"));
}
wipeData = formData.getBoolean("wipeData");
showWindow = formData.getBoolean("showWindow");
@@ -804,7 +808,7 @@ public BuildWrapper newInstance(StaplerRequest req, JSONObject formData) throws

return new AndroidEmulator(avdName, osVersion, screenDensity, screenResolution,
deviceLocale, sdCardSize, hardware.toArray(new HardwareProperty[0]), wipeData,
showWindow, useSnapshots, deleteAfterBuild, startupDelay, commandLineOptions);
showWindow, useSnapshots, deleteAfterBuild, startupDelay, commandLineOptions, targetAbi);
}

@Override
@@ -842,6 +846,11 @@ public boolean isApplicable(AbstractProject<?, ?> item) {
return Constants.HARDWARE_PROPERTIES;
}

/** Used in config.jelly: Lists common abis that can be set. */
public String[] getTargetAbis() {
return Constants.TARGET_ABIS;
}

public FormValidation doCheckAvdName(@QueryParameter String value) {
return doCheckAvdName(value, true).getFormValidation();
}
@@ -968,6 +977,22 @@ private ValidationResult doCheckDeviceLocale(String locale, boolean allowVariabl
return ValidationResult.ok();
}

public FormValidation doCheckTargetAbi(@QueryParameter String value) {
return checkTargetAbi(value).getFormValidation();
}

private ValidationResult checkTargetAbi(String value) {
if (value == null || "".equals(value.trim())) {
return ValidationResult.ok();
}
for (String s : Constants.TARGET_ABIS) {
if (s.equals(value)) {
return ValidationResult.ok();
}
}
return ValidationResult.error(Messages.INVALID_TARGET_ABI());
}

public FormValidation doCheckSdCardSize(@QueryParameter String value) {
return doCheckSdCardSize(value, true).getFormValidation();
}
@@ -28,6 +28,11 @@
"hw.touchScreen", "hw.trackBall", "vm.heapSize"
};

/** Possible abis */
static final String[] TARGET_ABIS = {
"armeabi", "armeabi-v7a", "x86", "mips"
};

/** Name of the snapshot image we will use. */
static final String SNAPSHOT_NAME = "jenkins";

@@ -17,10 +17,10 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.PushbackInputStream;
import java.io.Serializable;
import java.util.Map;
import java.util.regex.Pattern;
@@ -35,6 +35,7 @@
private ScreenResolution screenResolution;
private String deviceLocale;
private String sdCardSize;
private String targetAbi;
private boolean wipeData;
private final boolean showWindow;
private final boolean useSnapshots;
@@ -51,7 +52,7 @@ public EmulatorConfig(String avdName, boolean wipeData, boolean showWindow,

public EmulatorConfig(String osVersion, String screenDensity, String screenResolution,
String deviceLocale, String sdCardSize, boolean wipeData, boolean showWindow,
boolean useSnapshots, String commandLineOptions)
boolean useSnapshots, String commandLineOptions, String targetAbi)
throws IllegalArgumentException {
if (osVersion == null || screenDensity == null || screenResolution == null) {
throw new IllegalArgumentException("Valid OS version and screen properties must be supplied.");
@@ -97,14 +98,15 @@ public EmulatorConfig(String osVersion, String screenDensity, String screenResol
this.showWindow = showWindow;
this.useSnapshots = useSnapshots;
this.commandLineOptions = commandLineOptions;
this.targetAbi = targetAbi;
}

public static final EmulatorConfig create(String avdName, String osVersion, String screenDensity,
String screenResolution, String deviceLocale, String sdCardSize, boolean wipeData,
boolean showWindow, boolean useSnapshots, String commandLineOptions) {
boolean showWindow, boolean useSnapshots, String commandLineOptions, String targetAbi) {
if (Util.fixEmptyAndTrim(avdName) == null) {
return new EmulatorConfig(osVersion, screenDensity, screenResolution, deviceLocale,
sdCardSize, wipeData, showWindow, useSnapshots, commandLineOptions);
sdCardSize, wipeData, showWindow, useSnapshots, commandLineOptions, targetAbi);
}

return new EmulatorConfig(avdName, wipeData, showWindow, useSnapshots, commandLineOptions);
@@ -114,7 +116,7 @@ public static final String getAvdName(String avdName, String osVersion, String s
String screenResolution, String deviceLocale) {
try {
return create(avdName, osVersion, screenDensity, screenResolution, deviceLocale, null,
false, false, false, null).getAvdName();
false, false, false, null, null).getAvdName();
} catch (IllegalArgumentException e) {}
return null;
}
@@ -475,6 +477,11 @@ public Boolean call() throws AndroidEmulatorException {
builder.add("-t");
builder.add(osVersion.getTargetName());

if (targetAbi != null) {
builder.add("--abi");
builder.add(targetAbi);
}

// Log command line used, for info
AndroidEmulator.log(logger, builder.toStringWithQuote());

@@ -490,6 +497,7 @@ public Boolean call() throws AndroidEmulatorException {

// Redirect process's stderr to a stream, for logging purposes
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
new StreamCopyThread("", process.getErrorStream(), stderr).start();

// Command may prompt us whether we want to further customise the AVD.
@@ -498,7 +506,7 @@ public Boolean call() throws AndroidEmulatorException {
boolean processAlive = true;

// Block until the command outputs something (or process ends)
final InputStream in = process.getInputStream();
final PushbackInputStream in = new PushbackInputStream(process.getInputStream(), 10);
int len = in.read();
if (len == -1) {
// Check whether the process has exited badly, as sometimes no output is valid.
@@ -510,7 +518,7 @@ public Boolean call() throws AndroidEmulatorException {
}
processAlive = false;
}
in.close();
in.unread(len);

// Write CRLF, if required
if (processAlive) {
@@ -521,6 +529,10 @@ public Boolean call() throws AndroidEmulatorException {
stream.close();
}

// read the rest of stdout (for debugging purposes)
Util.copyStream(in, stdout);
in.close();

// Wait for happy ending
if (process.waitFor() == 0) {
// Do a sanity check to ensure the AVD was really created
@@ -538,14 +550,13 @@ public Boolean call() throws AndroidEmulatorException {
// For reasons unknown, the return code may not be correctly reported on Windows.
// So check whether stderr contains failure info (useful for other platforms too).
String errOutput = stderr.toString();
String output = stdout.toString();
if (errOutput.contains("list targets")) {
AndroidEmulator.log(logger, Messages.INVALID_AVD_TARGET(osVersion.getTargetName()));
avdCreated = false;
errOutput = null;
} else if (errOutput.contains("more than one ABI")) {
// TODO: Currently we assume this message means there are *no* ABIs installed...
// TODO: See JENKINS-11516
AndroidEmulator.log(logger, Messages.ABI_REQUIRED(osVersion.getTargetName()), true);
AndroidEmulator.log(logger, Messages.MORE_THAN_ONE_ABI(osVersion.getTargetName(), output), true);
avdCreated = false;
errOutput = null;
}
@@ -3,7 +3,7 @@
<f:block>
<table style="margin-left:2em">

<f:radioBlock name="android-emulator.useNamed" value="true"
<f:radioBlock name="android-emulator.useNamed" value="true"
title="${%Run existing emulator}" checked="${instance.useNamedEmulator}"
help="${resURL}/plugin/android-emulator/help-emulatorNamed.html">
<f:block>
@@ -72,6 +72,11 @@
</f:repeatable>
</f:entry>

<f:entry title="${%Target ABI}" help="${resURL}/plugin/android-emulator/help-targetAbi.html">
<f:editableComboBox id="android-emulator.targetAbi" field="targetAbi"
items="${descriptor.targetAbis}"
checkUrl="'descriptorByName/AndroidEmulator/checkTargetAbi?value='+escape(this.value)" />
</f:entry>
</table>
</f:block>
</f:radioBlock>
@@ -20,6 +20,7 @@ SUSPECT_RESOLUTION_ANDROID_4=That doesn''t look right for Android {0}. Did you m
DEFAULT_LOCALE_WARNING=Locale will default to ''{0}'' if not specified
LOCALE_FORMAT_WARNING=Locale should have format: ab_XY
INVALID_SD_CARD_SIZE=SD card size should be numeric with suffix, e.g. 32M
INVALID_TARGET_ABI=Invalid target abi
SD_CARD_SIZE_TOO_SMALL=SD card size must be at least 9 megabytes
EMULATOR_CONFIGURATION_BAD=Unrecognised Android emulator configuration: ''{0}''

@@ -48,6 +49,7 @@ SDK_NOT_SPECIFIED=Android SDK directory needs to be specified in order to create
SDK_NOT_FOUND=Cannot find Android SDK at ''{0}''
INVALID_AVD_TARGET=The desired AVD platform ''{0}'' is not installed on this machine
ABI_REQUIRED=The desired platform ''{0}'' requires that you install a system image in order to create an AVD.\nUse the Android SDK Manager to install the ''ARM EABI v7a System Image'' for this platform.
MORE_THAN_ONE_ABI=There is more than one system image defined for platform ''{0}''.\nPick an image to use and set it in the ''Target ABI'' config field.\n{1}.
AVD_CREATION_FAILED=Failed to run AVD creation command
AVD_CREATION_ABORTED=AVD creation command failed to complete normally
AVD_CREATION_INTERRUPTED=Interrupted while creating new emulator
@@ -0,0 +1,3 @@
Should be the name of the abi / system image to be used, e.g "<code>armeabi</code>" or "<code>x86</code>".<br/>
If empty the default abi for the select platform will be used. You only need to define this field if you have
more than one system image per Android platform installed.

0 comments on commit 7a3d75b

Please sign in to comment.
You can’t perform that action at this time.