diff --git a/framework/assets/js/cache.js b/framework/assets/js/cache.js
new file mode 100644
index 00000000..28d55ce2
--- /dev/null
+++ b/framework/assets/js/cache.js
@@ -0,0 +1,18 @@
+PhoneGap.addPlugin = function(name, obj) {
+ if ( !window.plugins ) {
+ window.plugins = {};
+ }
+
+ if ( !window.plugins[name] ) {
+ window.plugins[name] = obj;
+ }
+}
+
+function Cache() {
+}
+
+Cache.prototype.getCachedPathForURI = function(uri, success, fail) {
+ PhoneGap.execAsync(success, fail, 'com.phonegap.api.impl.Cache', 'getCachedPathForURI', [uri]);
+};
+
+PhoneGap.addPlugin('cache', new Cache());
\ No newline at end of file
diff --git a/framework/assets/js/phonegap.js.base b/framework/assets/js/phonegap.js.base
index d80adc83..0e24a82a 100755
--- a/framework/assets/js/phonegap.js.base
+++ b/framework/assets/js/phonegap.js.base
@@ -6,7 +6,7 @@ if (typeof(DeviceInfo) != 'object')
* information about the state of PhoneGap.
* @class
*/
-PhoneGap = {
+var PhoneGap = {
queue: {
ready: true,
commands: [],
@@ -205,6 +205,8 @@ document.addEventListener = function(evt, handler, capture) {
+PhoneGap.callbackId = 0;
+PhoneGap.callbacks = {};
/**
* Execute a PhoneGap command in a queued fashion, to ensure commands do not
@@ -213,12 +215,28 @@ document.addEventListener = function(evt, handler, capture) {
* @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method"
* @param {String[]} [args] Zero or more arguments to pass to the method
*/
-PhoneGap.exec = function() {
- PhoneGap.queue.commands.push(arguments);
- if (PhoneGap.queue.timer == null)
- PhoneGap.queue.timer = setInterval(PhoneGap.run_command, 10);
+PhoneGap.exec = function(clazz, action, args) {
+ CommandManager.exec(clazz, action, callbackId, args.join('__PHONEGAP__'), false);
};
+PhoneGap.execAsync = function(success, fail, clazz, action, args) {
+ var callbackId = clazz + PhoneGap.callbackId++;
+ PhoneGap.callbacks[callbackId] = {success:success, fail:fail};
+ CommandManager.exec(clazz, action, callbackId, args.join('__PHONEGAP__'), true);
+ return callbackId;
+};
+
+PhoneGap.callbackSuccess = function(callbackId, args) {
+ PhoneGap.callbacks[callbackId].success.apply(this, JSON.parse(args));
+ delete PhoneGap.callbacks[callbackId];
+};
+
+PhoneGap.callbackFailure = function(callbackId, args) {
+ PhoneGap.callbacks[callbackId].fail.apply(this, JSON.parse(args));
+ delete PhoneGap.callbacks[callbackId];
+};
+
+
/**
* Internal function used to dispatch the request to PhoneGap. It processes the
* command queue and executes the next command on the list. If one of the
diff --git a/framework/export-phonegap.jardesc b/framework/export-phonegap.jardesc
deleted file mode 100644
index 04227fe4..00000000
--- a/framework/export-phonegap.jardesc
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/framework/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java
index cd9bdb83..ce9b7604 100755
--- a/framework/src/com/phonegap/DroidGap.java
+++ b/framework/src/com/phonegap/DroidGap.java
@@ -25,6 +25,9 @@ package com.phonegap;
import java.io.File;
+import com.phonegap.api.Command;
+import com.phonegap.api.CommandManager;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
@@ -73,6 +76,7 @@ public class DroidGap extends Activity {
private BrowserKey mKey;
private AudioHandler audio;
private CallbackServer callbackServer;
+ private CommandManager commandManager;
private Uri imageUri;
@@ -231,6 +235,7 @@ public class DroidGap extends Activity {
private void bindBrowser(WebView appView)
{
callbackServer = new CallbackServer();
+ commandManager = new CommandManager(appView, this);
gap = new Device(appView, this);
accel = new AccelListener(appView, this);
launcher = new CameraLauncher(appView, this);
@@ -243,6 +248,7 @@ public class DroidGap extends Activity {
audio = new AudioHandler(appView, this);
// This creates the new javascript interfaces for PhoneGap
+ appView.addJavascriptInterface(commandManager, "CommandManager");
appView.addJavascriptInterface(gap, "DroidGap");
appView.addJavascriptInterface(accel, "Accel");
appView.addJavascriptInterface(launcher, "GapCam");
@@ -263,7 +269,6 @@ public class DroidGap extends Activity {
appView.addJavascriptInterface(geo, "Geo");
}
}
-
public void loadUrl(String url)
{
@@ -288,7 +293,6 @@ public class DroidGap extends Activity {
return this.callbackServer.getPort();
}
-
/**
* Provides a hook for calling "alert" from javascript. Useful for
* debugging your javascript.
diff --git a/framework/src/com/phonegap/api/Command.java b/framework/src/com/phonegap/api/Command.java
new file mode 100644
index 00000000..479a3535
--- /dev/null
+++ b/framework/src/com/phonegap/api/Command.java
@@ -0,0 +1,24 @@
+package com.phonegap.api;
+
+import android.content.Context;
+
+public interface Command {
+ /**
+ * Executes the request and returns JS code to change client state.
+ *
+ * @param action the command to execute
+ * @return a string with JavaScript code or null
+ */
+ CommandResult execute(String action, String[] args);
+
+ /**
+ * Determines if this command can process a request.
+ *
+ * @param action the command to execute
+ *
+ * @return true if this command understands the petition
+ */
+ boolean accept(String action);
+
+ void setContext(Context ctx);
+}
diff --git a/framework/src/com/phonegap/api/CommandManager.java b/framework/src/com/phonegap/api/CommandManager.java
new file mode 100644
index 00000000..58bb146d
--- /dev/null
+++ b/framework/src/com/phonegap/api/CommandManager.java
@@ -0,0 +1,80 @@
+package com.phonegap.api;
+
+import android.content.Context;
+import android.webkit.WebView;
+
+import com.phonegap.DroidGap;
+
+/**
+ * Given a execution request detects matching {@link Command} and executes it.
+ */
+public final class CommandManager {
+ private static final String EXCEPTION_PREFIX = "[PhoneGap] *ERROR* Exception executing command [";
+ private static final String EXCEPTION_SUFFIX = "]: ";
+
+ private Command[] commands;
+
+ private final Context ctx;
+ private final WebView app;
+
+ public CommandManager(WebView app, Context ctx) {
+ this.ctx = ctx;
+ this.app = app;
+ }
+
+ /**
+ * Receives a request for execution and fulfills it as long as one of
+ * the configured {@link Command} can understand it. Command precedence
+ * is important (just one of them will be executed).
+ *
+ * @param instruction any API command
+ * @return JS code to execute by the client or null
+ */
+ public String exec(final String clazz, final String action, final String callbackId,
+ final String args, final boolean async) {
+ CommandResult cr = null;
+ try {
+ //final WebView wv = this.app;
+ final String _callbackId = callbackId;
+ final String[] aargs = args.split("__PHONEGAP__");
+ Class c = Class.forName(clazz);
+ Class[] interfaces = c.getInterfaces();
+ for (int j=0; j