From bac102ce334356b3f85fd98342914ee175585e4a Mon Sep 17 00:00:00 2001 From: benfry Date: Sat, 17 Jul 2010 20:18:45 +0000 Subject: [PATCH] working on the android tool, iron out some size() parsing issues --- android/todo.txt | 75 +++++++++++------ .../app/tools/android/AndroidEnvironment.java | 5 +- .../app/tools/android/AndroidSDK.java | 3 +- .../app/tools/android/AndroidTool.java | 10 ++- .../processing/app/tools/android/Build.java | 83 ++++++++++++------- .../app/tools/android/EmulatorController.java | 41 +++++++-- 6 files changed, 150 insertions(+), 67 deletions(-) diff --git a/android/todo.txt b/android/todo.txt index d592d6740..d5bc36c8a 100644 --- a/android/todo.txt +++ b/android/todo.txt @@ -1,12 +1,43 @@ 0190 android - -_ fix mouseX/Y mapping when using smaller screen sizes _ allow screenWidth/Height as parameters to size() _ right now would cause NumberFormatException -_ add notes to the wiki about the size() method +X add notes to the wiki about the size() method _ make sure sketchRenderer()/sketchWidth()/sketchHeight() are working on desktop _ see about getting them documented in the reference +_ size() command is currently ignored in Android +_ http://dev.processing.org/bugs/show_bug.cgi?id=1397 +_ Implement P3D, OpenGL, A3D for Android +_ http://dev.processing.org/bugs/show_bug.cgi?id=1396 + +_ post processing-android-core-0190.zip to the download page +_ get some help w/ the dist script to make the right file + +_ fix mouseX/Y mapping when using smaller screen sizes + +_ copy the changes over from the xml library + +_ when starting the emulator, the adb server gets reset +_ then it causes this exception, which kills the thread waiting for input +_ so another reset is necessary +Exception in thread "StreamPump 49" java.lang.RuntimeException: Inside processing.app.exec.StreamPump@1ebe8ec for out: adb devices + at processing.app.exec.StreamPump.run(StreamPump.java:82) + at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) + at java.lang.Thread.run(Thread.java:637) +Caused by: java.io.IOException: Stream closed + at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145) + at java.io.BufferedInputStream.read1(BufferedInputStream.java:255) + at java.io.BufferedInputStream.read(BufferedInputStream.java:317) + at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) + at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) + at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) + at java.io.InputStreamReader.read(InputStreamReader.java:167) + at java.io.BufferedReader.fill(BufferedReader.java:136) + at java.io.BufferedReader.readLine(BufferedReader.java:299) + at java.io.BufferedReader.readLine(BufferedReader.java:362) + at processing.app.exec.StreamPump.run(StreamPump.java:71) + ... 3 more _ major issue with sketches not quitting out of the run loop in background _ pause needs to actually kill the thread @@ -75,17 +106,14 @@ http://dev.processing.org/bugs/buglist.cgi?bug_status=&field0-0-0=product&type0- CORE (PApplet, P2D et al) -P2 _ separate "PApplet" into separate View and Activity classes -P2 _ http://dev.processing.org/bugs/show_bug.cgi?id=1398 P2 _ too many temporary objects (particularly w/ color) created with A2D P2 _ http://dev.processing.org/bugs/show_bug.cgi?id=1399 -P2 _ size() command is currently ignored in Android -P2 _ http://dev.processing.org/bugs/show_bug.cgi?id=1397 -P2 _ Implement P3D, OpenGL, A3D for Android -P2 _ http://dev.processing.org/bugs/show_bug.cgi?id=1396 -P3 _ remove unnecessary processing.xml.* code from android-core -P3 _ http://dev.processing.org/bugs/show_bug.cgi?id=1400 +P3 _ implement createGraphics() for A2D/P3D/OPENGL +P3 _ http://dev.processing.org/bugs/show_bug.cgi?id=1488 +P3 _ remove processing.opengl.* classes and finish PGraphicsAndroid3D +P3 _ http://dev.processing.org/bugs/show_bug.cgi?id=1401 + P3 _ mouseClicked() is currently missing P3 _ implement tap methods to handle mouseClicked() P3 _ http://dev.processing.org/bugs/show_bug.cgi?id=1406 @@ -110,11 +138,8 @@ P5 _ instead, create a new resized bitmap, and get rid of pixels[] P5 _ http://dev.processing.org/bugs/show_bug.cgi?id=1487 P5 _ should alpha PImage stuff use a non-4byte config? P5 _ http://dev.processing.org/bugs/show_bug.cgi?id=1490 -P5 _ colorMode() error -P5 _ http://dev.processing.org/bugs/show_bug.cgi?id=1436 -P5 _ add clear and close to all stream methods? -P5 _ http://dev.processing.org/bugs/show_bug.cgi?id=1492 - +DL _ colorMode() error +DL _ http://code.google.com/p/processing/issues/detail?id=223 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -230,12 +255,17 @@ P5 _ http://dev.processing.org/bugs/show_bug.cgi?id=1392 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -OPENGL/A3D/P3D +SAVED FOR LATER -P3 _ implement createGraphics() for A2D/P3D/OPENGL -P3 _ http://dev.processing.org/bugs/show_bug.cgi?id=1488 -P3 _ remove processing.opengl.* classes and finish PGraphicsAndroid3D -P3 _ http://dev.processing.org/bugs/show_bug.cgi?id=1401 +DL _ add clear and close to all stream methods? +DL _ http://code.google.com/p/processing/issues/detail?id=244 + +EH _ separate "PApplet" into separate View and Activity classes +EH _ http://code.google.com/p/processing/issues/detail?id=212 +EM _ remove unnecessary processing.xml.* code from android-core +EM _ http://code.google.com/p/processing/issues/detail?id=214 +EM _ implement size() and createGraphics() for arbitrary renderers +EM _ http://code.google.com/p/processing/issues/detail?id=241 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -246,9 +276,6 @@ OPTIMIZE / ENHANCEMENTS _ don't re-calculate stroke() or fill() when it's the same value _ should path.reset() or path.rewind() be used for a path to be reused? -EM _ implement size() and createGraphics() for arbitrary renderers -EM _ http://code.google.com/p/processing/issues/detail?id=241 - _ errors that cause a crash when setting sketchPath _ seems to be a filesystem that got too full _ no real signs of what went wrong, but deleting the avd fixed it diff --git a/android/tool/src/processing/app/tools/android/AndroidEnvironment.java b/android/tool/src/processing/app/tools/android/AndroidEnvironment.java index 164900275..c03eb3dc9 100644 --- a/android/tool/src/processing/app/tools/android/AndroidEnvironment.java +++ b/android/tool/src/processing/app/tools/android/AndroidEnvironment.java @@ -152,8 +152,8 @@ class AndroidEnvironment { return blockingGetHardware(); } }; - final FutureTask task = new FutureTask( - androidFinder); + final FutureTask task = + new FutureTask(androidFinder); deviceLaunchThread.execute(task); return task; } @@ -238,6 +238,7 @@ class AndroidEnvironment { } catch (InterruptedException e) { return Collections.emptyList(); } catch (IOException e) { + System.err.println("AndroidEnvironment.listDevices() did this to me"); e.printStackTrace(); // System.err.println(e); // System.err.println("checking devices"); diff --git a/android/tool/src/processing/app/tools/android/AndroidSDK.java b/android/tool/src/processing/app/tools/android/AndroidSDK.java index 9e336b5f4..c7d016473 100644 --- a/android/tool/src/processing/app/tools/android/AndroidSDK.java +++ b/android/tool/src/processing/app/tools/android/AndroidSDK.java @@ -197,7 +197,8 @@ class AndroidSDK { } else { adbCmd = cmd; } -// PApplet.println(adbCmd); + // printing this here to see if anyone else is killing the adb server + PApplet.println(adbCmd); // try { ProcessResult adbResult = new ProcessHelper(adbCmd).execute(); // Ignore messages about starting up an adb daemon diff --git a/android/tool/src/processing/app/tools/android/AndroidTool.java b/android/tool/src/processing/app/tools/android/AndroidTool.java index 5df35d9d0..ec09c23b0 100644 --- a/android/tool/src/processing/app/tools/android/AndroidTool.java +++ b/android/tool/src/processing/app/tools/android/AndroidTool.java @@ -43,13 +43,15 @@ public class AndroidTool implements Tool, DeviceListener { private Editor editor; private Build build; - private static final String ANDROID_CORE_URL = - "http://processing.googlecode.com/svn" + - "/tags/processing-" + Base.VERSION_NAME + "/android/core.zip"; - private static final String ANDROID_CORE_FILENAME = "processing-android-core-" + Base.VERSION_NAME + ".zip"; + private static final String ANDROID_CORE_URL = + "http://processing.googlecode.com/files/" + ANDROID_CORE_FILENAME; +// private static final String ANDROID_CORE_URL = +// "http://processing.googlecode.com/svn" + +// "/tags/processing-" + Base.VERSION_NAME + "/android/core.zip"; + public String getMenuTitle() { return "Android Mode"; } diff --git a/android/tool/src/processing/app/tools/android/Build.java b/android/tool/src/processing/app/tools/android/Build.java index 0b8357745..281bd4bbd 100644 --- a/android/tool/src/processing/app/tools/android/Build.java +++ b/android/tool/src/processing/app/tools/android/Build.java @@ -31,10 +31,13 @@ class Build { static final String sdkVersion = "7"; - String sketchSize; - String sketchWidth = "screenWidth"; - String sketchHeight = "screenHeight"; - String sketchRenderer = "A2D"; + String sizeStatement; + String sketchWidth; + String sketchHeight; + String sketchRenderer; +// String sketchWidth = "screenWidth"; +// String sketchHeight = "screenHeight"; +// String sketchRenderer = "A2D"; public Build(final Editor editor, final AndroidSDK sdk) { @@ -44,42 +47,58 @@ class Build { // TODO this needs to be a generic function inside Sketch or elsewhere + protected boolean calcSketchSize() { // This matches against any uses of the size() function, whether numbers // or variables or whatever. This way, no warning is shown if size() isn't // actually used in the applet, which is the case especially for anyone // who is cutting/pasting from the reference. - final String sizeRegex = - "(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+),?\\s*([^\\)]*)\\s*\\)\\s*\\;"; -// "(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+),?\\s*([^\\)]*)\\s*\\)"; - // This is identical to the version in Sketch.java, but adds the semicolon Sketch sketch = editor.getSketch(); String scrubbed = Sketch.scrubComments(sketch.getCode(0).getProgram()); - String[] matches = PApplet.match(scrubbed, sizeRegex); + String[] matches = PApplet.match(scrubbed, Sketch.SIZE_REGEX); +// PApplet.println("matches: "); +// PApplet.println(matches); if (matches != null) { - try { - // these are ignored, just checking for the exception - Integer.parseInt(matches[1]); - Integer.parseInt(matches[2]); - } catch (final NumberFormatException e) { - // found a reference to size, but it didn't - // seem to contain numbers + boolean badSize = false; + + if (!matches[1].equals("screenWidth") && + !matches[1].equals("screenHeight") && + PApplet.parseInt(matches[1], -1) == -1) { + badSize = true; + } + if (!matches[2].equals("screenWidth") && + !matches[2].equals("screenHeight") && + PApplet.parseInt(matches[2], -1) == -1) { + badSize = true; + } + + if (badSize) { + // found a reference to size, but it didn't seem to contain numbers final String message = - "The size of this applet could not automatically be\n" + - "determined from your code.\n" + - "Use only numeric values (not variables) for the size()\n" + - "command. See the size() reference for an explanation."; + "The size of this applet could not automatically be determined\n" + + "from your code. Use only numeric values (not variables) for the\n" + + "size() command. See the size() reference for more information."; Base.showWarning("Could not find sketch size", message, null); + System.out.println("More about the size() command on Android can be"); + System.out.println("found here: http://wiki.processing.org/w/Android"); return false; } - sketchSize = matches[0]; + +// PApplet.println(matches); + sizeStatement = matches[0]; // the full method to be removed from the source sketchWidth = matches[1]; sketchHeight = matches[2]; - if (matches[3].trim().length() != 0) { - sketchRenderer = matches[3]; + sketchRenderer = matches[3].trim(); + if (sketchRenderer.length() == 0) { + sketchRenderer = null; } + } else { + sizeStatement = null; + sketchWidth = null; + sketchHeight = null; + sketchRenderer = null; } return true; } @@ -348,10 +367,10 @@ class Build { public PreprocessResult write(Writer out, String program, String codeFolderPackages[]) throws RunnerException, RecognitionException, TokenStreamException { - if (sketchSize != null) { - int start = program.indexOf(sketchSize); + if (sizeStatement != null) { + int start = program.indexOf(sizeStatement); program = program.substring(0, start) + - program.substring(start + sketchSize.length()); + program.substring(start + sizeStatement.length()); } return super.write(out, program, codeFolderPackages); } @@ -375,9 +394,15 @@ class Build { if ((mode == Mode.STATIC) || (mode == Mode.ACTIVE)) { out.println(); - out.println(indent + "public int sketchWidth() { return " + sketchWidth + "; }"); - out.println(indent + "public int sketchHeight() { return " + sketchHeight + "; }"); - out.println(indent + "public String sketchRenderer() { return " + sketchRenderer + "; }"); + if (sketchWidth != null) { + out.println(indent + "public int sketchWidth() { return " + sketchWidth + "; }"); + } + if (sketchHeight != null) { + out.println(indent + "public int sketchHeight() { return " + sketchHeight + "; }"); + } + if (sketchRenderer != null) { + out.println(indent + "public String sketchRenderer() { return " + sketchRenderer + "; }"); + } // close off the class definition out.println("}"); diff --git a/android/tool/src/processing/app/tools/android/EmulatorController.java b/android/tool/src/processing/app/tools/android/EmulatorController.java index e411b306c..5538c860d 100644 --- a/android/tool/src/processing/app/tools/android/EmulatorController.java +++ b/android/tool/src/processing/app/tools/android/EmulatorController.java @@ -3,6 +3,7 @@ package processing.app.tools.android; import java.io.IOException; import java.util.concurrent.CountDownLatch; import processing.app.Preferences; +import processing.app.exec.LineProcessor; import processing.app.exec.ProcessRegistry; import processing.app.exec.StreamPump; import processing.core.PApplet; @@ -61,15 +62,41 @@ class EmulatorController { // beginning execution of the emulator, so we are now officially "Launched" setState(State.WAITING_FOR_BOOT); - // TODO need to suppress this warning on OS X + final String title = PApplet.join(cmd, ' '); + + // when this shows up on stdout: + // emulator: ERROR: the cache image is used by another emulator. aborting + // need to reset adb and try again, since it's running but adb is hosed + StreamPump outie = new StreamPump(p.getInputStream(), "out: " + title); + outie.addTarget(new LineProcessor() { + public void processLine(String line) { + if (line.contains("the cache image is used by another emulator")) { + + } else { +// System.out.println(line); + System.out.println(title + ": " + line); + } + } + }); + //new StreamPump(p.getInputStream(), "out: " + title).addTarget(System.out).start(); + + // suppress this warning on OS X, otherwise we're gonna get a lot of reports: // 2010-04-13 15:26:56.380 emulator[91699:903] Warning once: This // application, or a library it uses, is using NSQuickDrawView, which has // been deprecated. Apps should cease use of QuickDraw and move to Quartz. - final String title = PApplet.join(cmd, ' '); - new StreamPump(p.getInputStream(), "out: " + title).addTarget(System.out) - .start(); - new StreamPump(p.getErrorStream(), "err: " + title).addTarget(System.err) - .start(); + StreamPump errie = new StreamPump(p.getErrorStream(), "err: " + title); + errie.addTarget(new LineProcessor() { + public void processLine(String line) { + if (line.contains("This application, or a library it uses, is using NSQuickDrawView")) { + // i don't really care + } else { +// System.err.println(line); + System.err.println(title + ": " + line); + } + } + }); + //new StreamPump(p.getErrorStream(), "err: " + title).addTarget(System.err).start(); + final CountDownLatch latch = new CountDownLatch(1); new Thread(new Runnable() { public void run() { @@ -78,7 +105,7 @@ class EmulatorController { while (state == State.WAITING_FOR_BOOT) { System.out.println("sleeping for 2 seconds " + new java.util.Date().toString()); Thread.sleep(2000); - System.out.println("done sleeping"); +// System.out.println("done sleeping"); for (final String device : AndroidEnvironment.listDevices()) { if (device.contains("emulator")) { // System.err.println("EmulatorController: Emulator booted.");