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 <agri...@chromium.org>
Authored: Fri Aug 24 14:08:53 2012 -0400
Committer: Andrew Grieve <agri...@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()+");";
     }

Reply via email to