From 77da3afe5a26f3efc03d8b893df69faf0017772f Mon Sep 17 00:00:00 2001 From: benfry Date: Tue, 24 Nov 2009 22:11:08 +0000 Subject: [PATCH] adding sdk tests and other debug work --- app/src/processing/app/Base.java | 123 ++++++++++++++++++ app/src/processing/app/Editor.java | 1 + .../processing/app/tools/android/Android.java | 118 +++++++++++++---- .../processing/app/tools/android/Device.java | 6 +- 4 files changed, 220 insertions(+), 28 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index ecd9236fa..2aa163c69 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -29,6 +29,8 @@ import java.util.*; import javax.swing.*; +import com.sun.codemodel.internal.JOp; + import processing.app.debug.Compiler; import processing.core.*; @@ -1672,6 +1674,127 @@ public class Base { // ................................................................... + + // incomplete + static public int showYesNoCancelQuestion(Editor editor, String title, + String primary, String secondary) { + if (!Base.isMacOS()) { + int result = + JOptionPane.showConfirmDialog(null, primary + "\n" + secondary, title, + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + return result; +// if (result == JOptionPane.YES_OPTION) { +// +// } else if (result == JOptionPane.NO_OPTION) { +// return true; // ok to continue +// +// } else if (result == JOptionPane.CANCEL_OPTION) { +// return false; +// +// } else { +// throw new IllegalStateException(); +// } + + } else { + // Pane formatting adapted from the Quaqua guide + // http://www.randelshofer.ch/quaqua/guide/joptionpane.html + JOptionPane pane = + new JOptionPane(" " + + " " + + "Do you want to save changes to this sketch
" + + " before closing?
" + + "

If you don't save, your changes will be lost.", + JOptionPane.QUESTION_MESSAGE); + + String[] options = new String[] { + "Save", "Cancel", "Don't Save" + }; + pane.setOptions(options); + + // highlight the safest option ala apple hig + pane.setInitialValue(options[0]); + + // on macosx, setting the destructive property places this option + // away from the others at the lefthand side + pane.putClientProperty("Quaqua.OptionPane.destructiveOption", + new Integer(2)); + + JDialog dialog = pane.createDialog(editor, null); + dialog.setVisible(true); + + Object result = pane.getValue(); + if (result == options[0]) { + return JOptionPane.YES_OPTION; + } else if (result == options[1]) { + return JOptionPane.CANCEL_OPTION; + } else if (result == options[2]) { + return JOptionPane.NO_OPTION; + } else { + return JOptionPane.CLOSED_OPTION; + } + } + } + + +//if (result == JOptionPane.YES_OPTION) { + // +// } else if (result == JOptionPane.NO_OPTION) { +// return true; // ok to continue + // +// } else if (result == JOptionPane.CANCEL_OPTION) { +// return false; + // +// } else { +// throw new IllegalStateException(); +// } + + static public int showYesNoQuestion(Editor editor, String title, + String primary, String secondary) { + if (!Base.isMacOS()) { + return JOptionPane.showConfirmDialog(editor, + primary + "\n" + secondary, title, + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + } else { + // Pane formatting adapted from the Quaqua guide + // http://www.randelshofer.ch/quaqua/guide/joptionpane.html + JOptionPane pane = + new JOptionPane(" " + + " " + + "" + primary + "" + + "

" + secondary + "

", + JOptionPane.QUESTION_MESSAGE); + + String[] options = new String[] { + "Yes", "No" + }; + pane.setOptions(options); + + // highlight the safest option ala apple hig + pane.setInitialValue(options[0]); + + JDialog dialog = pane.createDialog(editor, null); + dialog.setVisible(true); + + Object result = pane.getValue(); + if (result == options[0]) { + return JOptionPane.YES_OPTION; + } else if (result == options[1]) { + return JOptionPane.NO_OPTION; + } else { + return JOptionPane.CLOSED_OPTION; + } + } + } + + /** * Retrieve a path to something in the Processing folder. Eventually this * may refer to the Contents subfolder of Processing.app, if we bundle things diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index e2d972be0..c076f1870 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -1753,6 +1753,7 @@ public class Editor extends JFrame implements RunnerListener { } else if (result == JOptionPane.CANCEL_OPTION) { return false; + } else { throw new IllegalStateException(); } diff --git a/app/src/processing/app/tools/android/Android.java b/app/src/processing/app/tools/android/Android.java index fd7af3e74..dfacc180f 100644 --- a/app/src/processing/app/tools/android/Android.java +++ b/app/src/processing/app/tools/android/Android.java @@ -23,6 +23,8 @@ package processing.app.tools.android; import java.io.File; import java.io.IOException; + +import javax.swing.JOptionPane; //import java.util.ArrayList; import processing.app.*; @@ -30,8 +32,8 @@ import processing.app.tools.Tool; import processing.core.PApplet; -// http://dl.google.com/android/android-sdk_r3-mac.zip // http://dl.google.com/android/repository/repository.xml +// http://dl.google.com/android/android-sdk_r3-mac.zip // http://dl.google.com/android/repository/tools_r03-macosx.zip public class Android implements Tool { @@ -44,6 +46,21 @@ public class Android implements Tool { String emulator; Process emulatorProcess; + static final String ANDROID_SDK_PRIMARY = + "Is the Android SDK installed?"; + static final String ANDROID_SDK_SECONDARY = + "The Android SDK does not appear to be installed,
" + + "because the ANDROID_SDK variable is not set.
" + + "If it is installed, click “Yes” to select the
" + + "location of the SDK, or “No” to visit the SDK
" + + "download site at http://developer.android.com/sdk."; + static final String SELECT_ANDROID_SDK_FOLDER = + "Choose the location of the Android SDK"; + static final String NOT_ANDROID_SDK = + "The selected folder does not appear to contain an Android SDK."; + static final String ANDROID_SDK_URL = + "http://developer.android.com/sdk/"; + public String getMenuTitle() { return "Android Mode"; @@ -58,33 +75,80 @@ public class Android implements Tool { public void run() { editor.statusNotice("Loading Android tools."); - checkPath(); - boolean success = Device.checkDefaults(); - if (success) { - editor.setHandlers(new RunHandler(), new PresentHandler(), - new StopHandler(), - new ExportHandler(), new ExportAppHandler()); - build = new Build(editor); - editor.statusNotice("Done loading Android tools."); - } else { - editor.statusError("Could not load Android tools."); + boolean success = checkPath(); + if (!success) { + editor.statusNotice("Android mode canceled."); + return; } + success = Device.checkDefaults(); + if (!success) { + editor.statusError("Could not load Android tools."); + return; + } + editor.setHandlers(new RunHandler(), new PresentHandler(), + new StopHandler(), + new ExportHandler(), new ExportAppHandler()); + build = new Build(editor); + editor.statusNotice("Done loading Android tools."); } - static protected void checkPath() { + protected boolean checkPath() { Platform platform = Base.getPlatform(); - // System.out.println("PATH is " + Base.getenv("PATH")); - // System.out.println("PATH from System is " + System.getenv("PATH")); - if (platform.getenv("ANDROID_SDK") == null) { - platform.setenv("ANDROID_SDK", "/opt/android"); + + // The environment variable is king. The preferences.txt entry is a page. + String envPath = platform.getenv("ANDROID_SDK"); + if (envPath != null) { + sdkPath = envPath; + // Just set the pref, in case it the ANDROID_SDK variable gets + // knocked out later. For instance, by that pesky Eclipse, + // which nukes all env variables when launching from the IDE. + Preferences.set("android.sdk.path", envPath); + + } else { + sdkPath = Preferences.get("android.sdk.path"); + + if (sdkPath == null) { + int result = Base.showYesNoQuestion(editor, "Android SDK", + ANDROID_SDK_PRIMARY, + ANDROID_SDK_SECONDARY); + if (result == JOptionPane.YES_OPTION) { + File folder = + Base.selectFolder(SELECT_ANDROID_SDK_FOLDER, null, editor); + if (folder != null) { + boolean basicCheck = new File(folder, "tools/android").exists(); + if (basicCheck) { + sdkPath = folder.getAbsolutePath(); + Preferences.set("android.sdk.path", sdkPath); + } else { + // tools/android not found in the selected folder + JOptionPane.showMessageDialog(editor, NOT_ANDROID_SDK); + return false; + } + } + } else if (result == JOptionPane.NO_OPTION) { + // user admitted they don't have the SDK installed, and need help. + Base.openURL(ANDROID_SDK_URL); + } + } } - sdkPath = platform.getenv("ANDROID_SDK"); -// System.out.println("sdk path is " + sdkPath); + if (sdkPath == null) { // still not interested? + return false; + } + if (envPath == null) { + platform.setenv("ANDROID_SDK", sdkPath); + } + //platform.setenv("ANDROID_SDK", "/opt/android"); + //sdkPath = platform.getenv("ANDROID_SDK"); + //System.out.println("sdk path is " + sdkPath); // sdkPath = "/opt/android"; - String toolsPath = sdkPath + File.separator + "tools"; - platform.setenv("PATH", platform.getenv("PATH") + File.pathSeparator + toolsPath); -// System.out.println("path after set is " + Base.getenv("PATH")); + + // Make sure that the tools are in the PATH + toolsPath = sdkPath + File.separator + "tools"; + String path = platform.getenv("PATH"); + platform.setenv("PATH", path + File.pathSeparator + toolsPath); + //System.out.println("path after set is " + Base.getenv("PATH")); + return true; } @@ -178,12 +242,12 @@ public class Android implements Tool { return null; } } - - + + public String getDefaultDevice() { return Device.avdDonut.name; } - + /** Find connected devices */ public String findDevice() { @@ -324,9 +388,11 @@ public class Android implements Tool { Process p = Runtime.getRuntime().exec(new String[] { "adb", "-s", device, - "shell", "am", "start", + //"-d", // this is for a single USB device + "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) { diff --git a/app/src/processing/app/tools/android/Device.java b/app/src/processing/app/tools/android/Device.java index 010aa8325..b16c2524e 100644 --- a/app/src/processing/app/tools/android/Device.java +++ b/app/src/processing/app/tools/android/Device.java @@ -132,10 +132,12 @@ public class Device { protected boolean create() throws IOException { + // not using "-s", width + "x" + height, because that can be specified + // on startup, which will be easier to do for Processing apps anyway. String[] cmd = { "android", "create", "avd", "-n", name, - "-t", target -// "-s", width + "x" + height + "-t", target, + "-c", "64M" }; //System.out.println(PApplet.join(cmd, " ")); Process p = Runtime.getRuntime().exec(cmd);