Skip to content

Rupak's emulator fixes (using avdmanager instead of the android tool) #364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 112 additions & 56 deletions src/processing/mode/android/AVD.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@
package processing.mode.android;

import processing.app.Base;
import processing.app.exec.ProcessHelper;
import processing.app.exec.ProcessResult;
import processing.app.Platform;
import processing.core.PApplet;

import java.awt.Frame;
import java.io.IOException;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -68,40 +67,39 @@ public class AVD {

static final String DEFAULT_SDCARD_SIZE = "64M";

static final String DEFAULT_SKIN = "WVGA800";
static final String WEAR_SKIN = "AndroidWearSquare";

/** Name of this avd. */
protected String name;

/** "android-7" or "Google Inc.:Google APIs:7" */
protected String target;
protected String sdkId;

static boolean invalidPackage;
static ArrayList<String> avdList;
static ArrayList<String> badList;
// static ArrayList<String> skinList;

private Map<String, String> preferredAbi = new HashMap<>(30);
private List<String> abiList = new ArrayList<>();
private String skin;
private static Process process;

/** Default virtual device used by Processing. */
static public final AVD mobileAVD =
new AVD("Processing-0" + Base.getRevision(),
AndroidBuild.TARGET_PLATFORM, SysImageDownloader.SYSTEM_IMAGE_TAG, DEFAULT_SKIN);
"system-images;" + AndroidBuild.TARGET_PLATFORM + ";" +
SysImageDownloader.SYSTEM_IMAGE_TAG + ";x86", SysImageDownloader.SYSTEM_IMAGE_TAG);
// "Google Inc.:Google APIs:" + AndroidBuild.sdkVersion);

/** Default virtual wear device used by Processing. */
static public final AVD wearAVD =
new AVD("Processing-Wear-0" + Base.getRevision(),
AndroidBuild.TARGET_PLATFORM, SysImageDownloader.SYSTEM_IMAGE_WEAR_TAG, WEAR_SKIN);
"system-images;" + AndroidBuild.TARGET_PLATFORM + ";" +
SysImageDownloader.SYSTEM_IMAGE_WEAR_TAG + ";x86", SysImageDownloader.SYSTEM_IMAGE_WEAR_TAG);

