You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2012/08/24 20:32:44 UTC
android commit: Implement LOAD_URL exec bridge.
Updated Branches:
refs/heads/master b30f5d782 -> 250380d73
Implement LOAD_URL exec bridge.
Also refactors PluginManager.exec to return the PluginResult instead of
a string.
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/commit/250380d7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/250380d7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/250380d7
Branch: refs/heads/master
Commit: 250380d73e80bf921b06080dbab0b932adb4d62c
Parents: b30f5d7
Author: Andrew Grieve <ag...@chromium.org>
Authored: Fri Aug 24 14:08:53 2012 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Fri Aug 24 14:19:41 2012 -0400
----------------------------------------------------------------------
.../org/apache/cordova/CordovaChromeClient.java | 5 +-
.../src/org/apache/cordova/CordovaWebView.java | 6 ++-
.../org/apache/cordova/CordovaWebViewClient.java | 42 +++++++++++++--
.../src/org/apache/cordova/api/PluginManager.java | 30 ++++-------
.../src/org/apache/cordova/api/PluginResult.java | 13 +++++
5 files changed, 69 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/250380d7/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java
index 72c8626..4fe56ad 100755
--- a/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -20,6 +20,7 @@ package org.apache.cordova;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.LOG;
+import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
@@ -202,8 +203,8 @@ public class CordovaChromeClient extends WebChromeClient {
String action = array.getString(1);
String callbackId = array.getString(2);
boolean async = array.getBoolean(3);
- String r = this.appView.pluginManager.exec(service, action, callbackId, message, async);
- result.confirm(r);
+ PluginResult r = this.appView.pluginManager.exec(service, action, callbackId, message, async);
+ result.confirm(r == null ? "" : r.getJSONString());
} catch (JSONException e) {
e.printStackTrace();
}
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/250380d7/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 7962e81..3f7a504 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -30,6 +30,7 @@ import java.util.regex.Pattern;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.LOG;
import org.apache.cordova.api.PluginManager;
+import org.apache.cordova.api.PluginResult;
import org.json.JSONException;
import org.xmlpull.v1.XmlPullParserException;
@@ -248,7 +249,8 @@ public class CordovaWebView extends WebView {
this.addJavascriptInterface(new Object() {
@SuppressWarnings("unused")
public String exec(String service, String action, String callbackId, String arguments) throws JSONException {
- return pluginManager.exec(service, action, callbackId, arguments, true /* async */);
+ PluginResult r = pluginManager.exec(service, action, callbackId, arguments, true /* async */);
+ return r == null ? "" : r.getJSONString();
}
}, "_cordovaExec");
}
@@ -489,7 +491,7 @@ public class CordovaWebView extends WebView {
// Load url
this.loadUrlIntoView(url);
}
-
+
/**
* Send JavaScript statement back to JavaScript.
* (This is a convenience method)
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/250380d7/framework/src/org/apache/cordova/CordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebViewClient.java b/framework/src/org/apache/cordova/CordovaWebViewClient.java
index 4513a81..28e754a 100755
--- a/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/CordovaWebViewClient.java
@@ -21,6 +21,8 @@ package org.apache.cordova;
import java.util.Hashtable;
import org.apache.cordova.api.CordovaInterface;
+import org.apache.cordova.api.PluginResult;
+
import java.io.IOException;
import java.io.InputStream;
@@ -38,6 +40,7 @@ import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
+import android.util.Log;
import android.view.View;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
@@ -50,7 +53,11 @@ import android.webkit.WebViewClient;
*/
public class CordovaWebViewClient extends WebViewClient {
- private static final String TAG = "Cordova";
+ private static final String TAG = "Cordova";
+ // Disable URL-based exec() bridge by default since it's a bit of a
+ // security concern.
+ private static boolean ENABLE_LOCATION_CHANGE_EXEC_MODE = false;
+ private static final String CORDOVA_EXEC_URL_PREFIX = "http://cdv_exec/";
CordovaInterface cordova;
CordovaWebView appView;
private boolean doClearHistory = false;
@@ -87,6 +94,29 @@ public class CordovaWebViewClient extends WebViewClient {
this.appView = view;
}
+
+ // Parses commands sent by setting the webView's URL to:
+ // cdvbrg:service/action/callbackId#jsonArgs
+ private void handleExecUrl(String url) {
+ int idx1 = CORDOVA_EXEC_URL_PREFIX.length();
+ int idx2 = url.indexOf('#', idx1 + 1);
+ int idx3 = url.indexOf('#', idx2 + 1);
+ int idx4 = url.indexOf('#', idx3 + 1);
+ if (idx1 == -1 || idx2 == -1 || idx3 == -1 || idx4 == -1) {
+ Log.e(TAG, "Could not decode URL command: " + url);
+ return;
+ }
+ String service = url.substring(idx1, idx2);
+ String action = url.substring(idx2 + 1, idx3);
+ String callbackId = url.substring(idx3 + 1, idx4);
+ String jsonArgs = url.substring(idx4 + 1);
+ PluginResult r = appView.pluginManager.exec(service, action, callbackId, jsonArgs, true /* async */);
+ String callbackString = r.toCallbackString(callbackId);
+ if (r != null) {
+ appView.sendJavascript(callbackString);
+ }
+ }
+
/**
* Give the host application a chance to take over the control when a new url
* is about to be loaded in the current WebView.
@@ -95,11 +125,15 @@ public class CordovaWebViewClient extends WebViewClient {
* @param url The url to be loaded.
* @return true to override, false for default behavior
*/
- @Override
+ @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ // Check if it's an exec() bridge command message.
+ if (ENABLE_LOCATION_CHANGE_EXEC_MODE && url.startsWith(CORDOVA_EXEC_URL_PREFIX)) {
+ handleExecUrl(url);
+ }
- // First give any plugins the chance to handle the url themselves
- if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
+ // Give plugins the chance to handle the url
+ else if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
}
// If dialing phone (tel:5551212)
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/250380d7/framework/src/org/apache/cordova/api/PluginManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/PluginManager.java b/framework/src/org/apache/cordova/api/PluginManager.java
index a48de67..1f4ea1e 100755
--- a/framework/src/org/apache/cordova/api/PluginManager.java
+++ b/framework/src/org/apache/cordova/api/PluginManager.java
@@ -172,9 +172,9 @@ public class PluginManager {
* immediate return value. If true, either Cordova.callbackSuccess(...) or
* Cordova.callbackError(...) is called once the plugin code has executed.
*
- * @return JSON encoded string with a response message and status.
+ * @return PluginResult to send to the page, or null if no response is ready yet.
*/
- public String exec(final String service, final String action, final String callbackId, final String jsonArgs, final boolean async) {
+ public PluginResult exec(final String service, final String action, final String callbackId, final String jsonArgs, final boolean async) {
PluginResult cr = null;
boolean runAsync = async;
try {
@@ -190,20 +190,9 @@ public class PluginManager {
try {
// Call execute on the plugin so that it can do it's thing
PluginResult cr = plugin.execute(action, args, callbackId);
- int status = cr.getStatus();
-
- // If no result to be sent and keeping callback, then no need to sent back to JavaScript
- if ((status == PluginResult.Status.NO_RESULT.ordinal()) && cr.getKeepCallback()) {
- }
-
- // Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
- else if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
- app.sendJavascript(cr.toSuccessCallbackString(callbackId));
- }
-
- // If error
- else {
- app.sendJavascript(cr.toErrorCallbackString(callbackId));
+ String callbackString = cr.toCallbackString(callbackId);
+ if (callbackString != null) {
+ app.sendJavascript(callbackString);
}
} catch (Exception e) {
PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
@@ -212,14 +201,14 @@ public class PluginManager {
}
});
thread.start();
- return "";
+ return null;
} else {
// Call execute on the plugin so that it can do it's thing
cr = plugin.execute(action, args, callbackId);
// If no result to be sent and keeping callback, then no need to sent back to JavaScript
if ((cr.getStatus() == PluginResult.Status.NO_RESULT.ordinal()) && cr.getKeepCallback()) {
- return "";
+ return null;
}
}
}
@@ -234,7 +223,10 @@ public class PluginManager {
}
app.sendJavascript(cr.toErrorCallbackString(callbackId));
}
- return (cr != null ? cr.getJSONString() : "{ status: 0, message: 'all good' }");
+ if (cr == null) {
+ cr = new PluginResult(PluginResult.Status.NO_RESULT);
+ }
+ return cr;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/250380d7/framework/src/org/apache/cordova/api/PluginResult.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/PluginResult.java b/framework/src/org/apache/cordova/api/PluginResult.java
index b5ae304..eacf6d5 100755
--- a/framework/src/org/apache/cordova/api/PluginResult.java
+++ b/framework/src/org/apache/cordova/api/PluginResult.java
@@ -82,6 +82,19 @@ public class PluginResult {
return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}";
}
+ public String toCallbackString(String callbackId) {
+ // If no result to be sent and keeping callback, then no need to sent back to JavaScript
+ if ((status == PluginResult.Status.NO_RESULT.ordinal()) && keepCallback) {
+ return null;
+ }
+
+ // Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
+ if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
+ return toSuccessCallbackString(callbackId);
+ }
+
+ return toErrorCallbackString(callbackId);
+ }
public String toSuccessCallbackString(String callbackId) {
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
}