Skip to content

Commit

Permalink
Merge pull request #12 from jberkel/master
Browse files Browse the repository at this point in the history
[FIXED JENKINS-13906] Allow user to specify target abi / system image
  • Loading branch information
orrc committed Jun 26, 2012
2 parents 26c3b57 + a3472a4 commit 7a3d75b
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 14 deletions.
31 changes: 28 additions & 3 deletions src/main/java/hudson/plugins/android_emulator/AndroidEmulator.java
Expand Up @@ -75,6 +75,7 @@ public class AndroidEmulator extends BuildWrapper implements Serializable {
@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;

Expand All @@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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");
Expand All @@ -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
Expand Down Expand Up @@ -842,6 +846,11 @@ public String[] getHardwareProperties() {
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();
}
Expand Down Expand Up @@ -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();
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/hudson/plugins/android_emulator/Constants.java
Expand Up @@ -28,6 +28,11 @@ public interface Constants {
"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";

Expand Down
31 changes: 21 additions & 10 deletions src/main/java/hudson/plugins/android_emulator/EmulatorConfig.java
Expand Up @@ -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;
Expand All @@ -35,6 +35,7 @@ class EmulatorConfig implements Serializable {
private ScreenResolution screenResolution;
private String deviceLocale;
private String sdCardSize;
private String targetAbi;
private boolean wipeData;
private final boolean showWindow;
private final boolean useSnapshots;
Expand All @@ -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.");
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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());

Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -510,7 +518,7 @@ public Boolean call() throws AndroidEmulatorException {
}
processAlive = false;
}
in.close();
in.unread(len);

// Write CRLF, if required
if (processAlive) {
Expand All @@ -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
Expand All @@ -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;
}
Expand Down
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
Expand Up @@ -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}''

Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/main/webapp/help-targetAbi.html
@@ -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.