public AVD(final String name, final String target,
final String tag, final String skin) {
public AVD(final String name, final String sdkId,
final String tag) {
this.name = name;
this.target = target;
this.skin = skin;
initializeAbiList(tag);
this.sdkId = sdkId;
//initializeAbiList(tag);
}

private void initializeAbiList(String tag) {
Expand All @@ -121,11 +119,22 @@ static protected void list(final AndroidSDK sdk) throws IOException {
try {
avdList = new ArrayList<String>();
badList = new ArrayList<String>();
ProcessResult listResult =
new ProcessHelper(sdk.getAndroidToolPath(), "list", "avds").execute();
if (listResult.succeeded()) {
ProcessBuilder pb =
new ProcessBuilder(sdk.getAvdManagerPath(), "list", "avd");
Map<String, String> env = pb.environment();
env.clear();
env.put("JAVA_HOME", Platform.getJavaHome().getCanonicalPath());
pb.redirectErrorStream(true);

process = pb.start();
InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
process.waitFor();

if (process.exitValue() == 0) {
boolean badness = false;
for (String line : listResult) {
String line;
while ((line = reader.readLine()) != null) {
String[] m = PApplet.match(line, "\\s+Name\\:\\s+(\\S+)");
if (m != null) {
if (!badness) {
Expand All @@ -149,9 +158,14 @@ static protected void list(final AndroidSDK sdk) throws IOException {
}
} else {
System.err.println("Unhappy inside exists()");
System.err.println(listResult);
String line;
while ((line = reader.readLine()) != null)
System.err.println(line);
}
} catch (final InterruptedException ie) { }
finally {
process.destroy();
}
}


Expand Down Expand Up @@ -188,18 +202,24 @@ protected boolean badness() {

protected void initTargets(final AndroidSDK sdk) throws IOException {
preferredAbi.clear();
final String[] list_abi = {
sdk.getAndroidToolPath(),
"list", "targets"
};
ProcessBuilder pb = new ProcessBuilder(sdk.getAvdManagerPath(), "list", "target");

Map<String, String> env = pb.environment();
env.clear();
env.put("JAVA_HOME", Platform.getJavaHome().getCanonicalPath());
pb.redirectErrorStream(true);

process = pb.start();
InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));

ProcessHelper p = new ProcessHelper(list_abi);
try {
final ProcessResult abiListResult = p.execute();
process.waitFor();

String api = null;
String[] abis = null;
for (String line : abiListResult) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.equals("")) continue;

Expand Down Expand Up @@ -236,6 +256,8 @@ protected void initTargets(final AndroidSDK sdk) throws IOException {
}
}
} catch (InterruptedException e) {
} finally {
process.destroy();
}
}

Expand All @@ -248,43 +270,67 @@ protected boolean noTargets(final AndroidSDK sdk) throws IOException {


protected boolean create(final AndroidSDK sdk) throws IOException {
initTargets(sdk);
//initTargets(sdk);

final String[] params = {
sdk.getAndroidToolPath(),
ProcessBuilder pb = new ProcessBuilder(
sdk.getAvdManagerPath(),
"create", "avd",
"-n", name,
"-t", target,
"-c", DEFAULT_SDCARD_SIZE,
"-s", skin,
"--abi", preferredAbi.get(AndroidBuild.TARGET_SDK)
};

// sdk/tools/android create avd -n "Wear-Processing-0254" -t android-23 -c 64M -s AndroidWearSquare --abi android-wear/x86
"-k", sdkId,
"-c", DEFAULT_SDCARD_SIZE
);

// avdmanager create avd -n "Wear-Processing-0254" -k "system-images;android-25;google_apis;x86" -c 64M

// Set the list to null so that exists() will check again
avdList = null;

ProcessHelper p = new ProcessHelper(params);

Map<String, String> env = pb.environment();
env.clear();
env.put("JAVA_HOME", Platform.getJavaHome().getCanonicalPath());
pb.redirectErrorStream(true);

try {
process = pb.start();

InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));

// Passes 'no' to "Do you wish to create a custom hardware profile [no]"
OutputStream os = process.getOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
pw.println("no");
pw.flush();
pw.close();
os.flush();
os.close();

final ProcessResult createAvdResult = p.execute("no");
if (createAvdResult.succeeded()) {
process.waitFor();

if (process.exitValue() == 0) {
return true;
}
if (createAvdResult.toString().contains("Target id is not valid")) {

String line;
StringBuilder output = new StringBuilder();
while((line = reader.readLine()) != null) {
output.append(line);
}
if (output.toString().contains("Package path is not valid")) {
// They didn't install the Google APIs
AndroidUtil.showMessage(AVD_TARGET_TITLE, AVD_TARGET_MESSAGE);
//AndroidUtil.showMessage(AVD_TARGET_TITLE, AVD_TARGET_MESSAGE);
invalidPackage = true;
} else {
// Just generally not working
AndroidUtil.showMessage(AVD_CREATE_TITLE,
String.format(AVD_CREATE_MESSAGE, AndroidBuild.TARGET_SDK));
System.out.println(createAvdResult);
}
System.out.println(output.toString());
//System.err.println(createAvdResult);
} catch (final InterruptedException ie) {
ie.printStackTrace();
} finally {
process.destroy();
}

return false;
Expand All @@ -309,15 +355,20 @@ static public boolean ensureProperAVD(final Frame window, final AndroidMode mode
AndroidUtil.showMessage(AVD_LOAD_TITLE, AVD_LOAD_MESSAGE);
return false;
}
if (wearAVD.noTargets(sdk)) {
boolean res = AndroidSDK.locateSysImage(window, mode, true);
if (!res) {
return false;
}
}
if (wearAVD.create(sdk)) {
return true;
}
}
if (invalidPackage) {
boolean res = AndroidSDK.locateSysImage(window, mode, true);
if (!res) {
return false;
} else {
// Try again
if (wearAVD.create(sdk)) {
return true;
}
}
}
} else {
if (mobileAVD.exists(sdk)) {
return true;
Expand All @@ -326,14 +377,19 @@ static public boolean ensureProperAVD(final Frame window, final AndroidMode mode
AndroidUtil.showMessage(AVD_LOAD_TITLE, AVD_LOAD_MESSAGE);
return false;
}
if (mobileAVD.noTargets(sdk)) {
if (mobileAVD.create(sdk)) {
return true;
}
if (invalidPackage) {
boolean res = AndroidSDK.locateSysImage(window, mode, false);
if (!res) {
return false;
return false;
} else {
// Try again
if (mobileAVD.create(sdk)) {
return true;
}
}
}
if (mobileAVD.create(sdk)) {
return true;
}
}
} catch (final Exception e) {
Expand Down
2 changes: 1 addition & 1 deletion src/processing/mode/android/AndroidMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public void handleRunEmulator(Sketch sketch, AndroidEditor editor,
}

int comp = build.getAppComponent();
Future<Device> emu = Devices.getInstance().getEmulator(build.isWear(), build.usesOpenGL());
Future<Device> emu = Devices.getInstance().getEmulator(sdk.getToolsFolder(), build.isWear(), build.usesOpenGL());
runner = new AndroidRunner(build, listener);
runner.launch(emu, comp, true);
}
Expand Down
23 changes: 10 additions & 13 deletions src/processing/mode/android/AndroidSDK.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class AndroidSDK {
private final File androidJar;
private final File platformTools;
private final File buildTools;
private final File androidTool;
private final File avdManager;
private final File wearablePath;
private final File supportLibPath;

Expand Down Expand Up @@ -173,7 +173,7 @@ public AndroidSDK(File folder) throws BadSDKException, IOException {
throw new BadSDKException("There is no support library folder in " + folder);
}

androidTool = findAndroidTool(tools);
avdManager = findAvdManager(new File(tools, "bin"));

String path = Platform.getenv("PATH");

Expand Down Expand Up @@ -252,8 +252,8 @@ public File getToolsFolder() {
}


public String getAndroidToolPath() {
return androidTool.getAbsolutePath();
public String getAvdManagerPath() {
return avdManager.getAbsolutePath();
}


Expand Down Expand Up @@ -296,17 +296,14 @@ public File getSupportLibrary() {
* for the SDK installation. Also figures out the name of android/android.bat
* so that it can be called explicitly.
*/
private static File findAndroidTool(final File tools) throws BadSDKException {
if (new File(tools, "android.exe").exists()) {
return new File(tools, "android.exe");
private static File findAvdManager(final File tools) throws BadSDKException {
if (new File(tools, "avdmanager.bat").exists()) {
return new File(tools, "avdmanager.bat");
}
if (new File(tools, "android.bat").exists()) {
return new File(tools, "android.bat");
if (new File(tools, "avdmanager").exists()) {
return new File(tools, "avdmanager");
}
if (new File(tools, "android").exists()) {
return new File(tools, "android");
}
throw new BadSDKException("Cannot find the android tool in " + tools);
throw new BadSDKException("Cannot find avdmanager in " + tools);
}


Expand Down
2 changes: 1 addition & 1 deletion src/processing/mode/android/Commander.java
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private void execute() {
if (task == RUN) {
AndroidRunner runner = new AndroidRunner(build, this);
runner.launch(runOnEmu ?
Devices.getInstance().getEmulator(build.isWear(), build.usesOpenGL()) :
Devices.getInstance().getEmulator(androidMode.getSDK().getToolsFolder(), build.isWear(), build.usesOpenGL()) :
Devices.getInstance().getHardware(), build.getAppComponent(), runOnEmu);
}

Expand Down
9 changes: 5 additions & 4 deletions src/processing/mode/android/Devices.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import processing.app.exec.ProcessResult;
import processing.mode.android.EmulatorController.State;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -111,10 +112,10 @@ public void run() {
}


public Future<Device> getEmulator(final boolean wear, final boolean gpu) {
public Future<Device> getEmulator(final File sdkToolsPath, final boolean wear, final boolean gpu) {
final Callable<Device> androidFinder = new Callable<Device>() {
public Device call() throws Exception {
return blockingGetEmulator(wear, gpu);
return blockingGetEmulator(sdkToolsPath, wear, gpu);
}
};
final FutureTask<Device> task = new FutureTask<Device>(androidFinder);
Expand All @@ -123,7 +124,7 @@ public Device call() throws Exception {
}


private final Device blockingGetEmulator(final boolean wear, final boolean gpu) {
private final Device blockingGetEmulator(File sdkToolsPath, final boolean wear, final boolean gpu) {
// System.out.println("going looking for emulator");
String port = AVD.getPort(wear);
Device emu = find(true, port);
Expand All @@ -138,7 +139,7 @@ private final Device blockingGetEmulator(final boolean wear, final boolean gpu)
if (emuController.getState() == State.NOT_RUNNING) {
try {
// System.out.println("not running, gonna launch");
emuController.launch(wear, gpu); // this blocks until emulator boots
emuController.launch(sdkToolsPath, wear, gpu); // this blocks until emulator boots
// System.out.println("not just gonna, we've done the launch");
} catch (final IOException e) {
System.err.println("Problem while launching emulator.");
Expand Down
Loading