diff --git a/app/src/processing/app/tools/android/Android.java b/app/src/processing/app/tools/android/Android.java index df8fc0a17..0018f51de 100644 --- a/app/src/processing/app/tools/android/Android.java +++ b/app/src/processing/app/tools/android/Android.java @@ -221,15 +221,6 @@ public class Android implements Tool { //emulator -avd gee1 -logcat 'System.*:i' -no-boot-anim //# though lots of messages aren't through System.*, so that's not great //# need to instead use the adb interface - - // adb -s emulator-5566 jdwp - // prints a list of connections that can be made to the device - // the final port will be the entry of the most recently started application - // while launching, will say 'error: device offline' - // when not running, will say 'error: device not found' - - // adb -s emulator-5566 -d forward tcp:29882 jdwp:736 - // jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=29882 // launch emulator because it's not running yet try { @@ -315,10 +306,75 @@ public class Android implements Tool { //System.out.println("ant build complete " + success); if (!success) return; - success = installSketch(device); - if (!success) return; - - success = startSketch(device); + int port = waitUntilReady(device); + + if (port != 0) { + success = installSketch(device); + if (!success) return; + + success = startSketch(device, port); + } + } + + + protected int waitUntilReady(String device) { + long timeout = System.currentTimeMillis() + 30 * 1000; // 15 sec + + try { + while (System.currentTimeMillis() < timeout) { + // adb -s emulator-5566 jdwp + // prints a list of connections that can be made to the device + // the final port will be the entry of the most recently started application + // while launching, will say 'error: device offline' + // when not running, will say 'error: device not found' + + String[] cmd = new String[] { + "adb", + "-s", device, + "jdwp" // come and play! + }; + Process p = Runtime.getRuntime().exec(cmd); + + // System.out.println(); + // System.out.print("Checking for JDWP connection: "); + // System.out.println(PApplet.join(cmd, " ")); + + StringRedirectThread error = new StringRedirectThread(p.getErrorStream()); + StringRedirectThread output = new StringRedirectThread(p.getInputStream()); + + int result = p.waitFor(); + error.finish(); + output.finish(); + + for (String err : error.getLines()) { + if (err.length() != 0) { + System.err.println("err: " + err); + } + } + for (String out : output.getLines()) { + if (out.length() != 0) { + System.out.println("out: " + out); + } + } + + if (result == 0) { + String[] lines = output.getLines(); + String last = lines[lines.length - 1]; + if (last.length() == 0) { + last = lines[lines.length - 2]; + } + System.out.println("last is " + last); + return PApplet.parseInt(last); + } + + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { } + } + } catch (Exception e) { + e.printStackTrace(); + } + return 0; } @@ -393,7 +449,7 @@ public class Android implements Tool { // better version that actually runs through JDI: // http://asantoso.wordpress.com/2009/09/26/using-jdb-with-adb-to-debugging-of-android-app-on-a-real-device/ - boolean startSketch(String device) { + boolean startSketch(String device, int port) { try { Device.sendMenuButton(device); // wake up Device.sendHomeButton(device); // kill any running app @@ -406,7 +462,7 @@ public class Android implements Tool { "shell", "am", "start", // kick things off "-e", "debug", "true", "-a", "android.intent.action.MAIN", "-n", - build.getPackageName() + "/." + build.getClassName() + build.getPackageName() + "/." + build.getClassName() }); int result = p.waitFor(); if (result != 0) { @@ -420,11 +476,48 @@ public class Android implements Tool { return true; } + + // Originally based on helpful notes by Agus Santoso (http://j.mp/7zV69M) + + // adb -s emulator-5566 jdwp + // prints a list of connections that can be made to the device + // the final port will be the entry of the most recently started application + // while launching, will say 'error: device offline' + // when not running, will say 'error: device not found' + + // adb -s emulator-5566 -d forward tcp:29882 jdwp:736 + // jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=29882 + Process fwd = Runtime.getRuntime().exec(new String[] { + "adb", + "-s", device, + "-d", "forward", + "tcp:29892", + "jdwp:" + port + }); + StringRedirectThread error = new StringRedirectThread(p.getErrorStream()); + StringRedirectThread output = new StringRedirectThread(p.getInputStream()); + + result = fwd.waitFor(); + for (String err : error.getLines()) { + System.err.println("err: " + err); + } + for (String out : output.getLines()) { + System.out.println("out: " + out); + } + + if (result != 0) { + editor.statusError("Could not connect for debugging."); + return false; + } + + AndroidRunner ar = new AndroidRunner(editor); + ar.launch(String.valueOf(port)); + } catch (IOException e) { editor.statusError(e); } catch (InterruptedException e) { } - + return false; } diff --git a/app/src/processing/app/tools/android/StringRedirectThread.java b/app/src/processing/app/tools/android/StringRedirectThread.java index dab5f5380..e0c2e512d 100644 --- a/app/src/processing/app/tools/android/StringRedirectThread.java +++ b/app/src/processing/app/tools/android/StringRedirectThread.java @@ -39,6 +39,15 @@ public class StringRedirectThread extends Thread { } + public void finish() { + while (!finished) { + try { + Thread.sleep(50); + } catch (InterruptedException e) { } + } + } + + public boolean isFinished() { return finished; }