mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-07 23:03:11 +08:00
Implement LOAD_URL exec bridge.
Also refactors PluginManager.exec to return the PluginResult instead of a string.
This commit is contained in:
parent
b30f5d782d
commit
250380d73e
@ -20,6 +20,7 @@ package org.apache.cordova;
|
|||||||
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
@ -202,8 +203,8 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
String action = array.getString(1);
|
String action = array.getString(1);
|
||||||
String callbackId = array.getString(2);
|
String callbackId = array.getString(2);
|
||||||
boolean async = array.getBoolean(3);
|
boolean async = array.getBoolean(3);
|
||||||
String r = this.appView.pluginManager.exec(service, action, callbackId, message, async);
|
PluginResult r = this.appView.pluginManager.exec(service, action, callbackId, message, async);
|
||||||
result.confirm(r);
|
result.confirm(r == null ? "" : r.getJSONString());
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import java.util.regex.Pattern;
|
|||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
import org.apache.cordova.api.PluginManager;
|
import org.apache.cordova.api.PluginManager;
|
||||||
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
@ -248,7 +249,8 @@ public class CordovaWebView extends WebView {
|
|||||||
this.addJavascriptInterface(new Object() {
|
this.addJavascriptInterface(new Object() {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public String exec(String service, String action, String callbackId, String arguments) throws JSONException {
|
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");
|
}, "_cordovaExec");
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ package org.apache.cordova;
|
|||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.PluginResult;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ import android.content.res.AssetManager;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.http.SslError;
|
import android.net.http.SslError;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.HttpAuthHandler;
|
import android.webkit.HttpAuthHandler;
|
||||||
import android.webkit.SslErrorHandler;
|
import android.webkit.SslErrorHandler;
|
||||||
@ -50,7 +53,11 @@ import android.webkit.WebViewClient;
|
|||||||
*/
|
*/
|
||||||
public class CordovaWebViewClient extends 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;
|
CordovaInterface cordova;
|
||||||
CordovaWebView appView;
|
CordovaWebView appView;
|
||||||
private boolean doClearHistory = false;
|
private boolean doClearHistory = false;
|
||||||
@ -87,6 +94,29 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
this.appView = view;
|
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
|
* Give the host application a chance to take over the control when a new url
|
||||||
* is about to be loaded in the current WebView.
|
* 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.
|
* @param url The url to be loaded.
|
||||||
* @return true to override, false for default behavior
|
* @return true to override, false for default behavior
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
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
|
// Give plugins the chance to handle the url
|
||||||
if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
|
else if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If dialing phone (tel:5551212)
|
// If dialing phone (tel:5551212)
|
||||||
|
@ -172,9 +172,9 @@ public class PluginManager {
|
|||||||
* immediate return value. If true, either Cordova.callbackSuccess(...) or
|
* immediate return value. If true, either Cordova.callbackSuccess(...) or
|
||||||
* Cordova.callbackError(...) is called once the plugin code has executed.
|
* 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;
|
PluginResult cr = null;
|
||||||
boolean runAsync = async;
|
boolean runAsync = async;
|
||||||
try {
|
try {
|
||||||
@ -190,20 +190,9 @@ public class PluginManager {
|
|||||||
try {
|
try {
|
||||||
// Call execute on the plugin so that it can do it's thing
|
// Call execute on the plugin so that it can do it's thing
|
||||||
PluginResult cr = plugin.execute(action, args, callbackId);
|
PluginResult cr = plugin.execute(action, args, callbackId);
|
||||||
int status = cr.getStatus();
|
String callbackString = cr.toCallbackString(callbackId);
|
||||||
|
if (callbackString != null) {
|
||||||
// If no result to be sent and keeping callback, then no need to sent back to JavaScript
|
app.sendJavascript(callbackString);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
||||||
@ -212,14 +201,14 @@ public class PluginManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
return "";
|
return null;
|
||||||
} else {
|
} else {
|
||||||
// Call execute on the plugin so that it can do it's thing
|
// Call execute on the plugin so that it can do it's thing
|
||||||
cr = plugin.execute(action, args, callbackId);
|
cr = plugin.execute(action, args, callbackId);
|
||||||
|
|
||||||
// If no result to be sent and keeping callback, then no need to sent back to JavaScript
|
// 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()) {
|
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));
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +82,19 @@ public class PluginResult {
|
|||||||
return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}";
|
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) {
|
public String toSuccessCallbackString(String callbackId) {
|
||||||
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
|
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user