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