mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 20:33:07 +08:00
Delete Cordova*Client classes, Create CordovaBridge, Delete more CordovaWebView symbols
Changes made in order to get xwalk working again
This commit is contained in:
parent
25a7b66296
commit
efcedabee0
@ -20,8 +20,6 @@ package org.apache.cordova;
|
|||||||
|
|
||||||
import org.apache.cordova.CordovaInterface;
|
import org.apache.cordova.CordovaInterface;
|
||||||
import org.apache.cordova.LOG;
|
import org.apache.cordova.LOG;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@ -44,7 +42,6 @@ import android.widget.EditText;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the WebChromeClient that implements callbacks for our web view.
|
* This class is the WebChromeClient that implements callbacks for our web view.
|
||||||
@ -57,7 +54,7 @@ import android.util.Log;
|
|||||||
* @see CordovaWebViewClient
|
* @see CordovaWebViewClient
|
||||||
* @see CordovaWebView
|
* @see CordovaWebView
|
||||||
*/
|
*/
|
||||||
public class AndroidChromeClient extends WebChromeClient implements CordovaChromeClient {
|
public class AndroidChromeClient extends WebChromeClient {
|
||||||
|
|
||||||
public static final int FILECHOOSER_RESULTCODE = 5173;
|
public static final int FILECHOOSER_RESULTCODE = 5173;
|
||||||
private static final String LOG_TAG = "AndroidChromeClient";
|
private static final String LOG_TAG = "AndroidChromeClient";
|
||||||
@ -69,7 +66,7 @@ public class AndroidChromeClient extends WebChromeClient implements CordovaChrom
|
|||||||
private View mVideoProgressView;
|
private View mVideoProgressView;
|
||||||
|
|
||||||
// File Chooser
|
// File Chooser
|
||||||
public ValueCallback<Uri> mUploadMessage;
|
protected ValueCallback<Uri> mUploadMessage;
|
||||||
|
|
||||||
public AndroidChromeClient(CordovaInterface ctx, AndroidWebView app) {
|
public AndroidChromeClient(CordovaInterface ctx, AndroidWebView app) {
|
||||||
this.cordova = ctx;
|
this.cordova = ctx;
|
||||||
@ -182,67 +179,9 @@ public class AndroidChromeClient extends WebChromeClient implements CordovaChrom
|
|||||||
@Override
|
@Override
|
||||||
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, JsPromptResult result) {
|
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, JsPromptResult result) {
|
||||||
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
|
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
|
||||||
if (defaultValue != null && defaultValue.length() > 3 && defaultValue.startsWith("gap:")) {
|
String handledRet = appView.bridge.promptOnJsPrompt(origin, message, defaultValue);
|
||||||
JSONArray array;
|
if (handledRet != null) {
|
||||||
try {
|
result.confirm(handledRet);
|
||||||
array = new JSONArray(defaultValue.substring(4));
|
|
||||||
int bridgeSecret = array.getInt(0);
|
|
||||||
String service = array.getString(1);
|
|
||||||
String action = array.getString(2);
|
|
||||||
String callbackId = array.getString(3);
|
|
||||||
String r = appView.exposedJsApi.exec(bridgeSecret, service, action, callbackId, message);
|
|
||||||
result.confirm(r == null ? "" : r);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the native->JS bridge mode.
|
|
||||||
else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) {
|
|
||||||
try {
|
|
||||||
int bridgeSecret = Integer.parseInt(defaultValue.substring(16));
|
|
||||||
appView.exposedJsApi.setNativeToJsBridgeMode(bridgeSecret, Integer.parseInt(message));
|
|
||||||
result.cancel();
|
|
||||||
} catch (NumberFormatException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Polling for JavaScript messages
|
|
||||||
else if (defaultValue != null && defaultValue.startsWith("gap_poll:")) {
|
|
||||||
int bridgeSecret = Integer.parseInt(defaultValue.substring(9));
|
|
||||||
try {
|
|
||||||
String r = appView.exposedJsApi.retrieveJsMessages(bridgeSecret, "1".equals(message));
|
|
||||||
result.confirm(r == null ? "" : r);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
|
|
||||||
// Protect against random iframes being able to talk through the bridge.
|
|
||||||
// Trust only file URLs and the start URL's domain.
|
|
||||||
// The extra origin.startsWith("http") is to protect against iframes with data: having "" as origin.
|
|
||||||
if (origin.startsWith("file:") || (origin.startsWith("http") && appView.loadedUrl.startsWith(origin))) {
|
|
||||||
// Enable the bridge
|
|
||||||
int bridgeMode = Integer.parseInt(defaultValue.substring(9));
|
|
||||||
appView.jsMessageQueue.setBridgeMode(bridgeMode);
|
|
||||||
// Tell JS the bridge secret.
|
|
||||||
int secret = appView.exposedJsApi.generateBridgeSecret();
|
|
||||||
result.confirm(""+secret);
|
|
||||||
} else {
|
|
||||||
Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Returning false would also show a dialog, but the default one shows the origin (ugly).
|
// Returning false would also show a dialog, but the default one shows the origin (ugly).
|
||||||
final JsPromptResult res = result;
|
final JsPromptResult res = result;
|
||||||
@ -375,8 +314,4 @@ public class AndroidChromeClient extends WebChromeClient implements CordovaChrom
|
|||||||
this.cordova.getActivity().startActivityForResult(Intent.createChooser(i, "File Browser"),
|
this.cordova.getActivity().startActivityForResult(Intent.createChooser(i, "File Browser"),
|
||||||
FILECHOOSER_RESULTCODE);
|
FILECHOOSER_RESULTCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueCallback<Uri> getValueCallback() {
|
|
||||||
return this.mUploadMessage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import android.webkit.JavascriptInterface;
|
import android.webkit.JavascriptInterface;
|
||||||
import org.apache.cordova.PluginManager;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,70 +27,24 @@ import org.json.JSONException;
|
|||||||
* cordova-js/lib/android/plugin/android/promptbasednativeapi.js
|
* cordova-js/lib/android/plugin/android/promptbasednativeapi.js
|
||||||
*/
|
*/
|
||||||
class AndroidExposedJsApi implements ExposedJsApi {
|
class AndroidExposedJsApi implements ExposedJsApi {
|
||||||
|
private final CordovaBridge bridge;
|
||||||
|
|
||||||
private PluginManager pluginManager;
|
AndroidExposedJsApi(CordovaBridge bridge) {
|
||||||
private NativeToJsMessageQueue jsMessageQueue;
|
this.bridge = bridge;
|
||||||
private volatile int bridgeSecret = -1; // written by UI thread, read by JS thread.
|
|
||||||
|
|
||||||
public AndroidExposedJsApi(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue) {
|
|
||||||
this.pluginManager = pluginManager;
|
|
||||||
this.jsMessageQueue = jsMessageQueue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
|
public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
|
||||||
verifySecret(bridgeSecret);
|
return bridge.jsExec(bridgeSecret, service, action, callbackId, arguments);
|
||||||
// If the arguments weren't received, send a message back to JS. It will switch bridge modes and try again. See CB-2666.
|
|
||||||
// We send a message meant specifically for this case. It starts with "@" so no other message can be encoded into the same string.
|
|
||||||
if (arguments == null) {
|
|
||||||
return "@Null arguments.";
|
|
||||||
}
|
|
||||||
|
|
||||||
jsMessageQueue.setPaused(true);
|
|
||||||
try {
|
|
||||||
// Tell the resourceApi what thread the JS is running on.
|
|
||||||
CordovaResourceApi.jsThread = Thread.currentThread();
|
|
||||||
|
|
||||||
pluginManager.exec(service, action, callbackId, arguments);
|
|
||||||
String ret = "";
|
|
||||||
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
|
|
||||||
ret = jsMessageQueue.popAndEncode(false);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return "";
|
|
||||||
} finally {
|
|
||||||
jsMessageQueue.setPaused(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
|
public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
|
||||||
verifySecret(bridgeSecret);
|
bridge.jsSetNativeToJsBridgeMode(bridgeSecret, value);
|
||||||
jsMessageQueue.setBridgeMode(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
|
public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
|
||||||
verifySecret(bridgeSecret);
|
return bridge.jsRetrieveJsMessages(bridgeSecret, fromOnlineEvent);
|
||||||
return jsMessageQueue.popAndEncode(fromOnlineEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifySecret(int value) throws IllegalAccessException {
|
|
||||||
if (bridgeSecret < 0 || value != bridgeSecret) {
|
|
||||||
throw new IllegalAccessException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called on page transitions */
|
|
||||||
void clearBridgeSecret() {
|
|
||||||
bridgeSecret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called by cordova.js to initialize the bridge. */
|
|
||||||
int generateBridgeSecret() {
|
|
||||||
bridgeSecret = (int)(Math.random() * Integer.MAX_VALUE);
|
|
||||||
return bridgeSecret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
@ -66,23 +65,21 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
private HashSet<Integer> boundKeyCodes = new HashSet<Integer>();
|
private HashSet<Integer> boundKeyCodes = new HashSet<Integer>();
|
||||||
|
|
||||||
PluginManager pluginManager;
|
PluginManager pluginManager;
|
||||||
private boolean paused;
|
|
||||||
|
|
||||||
private BroadcastReceiver receiver;
|
private BroadcastReceiver receiver;
|
||||||
|
|
||||||
|
|
||||||
/** Activities and other important classes **/
|
/** Activities and other important classes **/
|
||||||
private CordovaInterface cordova;
|
private CordovaInterface cordova;
|
||||||
CordovaWebViewClient viewClient;
|
AndroidWebViewClient viewClient;
|
||||||
private CordovaChromeClient chromeClient;
|
private AndroidChromeClient chromeClient;
|
||||||
|
|
||||||
// Flag to track that a loadUrl timeout occurred
|
// Flag to track that a loadUrl timeout occurred
|
||||||
int loadUrlTimeout = 0;
|
int loadUrlTimeout = 0;
|
||||||
|
|
||||||
private long lastMenuEventTime = 0;
|
private long lastMenuEventTime = 0;
|
||||||
|
|
||||||
NativeToJsMessageQueue jsMessageQueue;
|
CordovaBridge bridge;
|
||||||
AndroidExposedJsApi exposedJsApi;
|
|
||||||
|
|
||||||
/** custom view created by the browser (a video player for example) */
|
/** custom view created by the browser (a video player for example) */
|
||||||
private View mCustomView;
|
private View mCustomView;
|
||||||
@ -94,21 +91,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
// The URL passed to loadUrl(), not necessarily the URL of the current page.
|
// The URL passed to loadUrl(), not necessarily the URL of the current page.
|
||||||
String loadedUrl;
|
String loadedUrl;
|
||||||
|
|
||||||
class ActivityResult {
|
|
||||||
|
|
||||||
int request;
|
|
||||||
int result;
|
|
||||||
Intent incoming;
|
|
||||||
|
|
||||||
public ActivityResult(int req, int res, Intent intent) {
|
|
||||||
request = req;
|
|
||||||
result = res;
|
|
||||||
incoming = intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
|
static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
|
||||||
new FrameLayout.LayoutParams(
|
new FrameLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
@ -127,24 +109,30 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
|
|
||||||
// Use two-phase init so that the control will work with XML layouts.
|
// Use two-phase init so that the control will work with XML layouts.
|
||||||
@Override
|
@Override
|
||||||
public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
|
public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries,
|
||||||
List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) {
|
Whitelist whitelist, CordovaPreferences preferences) {
|
||||||
if (this.cordova != null) {
|
if (this.cordova != null) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
this.cordova = cordova;
|
this.cordova = cordova;
|
||||||
setWebChromeClient(webChromeClient);
|
|
||||||
setWebViewClient(webViewClient);
|
|
||||||
this.whitelist = whitelist;
|
this.whitelist = whitelist;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
|
|
||||||
pluginManager = new PluginManager(this, this.cordova, pluginEntries);
|
pluginManager = new PluginManager(this, this.cordova, pluginEntries);
|
||||||
jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
|
|
||||||
exposedJsApi = new AndroidExposedJsApi(pluginManager, jsMessageQueue);
|
|
||||||
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
|
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
|
||||||
|
bridge = new CordovaBridge(pluginManager, new NativeToJsMessageQueue(this, cordova));
|
||||||
pluginManager.addService("App", "org.apache.cordova.CoreAndroid");
|
pluginManager.addService("App", "org.apache.cordova.CoreAndroid");
|
||||||
initWebViewSettings();
|
initWebViewSettings();
|
||||||
|
|
||||||
|
if (this.viewClient == null) {
|
||||||
|
setWebViewClient(Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH ?
|
||||||
|
new AndroidWebViewClient(cordova, this) :
|
||||||
|
new IceCreamCordovaWebViewClient(cordova, this));
|
||||||
|
}
|
||||||
|
if (this.chromeClient == null) {
|
||||||
|
setWebChromeClient(new AndroidChromeClient(cordova, this));
|
||||||
|
}
|
||||||
|
|
||||||
exposeJsInterface();
|
exposeJsInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,19 +241,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CordovaChromeClient makeWebChromeClient(CordovaInterface cordova) {
|
|
||||||
return new AndroidChromeClient(cordova, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CordovaWebViewClient makeWebViewClient(CordovaInterface cordova) {
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
|
||||||
return new AndroidWebViewClient(cordova, this);
|
|
||||||
}
|
|
||||||
return new IceCreamCordovaWebViewClient(cordova, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method to decide whether or not you need to request the
|
* Override this method to decide whether or not you need to request the
|
||||||
* focus when your application start
|
* focus when your application start
|
||||||
@ -284,80 +259,42 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
// use the prompt bridge instead.
|
// use the prompt bridge instead.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
AndroidExposedJsApi exposedJsApi = new AndroidExposedJsApi(bridge);
|
||||||
this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
|
this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWebViewClient(WebViewClient client) {
|
public void setWebViewClient(WebViewClient client) {
|
||||||
this.viewClient = (CordovaWebViewClient)client;
|
this.viewClient = (AndroidWebViewClient)client;
|
||||||
super.setWebViewClient(client);
|
super.setWebViewClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWebChromeClient(WebChromeClient client) {
|
public void setWebChromeClient(WebChromeClient client) {
|
||||||
this.chromeClient = (CordovaChromeClient)client;
|
this.chromeClient = (AndroidChromeClient)client;
|
||||||
super.setWebChromeClient(client);
|
super.setWebChromeClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setWebViewClient(CordovaWebViewClient client) {
|
|
||||||
setWebViewClient((WebViewClient) client);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setWebChromeClient(CordovaChromeClient client) {
|
|
||||||
setWebChromeClient((WebChromeClient) client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CordovaChromeClient getWebChromeClient() {
|
|
||||||
return this.chromeClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the url into the webview.
|
* Load the url into the webview.
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void loadUrl(String url) {
|
public void loadUrl(String url) {
|
||||||
if (url.equals("about:blank") || url.startsWith("javascript:")) {
|
this.loadUrlIntoView(url, true);
|
||||||
this.loadUrlNow(url);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.loadUrlIntoView(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the url into the webview after waiting for period of time.
|
|
||||||
* This is used to display the splashscreen for certain amount of time.
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
* @param time The number of ms to wait before loading webview
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void loadUrl(final String url, int time) {
|
|
||||||
if(url == null)
|
|
||||||
{
|
|
||||||
this.loadUrlIntoView(Config.getStartUrl());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.loadUrlIntoView(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadUrlIntoView(final String url) {
|
|
||||||
loadUrlIntoView(url, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the url into the webview.
|
* Load the url into the webview.
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void loadUrlIntoView(final String url, boolean recreatePlugins) {
|
public void loadUrlIntoView(final String url, boolean recreatePlugins) {
|
||||||
|
if (url.equals("about:blank") || url.startsWith("javascript:")) {
|
||||||
|
this.loadUrlNow(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LOG.d(TAG, ">>> loadUrl(" + url + ")");
|
LOG.d(TAG, ">>> loadUrl(" + url + ")");
|
||||||
|
recreatePlugins = recreatePlugins || (loadedUrl == null);
|
||||||
|
|
||||||
if (recreatePlugins) {
|
if (recreatePlugins) {
|
||||||
this.loadedUrl = url;
|
this.loadedUrl = url;
|
||||||
@ -367,7 +304,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
// Create a timeout timer for loadUrl
|
// Create a timeout timer for loadUrl
|
||||||
final AndroidWebView me = this;
|
final AndroidWebView me = this;
|
||||||
final int currentLoadUrlTimeout = me.loadUrlTimeout;
|
final int currentLoadUrlTimeout = me.loadUrlTimeout;
|
||||||
final int loadUrlTimeoutValue = Integer.parseInt(this.getProperty("LoadUrlTimeoutValue", "20000"));
|
final int loadUrlTimeoutValue = preferences.getInteger("LoadUrlTimeoutValue", 20000);
|
||||||
|
|
||||||
// Timeout error method
|
// Timeout error method
|
||||||
final Runnable loadError = new Runnable() {
|
final Runnable loadError = new Runnable() {
|
||||||
@ -375,7 +312,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
me.stopLoading();
|
me.stopLoading();
|
||||||
LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
|
LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
|
||||||
if (viewClient != null) {
|
if (viewClient != null) {
|
||||||
viewClient.onReceivedError(-6, "The connection to the server was unsuccessful.", url);
|
viewClient.onReceivedError(AndroidWebView.this, -6, "The connection to the server was unsuccessful.", url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -409,10 +346,8 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load URL in webview.
|
* Load URL in webview.
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
*/
|
*/
|
||||||
public void loadUrlNow(String url) {
|
private void loadUrlNow(String url) {
|
||||||
if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
|
if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
|
||||||
LOG.d(TAG, ">>> loadUrlNow()");
|
LOG.d(TAG, ">>> loadUrlNow()");
|
||||||
}
|
}
|
||||||
@ -421,33 +356,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the url into the webview after waiting for period of time.
|
|
||||||
* This is used to display the splashscreen for certain amount of time.
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
* @param time The number of ms to wait before loading webview
|
|
||||||
*/
|
|
||||||
public void loadUrlIntoView(final String url, final int time) {
|
|
||||||
|
|
||||||
// If not first page of app, then load immediately
|
|
||||||
// Add support for browser history if we use it.
|
|
||||||
if ((url.startsWith("javascript:")) || this.canGoBack()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// If first page, then show splashscreen
|
|
||||||
else {
|
|
||||||
|
|
||||||
LOG.d(TAG, "loadUrlIntoView(%s, %d)", url, time);
|
|
||||||
|
|
||||||
// Send message to show splashscreen now if desired
|
|
||||||
this.postMessage("splashscreen", "show");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load url
|
|
||||||
this.loadUrlIntoView(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopLoading() {
|
public void stopLoading() {
|
||||||
//viewClient.isCurrentlyLoading = false;
|
//viewClient.isCurrentlyLoading = false;
|
||||||
@ -459,43 +367,24 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
super.onScrollChanged(l, t, oldl, oldt);
|
super.onScrollChanged(l, t, oldl, oldt);
|
||||||
//We should post a message that the scroll changed
|
//We should post a message that the scroll changed
|
||||||
ScrollEvent myEvent = new ScrollEvent(l, t, oldl, oldt, this);
|
ScrollEvent myEvent = new ScrollEvent(l, t, oldl, oldt, this);
|
||||||
this.postMessage("onScrollChanged", myEvent);
|
pluginManager.postMessage("onScrollChanged", myEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send JavaScript statement back to JavaScript.
|
* Send JavaScript statement back to JavaScript.
|
||||||
* (This is a convenience method)
|
* (This is a convenience method)
|
||||||
*
|
|
||||||
* @param statement
|
|
||||||
*/
|
*/
|
||||||
public void sendJavascript(String statement) {
|
public void sendJavascript(String statement) {
|
||||||
this.jsMessageQueue.addJavaScript(statement);
|
bridge.getMessageQueue().addJavaScript(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a plugin result back to JavaScript.
|
* Send a plugin result back to JavaScript.
|
||||||
* (This is a convenience method)
|
|
||||||
*
|
|
||||||
* @param result
|
|
||||||
* @param callbackId
|
|
||||||
*/
|
*/
|
||||||
public void sendPluginResult(PluginResult result, String callbackId) {
|
public void sendPluginResult(PluginResult result, String callbackId) {
|
||||||
this.jsMessageQueue.addPluginResult(result, callbackId);
|
bridge.getMessageQueue().addPluginResult(result, callbackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a message to all plugins.
|
|
||||||
*
|
|
||||||
* @param id The message id
|
|
||||||
* @param data The message data
|
|
||||||
*/
|
|
||||||
public void postMessage(String id, Object data) {
|
|
||||||
if (this.pluginManager != null) {
|
|
||||||
this.pluginManager.postMessage(id, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Go to previous page in history. (We manage our own history)
|
* Go to previous page in history. (We manage our own history)
|
||||||
*
|
*
|
||||||
@ -540,7 +429,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
if (url.startsWith("file://") || whitelist.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || whitelist.isUrlWhiteListed(url)) {
|
||||||
// TODO: What about params?
|
// TODO: What about params?
|
||||||
// Load new URL
|
// Load new URL
|
||||||
this.loadUrl(url);
|
loadUrlIntoView(url, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Load in default viewer if not
|
// Load in default viewer if not
|
||||||
@ -562,26 +451,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get string property for activity.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* @param defaultValue
|
|
||||||
* @return the String value for the named property
|
|
||||||
*/
|
|
||||||
public String getProperty(String name, String defaultValue) {
|
|
||||||
Bundle bundle = this.cordova.getActivity().getIntent().getExtras();
|
|
||||||
if (bundle == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
name = name.toLowerCase(Locale.getDefault());
|
|
||||||
Object p = bundle.get(name);
|
|
||||||
if (p == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return p.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* onKeyDown
|
* onKeyDown
|
||||||
*/
|
*/
|
||||||
@ -705,13 +574,10 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
// Pause JavaScript timers (including setInterval)
|
// Pause JavaScript timers (including setInterval)
|
||||||
this.pauseTimers();
|
this.pauseTimers();
|
||||||
}
|
}
|
||||||
paused = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
|
public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
|
||||||
{
|
{
|
||||||
|
|
||||||
this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
|
this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
|
||||||
|
|
||||||
// Forward to plugins
|
// Forward to plugins
|
||||||
@ -721,7 +587,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
|
|
||||||
// Resume JavaScript timers (including setInterval)
|
// Resume JavaScript timers (including setInterval)
|
||||||
this.resumeTimers();
|
this.resumeTimers();
|
||||||
paused = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleDestroy()
|
public void handleDestroy()
|
||||||
@ -755,11 +620,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPaused()
|
|
||||||
{
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapping these functions in their own class prevents warnings in adb like:
|
// Wrapping these functions in their own class prevents warnings in adb like:
|
||||||
// VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs
|
// VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs
|
||||||
@TargetApi(16)
|
@TargetApi(16)
|
||||||
@ -862,57 +722,17 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
return resourceApi;
|
return resourceApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLayoutParams(
|
|
||||||
android.widget.LinearLayout.LayoutParams layoutParams) {
|
|
||||||
super.setLayoutParams(layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOverScrollMode(int mode) {
|
|
||||||
super.setOverScrollMode(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addJavascript(String statement) {
|
|
||||||
this.jsMessageQueue.addJavaScript(statement);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CordovaPlugin getPlugin(String initCallbackClass) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return this.pluginManager.getPlugin(initCallbackClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOverrideUrlLoading(String url) {
|
|
||||||
return this.pluginManager.onOverrideUrlLoading(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onPageReset() {
|
void onPageReset() {
|
||||||
boundKeyCodes.clear();
|
boundKeyCodes.clear();
|
||||||
pluginManager.onReset();
|
pluginManager.onReset();
|
||||||
jsMessageQueue.reset();
|
bridge.reset(loadedUrl);
|
||||||
exposedJsApi.clearBridgeSecret();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void incUrlTimeout() {
|
|
||||||
this.loadUrlTimeout++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginManager getPluginManager() {
|
public PluginManager getPluginManager() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return this.pluginManager;
|
return this.pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLayoutParams(
|
|
||||||
android.widget.FrameLayout.LayoutParams layoutParams) {
|
|
||||||
super.setLayoutParams(layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView() {
|
public View getView() {
|
||||||
return this;
|
return this;
|
||||||
@ -927,4 +747,17 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
|||||||
public CordovaPreferences getPreferences() {
|
public CordovaPreferences getPreferences() {
|
||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFilePickerResult(Uri uri) {
|
||||||
|
if (null == chromeClient.mUploadMessage)
|
||||||
|
return;
|
||||||
|
chromeClient.mUploadMessage.onReceiveValue(uri);
|
||||||
|
chromeClient.mUploadMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object postMessage(String id, Object data) {
|
||||||
|
return pluginManager.postMessage(id, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ import android.webkit.WebViewClient;
|
|||||||
* @see CordovaChromeClient
|
* @see CordovaChromeClient
|
||||||
* @see CordovaWebView
|
* @see CordovaWebView
|
||||||
*/
|
*/
|
||||||
public class AndroidWebViewClient extends WebViewClient implements CordovaWebViewClient{
|
public class AndroidWebViewClient extends WebViewClient {
|
||||||
|
|
||||||
private static final String TAG = "AndroidWebViewClient";
|
private static final String TAG = "AndroidWebViewClient";
|
||||||
protected final CordovaInterface cordova;
|
protected final CordovaInterface cordova;
|
||||||
@ -60,12 +60,6 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
/** The authorization tokens. */
|
/** The authorization tokens. */
|
||||||
private Hashtable<String, AuthenticationToken> authenticationTokens = new Hashtable<String, AuthenticationToken>();
|
private Hashtable<String, AuthenticationToken> authenticationTokens = new Hashtable<String, AuthenticationToken>();
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param cordova
|
|
||||||
* @param view
|
|
||||||
*/
|
|
||||||
public AndroidWebViewClient(CordovaInterface cordova, AndroidWebView view) {
|
public AndroidWebViewClient(CordovaInterface cordova, AndroidWebView view) {
|
||||||
this.cordova = cordova;
|
this.cordova = cordova;
|
||||||
this.appView = view;
|
this.appView = view;
|
||||||
@ -82,17 +76,12 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||||
return helper.shouldOverrideUrlLoading(view, url);
|
return helper.shouldOverrideUrlLoading(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On received http auth request.
|
* On received http auth request.
|
||||||
* The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination
|
* The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param handler
|
|
||||||
* @param host
|
|
||||||
* @param realm
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
|
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
|
||||||
@ -126,7 +115,7 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
this.appView.onPageReset();
|
this.appView.onPageReset();
|
||||||
|
|
||||||
// Broadcast message that page has loaded
|
// Broadcast message that page has loaded
|
||||||
this.appView.postMessage("onPageStarted", url);
|
this.appView.getPluginManager().postMessage("onPageStarted", url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,10 +148,10 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear timeout flag
|
// Clear timeout flag
|
||||||
this.appView.incUrlTimeout();
|
appView.loadUrlTimeout++;
|
||||||
|
|
||||||
// Broadcast message that page has loaded
|
// Broadcast message that page has loaded
|
||||||
this.appView.postMessage("onPageFinished", url);
|
this.appView.getPluginManager().postMessage("onPageFinished", url);
|
||||||
|
|
||||||
// Make app visible after 2 sec in case there was a JS error and Cordova JS never initialized correctly
|
// Make app visible after 2 sec in case there was a JS error and Cordova JS never initialized correctly
|
||||||
if (this.appView.getVisibility() == View.INVISIBLE) {
|
if (this.appView.getVisibility() == View.INVISIBLE) {
|
||||||
@ -172,7 +161,7 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
cordova.getActivity().runOnUiThread(new Runnable() {
|
cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
appView.postMessage("spinner", "stop");
|
appView.getPluginManager().postMessage("spinner", "stop");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -184,7 +173,7 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
|
|
||||||
// Shutdown if blank loaded
|
// Shutdown if blank loaded
|
||||||
if (url.equals("about:blank")) {
|
if (url.equals("about:blank")) {
|
||||||
appView.postMessage("exit", null);
|
appView.getPluginManager().postMessage("exit", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +195,7 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
LOG.d(TAG, "CordovaWebViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl);
|
LOG.d(TAG, "CordovaWebViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl);
|
||||||
|
|
||||||
// Clear timeout flag
|
// Clear timeout flag
|
||||||
this.appView.incUrlTimeout();
|
appView.loadUrlTimeout++;
|
||||||
|
|
||||||
// Handle error
|
// Handle error
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
@ -217,7 +206,7 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.appView.postMessage("onReceivedError", data);
|
this.appView.getPluginManager().postMessage("onReceivedError", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -326,10 +315,4 @@ public class AndroidWebViewClient extends WebViewClient implements CordovaWebVie
|
|||||||
public void clearAuthenticationTokens() {
|
public void clearAuthenticationTokens() {
|
||||||
this.authenticationTokens.clear();
|
this.authenticationTokens.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceivedError(int errorCode, String description, String url) {
|
|
||||||
this.onReceivedError(appView, errorCode, description, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.webkit.ValueCallback;
|
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
@ -162,11 +161,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
appView = makeWebView();
|
appView = makeWebView();
|
||||||
appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist, preferences);
|
|
||||||
|
|
||||||
// TODO: Have the views set this themselves.
|
// TODO: Have the views set this themselves.
|
||||||
if (preferences.getBoolean("DisallowOverscroll", false)) {
|
if (preferences.getBoolean("DisallowOverscroll", false)) {
|
||||||
appView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
appView.getView().setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||||
}
|
}
|
||||||
createViews();
|
createViews();
|
||||||
|
|
||||||
@ -190,7 +188,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
protected void createViews() {
|
protected void createViews() {
|
||||||
// This builds the view. We could probably get away with NOT having a LinearLayout, but I like having a bucket!
|
|
||||||
// This builds the view. We could probably get away with NOT having a LinearLayout, but I like having a bucket!
|
// This builds the view. We could probably get away with NOT having a LinearLayout, but I like having a bucket!
|
||||||
Display display = getWindowManager().getDefaultDisplay();
|
Display display = getWindowManager().getDefaultDisplay();
|
||||||
int width = display.getWidth();
|
int width = display.getWidth();
|
||||||
@ -201,15 +198,15 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
|
ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
|
||||||
|
|
||||||
appView.setId(100);
|
appView.getView().setId(100);
|
||||||
appView.setLayoutParams(new LinearLayout.LayoutParams(
|
appView.getView().setLayoutParams(new LinearLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
1.0F));
|
1.0F));
|
||||||
|
|
||||||
// Add web view but make it invisible while loading URL
|
// Add web view but make it invisible while loading URL
|
||||||
appView.setVisibility(View.INVISIBLE);
|
appView.getView().setVisibility(View.INVISIBLE);
|
||||||
root.addView((View) appView);
|
root.addView(appView.getView());
|
||||||
setContentView(root);
|
setContentView(root);
|
||||||
|
|
||||||
// TODO: Setting this on the appView causes it to show when <html style="opacity:0">.
|
// TODO: Setting this on the appView causes it to show when <html style="opacity:0">.
|
||||||
@ -231,63 +228,34 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
* require a more specialized web view.
|
* require a more specialized web view.
|
||||||
*/
|
*/
|
||||||
protected CordovaWebView makeWebView() {
|
protected CordovaWebView makeWebView() {
|
||||||
String r = preferences.getString("webView", "org.apache.cordova.AndroidWebView");
|
String r = preferences.getString("webView", null);
|
||||||
|
CordovaWebView ret = null;
|
||||||
try {
|
if (r != null) {
|
||||||
Class<?> webViewClass = Class.forName(r);
|
try {
|
||||||
Constructor<?>[] webViewConstructors = webViewClass.getConstructors();
|
Class<?> webViewClass = Class.forName(r);
|
||||||
|
Constructor<?> constructor = webViewClass.getConstructor(Context.class);
|
||||||
if(CordovaWebView.class.isAssignableFrom(webViewClass)) {
|
ret = (CordovaWebView) constructor.newInstance((Context)this);
|
||||||
for (Constructor<?> constructor : webViewConstructors) {
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
e.printStackTrace();
|
||||||
CordovaWebView webView = (CordovaWebView) constructor.newInstance((Context)this);
|
} catch (InstantiationException e) {
|
||||||
return webView;
|
e.printStackTrace();
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalAccessException e) {
|
||||||
LOG.d(TAG, "Illegal arguments; trying next constructor.");
|
e.printStackTrace();
|
||||||
}
|
} catch (IllegalArgumentException e) {
|
||||||
}
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
LOG.e(TAG, "The WebView Engine is NOT a proper WebView, defaulting to system WebView");
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
LOG.e(TAG, "The WebView Engine was not found, defaulting to system WebView");
|
|
||||||
} catch (InstantiationException e) {
|
|
||||||
LOG.e(TAG, "Unable to instantiate the WebView, defaulting to system WebView");
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
LOG.e(TAG, "Illegal Access to Constructor. This should never happen, defaulting to system WebView");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
LOG.e(TAG, "The WebView does not implement the default constructor, defaulting to system WebView");
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
LOG.e(TAG, "Invocation Target Exception! Reflection is hard, defaulting to system WebView");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all else fails, return a default WebView
|
if (ret == null) {
|
||||||
return (CordovaWebView) new AndroidWebView(this);
|
// If all else fails, return a default WebView
|
||||||
}
|
ret = new AndroidWebView(this);
|
||||||
|
}
|
||||||
/**
|
ret.init(this, pluginEntries, whitelist, preferences);
|
||||||
* Construct the client for the default web view object.
|
return ret;
|
||||||
*
|
|
||||||
* This is intended to be overridable by subclasses of CordovaActivity which
|
|
||||||
* require a more specialized web view. By default, it allows the webView
|
|
||||||
* to create its own client objects.
|
|
||||||
*
|
|
||||||
* @param webView the default constructed web view object
|
|
||||||
*/
|
|
||||||
protected CordovaWebViewClient makeWebViewClient(CordovaWebView webView) {
|
|
||||||
return webView.makeWebViewClient(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct the chrome client for the default web view object.
|
|
||||||
*
|
|
||||||
* This is intended to be overridable by subclasses of CordovaActivity which
|
|
||||||
* require a more specialized web view. By default, it allows the webView
|
|
||||||
* to create its own client objects.
|
|
||||||
*
|
|
||||||
* @param webView the default constructed web view object
|
|
||||||
*/
|
|
||||||
protected CordovaChromeClient makeChromeClient(CordovaWebView webView) {
|
|
||||||
return webView.makeWebChromeClient(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,21 +277,17 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
this.keepRunning = preferences.getBoolean("KeepRunning", true);
|
this.keepRunning = preferences.getBoolean("KeepRunning", true);
|
||||||
|
|
||||||
//Check if the view is attached to anything
|
//Check if the view is attached to anything
|
||||||
if(appView.getParent() != null)
|
if(appView.getView().getParent() != null)
|
||||||
{
|
{
|
||||||
// Then load the spinner
|
// Then load the spinner
|
||||||
this.loadSpinner();
|
this.loadSpinner();
|
||||||
}
|
}
|
||||||
//Load the correct splashscreen
|
//Load the correct splashscreen
|
||||||
|
|
||||||
if(this.splashscreen != 0)
|
if(this.splashscreen != 0)
|
||||||
{
|
{
|
||||||
this.appView.loadUrl(url, this.splashscreenTime);
|
appView.getPluginManager().postMessage("splashscreen", "show");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.appView.loadUrl(url);
|
|
||||||
}
|
}
|
||||||
|
this.appView.loadUrlIntoView(url, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -458,15 +422,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a message to all plugins.
|
|
||||||
*/
|
|
||||||
public void postMessage(String id, Object data) {
|
|
||||||
if (this.appView != null) {
|
|
||||||
this.appView.postMessage(id, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the spinner. Must be called from the UI thread.
|
* Show the spinner. Must be called from the UI thread.
|
||||||
*
|
*
|
||||||
@ -542,21 +497,15 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
super.onActivityResult(requestCode, resultCode, intent);
|
super.onActivityResult(requestCode, resultCode, intent);
|
||||||
Log.d(TAG, "Request code = " + requestCode);
|
Log.d(TAG, "Request code = " + requestCode);
|
||||||
if (appView != null && requestCode == AndroidChromeClient.FILECHOOSER_RESULTCODE) {
|
if (appView != null && requestCode == AndroidChromeClient.FILECHOOSER_RESULTCODE) {
|
||||||
ValueCallback<Uri> mUploadMessage = ((CordovaChromeClient) this.appView.getWebChromeClient()).getValueCallback();
|
|
||||||
Log.d(TAG, "did we get here?");
|
|
||||||
if (null == mUploadMessage)
|
|
||||||
return;
|
|
||||||
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
|
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
|
||||||
Log.d(TAG, "result = " + result);
|
appView.onFilePickerResult(result);
|
||||||
mUploadMessage.onReceiveValue(result);
|
|
||||||
mUploadMessage = null;
|
|
||||||
}
|
}
|
||||||
CordovaPlugin callback = this.activityResultCallback;
|
CordovaPlugin callback = this.activityResultCallback;
|
||||||
if(callback == null && initCallbackClass != null) {
|
if(callback == null && initCallbackClass != null) {
|
||||||
// The application was restarted, but had defined an initial callback
|
// The application was restarted, but had defined an initial callback
|
||||||
// before being shut down.
|
// before being shut down.
|
||||||
//this.activityResultCallback = appView.pluginManager.getPlugin(initCallbackClass);
|
//this.activityResultCallback = appView.pluginManager.getPlugin(initCallbackClass);
|
||||||
this.activityResultCallback = appView.getPlugin(initCallbackClass);
|
this.activityResultCallback = appView.getPluginManager().getPlugin(initCallbackClass);
|
||||||
callback = this.activityResultCallback;
|
callback = this.activityResultCallback;
|
||||||
}
|
}
|
||||||
if(callback != null) {
|
if(callback != null) {
|
||||||
@ -598,7 +547,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
me.runOnUiThread(new Runnable() {
|
me.runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (exit) {
|
if (exit) {
|
||||||
me.appView.setVisibility(View.GONE);
|
me.appView.getView().setVisibility(View.GONE);
|
||||||
me.displayError("Application Error", description + " (" + failingUrl + ")", "OK", exit);
|
me.displayError("Application Error", description + " (" + failingUrl + ")", "OK", exit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,32 +585,24 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if URL is in approved list of URLs to load.
|
|
||||||
*/
|
|
||||||
@Deprecated // Use whitelist object directly.
|
|
||||||
public boolean isUrlWhiteListed(String url) {
|
|
||||||
return whitelist.isUrlWhiteListed(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hook in Cordova for menu plugins
|
* Hook in Cordova for menu plugins
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
this.postMessage("onCreateOptionsMenu", menu);
|
appView.getPluginManager().postMessage("onCreateOptionsMenu", menu);
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
this.postMessage("onPrepareOptionsMenu", menu);
|
appView.getPluginManager().postMessage("onPrepareOptionsMenu", menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
this.postMessage("onOptionsItemSelected", item);
|
appView.getPluginManager().postMessage("onOptionsItemSelected", item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,7 +694,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
else if ("spinner".equals(id)) {
|
else if ("spinner".equals(id)) {
|
||||||
if ("stop".equals(data.toString())) {
|
if ("stop".equals(data.toString())) {
|
||||||
this.spinnerStop();
|
this.spinnerStop();
|
||||||
this.appView.setVisibility(View.VISIBLE);
|
this.appView.getView().setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ("onReceivedError".equals(id)) {
|
else if ("onReceivedError".equals(id)) {
|
||||||
|
167
framework/src/org/apache/cordova/CordovaBridge.java
Normal file
167
framework/src/org/apache/cordova/CordovaBridge.java
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import org.apache.cordova.PluginManager;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains APIs that the JS can call. All functions in here should also have
|
||||||
|
* an equivalent entry in CordovaChromeClient.java, and be added to
|
||||||
|
* cordova-js/lib/android/plugin/android/promptbasednativeapi.js
|
||||||
|
*/
|
||||||
|
public class CordovaBridge {
|
||||||
|
private static final String LOG_TAG = "CordovaBridge";
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
private NativeToJsMessageQueue jsMessageQueue;
|
||||||
|
private volatile int bridgeSecret = -1; // written by UI thread, read by JS thread.
|
||||||
|
private String loadedUrl;
|
||||||
|
|
||||||
|
public CordovaBridge(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue) {
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
this.jsMessageQueue = jsMessageQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsExec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
|
||||||
|
verifySecret(bridgeSecret);
|
||||||
|
// If the arguments weren't received, send a message back to JS. It will switch bridge modes and try again. See CB-2666.
|
||||||
|
// We send a message meant specifically for this case. It starts with "@" so no other message can be encoded into the same string.
|
||||||
|
if (arguments == null) {
|
||||||
|
return "@Null arguments.";
|
||||||
|
}
|
||||||
|
|
||||||
|
jsMessageQueue.setPaused(true);
|
||||||
|
try {
|
||||||
|
// Tell the resourceApi what thread the JS is running on.
|
||||||
|
CordovaResourceApi.jsThread = Thread.currentThread();
|
||||||
|
|
||||||
|
pluginManager.exec(service, action, callbackId, arguments);
|
||||||
|
String ret = "";
|
||||||
|
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
|
||||||
|
ret = jsMessageQueue.popAndEncode(false);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
} finally {
|
||||||
|
jsMessageQueue.setPaused(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsSetNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
|
||||||
|
verifySecret(bridgeSecret);
|
||||||
|
jsMessageQueue.setBridgeMode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsRetrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
|
||||||
|
verifySecret(bridgeSecret);
|
||||||
|
return jsMessageQueue.popAndEncode(fromOnlineEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifySecret(int value) throws IllegalAccessException {
|
||||||
|
if (bridgeSecret < 0 || value != bridgeSecret) {
|
||||||
|
throw new IllegalAccessException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called on page transitions */
|
||||||
|
void clearBridgeSecret() {
|
||||||
|
bridgeSecret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by cordova.js to initialize the bridge. */
|
||||||
|
int generateBridgeSecret() {
|
||||||
|
bridgeSecret = (int)(Math.random() * Integer.MAX_VALUE);
|
||||||
|
return bridgeSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(String loadedUrl) {
|
||||||
|
jsMessageQueue.reset();
|
||||||
|
clearBridgeSecret();
|
||||||
|
this.loadedUrl = loadedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String promptOnJsPrompt(String origin, String message, String defaultValue) {
|
||||||
|
if (defaultValue != null && defaultValue.length() > 3 && defaultValue.startsWith("gap:")) {
|
||||||
|
JSONArray array;
|
||||||
|
try {
|
||||||
|
array = new JSONArray(defaultValue.substring(4));
|
||||||
|
int bridgeSecret = array.getInt(0);
|
||||||
|
String service = array.getString(1);
|
||||||
|
String action = array.getString(2);
|
||||||
|
String callbackId = array.getString(3);
|
||||||
|
String r = jsExec(bridgeSecret, service, action, callbackId, message);
|
||||||
|
return r == null ? "" : r;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Sets the native->JS bridge mode.
|
||||||
|
else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) {
|
||||||
|
try {
|
||||||
|
int bridgeSecret = Integer.parseInt(defaultValue.substring(16));
|
||||||
|
jsSetNativeToJsBridgeMode(bridgeSecret, Integer.parseInt(message));
|
||||||
|
} catch (NumberFormatException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Polling for JavaScript messages
|
||||||
|
else if (defaultValue != null && defaultValue.startsWith("gap_poll:")) {
|
||||||
|
int bridgeSecret = Integer.parseInt(defaultValue.substring(9));
|
||||||
|
try {
|
||||||
|
String r = jsRetrieveJsMessages(bridgeSecret, "1".equals(message));
|
||||||
|
return r == null ? "" : r;
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
|
||||||
|
// Protect against random iframes being able to talk through the bridge.
|
||||||
|
// Trust only file URLs and the start URL's domain.
|
||||||
|
// The extra origin.startsWith("http") is to protect against iframes with data: having "" as origin.
|
||||||
|
if (origin.startsWith("file:") || (origin.startsWith("http") && loadedUrl.startsWith(origin))) {
|
||||||
|
// Enable the bridge
|
||||||
|
int bridgeMode = Integer.parseInt(defaultValue.substring(9));
|
||||||
|
jsMessageQueue.setBridgeMode(bridgeMode);
|
||||||
|
// Tell JS the bridge secret.
|
||||||
|
int secret = generateBridgeSecret();
|
||||||
|
return ""+secret;
|
||||||
|
} else {
|
||||||
|
Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeToJsMessageQueue getMessageQueue() {
|
||||||
|
return jsMessageQueue;
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.webkit.ValueCallback;
|
|
||||||
|
|
||||||
public interface CordovaChromeClient {
|
|
||||||
ValueCallback<Uri> getValueCallback();
|
|
||||||
}
|
|
@ -21,16 +21,15 @@ package org.apache.cordova;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.webkit.WebView;
|
|
||||||
|
|
||||||
class CordovaUriHelper {
|
public class CordovaUriHelper {
|
||||||
|
|
||||||
private static final String TAG = "CordovaUriHelper";
|
private static final String TAG = "CordovaUriHelper";
|
||||||
|
|
||||||
private CordovaWebView appView;
|
private CordovaWebView appView;
|
||||||
private CordovaInterface cordova;
|
private CordovaInterface cordova;
|
||||||
|
|
||||||
CordovaUriHelper(CordovaInterface cdv, CordovaWebView webView)
|
public CordovaUriHelper(CordovaInterface cdv, CordovaWebView webView)
|
||||||
{
|
{
|
||||||
appView = webView;
|
appView = webView;
|
||||||
cordova = cdv;
|
cordova = cdv;
|
||||||
@ -44,7 +43,7 @@ class CordovaUriHelper {
|
|||||||
* @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
|
||||||
*/
|
*/
|
||||||
boolean shouldOverrideUrlLoading(WebView view, String url) {
|
public boolean shouldOverrideUrlLoading(String url) {
|
||||||
// The WebView should support http and https when going on the Internet
|
// The WebView should support http and https when going on the Internet
|
||||||
if(url.startsWith("http:") || url.startsWith("https:"))
|
if(url.startsWith("http:") || url.startsWith("https:"))
|
||||||
{
|
{
|
||||||
@ -55,7 +54,7 @@ class CordovaUriHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Give plugins the chance to handle the url
|
// Give plugins the chance to handle the url
|
||||||
else if (this.appView.onOverrideUrlLoading(url)) {
|
else if (this.appView.getPluginManager().onOverrideUrlLoading(url)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(url.startsWith("file://") | url.startsWith("data:"))
|
else if(url.startsWith("file://") | url.startsWith("data:"))
|
||||||
|
@ -5,45 +5,19 @@ import java.util.List;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebChromeClient.CustomViewCallback;
|
import android.webkit.WebChromeClient.CustomViewCallback;
|
||||||
import android.widget.LinearLayout.LayoutParams;
|
|
||||||
|
|
||||||
public interface CordovaWebView {
|
public interface CordovaWebView {
|
||||||
public static final String CORDOVA_VERSION = "4.0.0-dev";
|
public static final String CORDOVA_VERSION = "4.0.0-dev";
|
||||||
|
|
||||||
void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
|
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries,
|
||||||
List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences);
|
Whitelist whitelist, CordovaPreferences preferences);
|
||||||
|
|
||||||
View getView();
|
View getView();
|
||||||
|
|
||||||
CordovaWebViewClient makeWebViewClient(CordovaInterface cordova);
|
void loadUrlIntoView(String url, boolean recreatePlugins);
|
||||||
|
|
||||||
CordovaChromeClient makeWebChromeClient(CordovaInterface cordova);
|
|
||||||
|
|
||||||
void setWebViewClient(CordovaWebViewClient webViewClient);
|
|
||||||
|
|
||||||
void setWebChromeClient(CordovaChromeClient webChromeClient);
|
|
||||||
|
|
||||||
void setId(int i);
|
|
||||||
|
|
||||||
void setLayoutParams(LayoutParams layoutParams);
|
|
||||||
|
|
||||||
void setVisibility(int invisible);
|
|
||||||
|
|
||||||
Object getParent();
|
|
||||||
|
|
||||||
void loadUrl(String url);
|
|
||||||
|
|
||||||
void loadUrl(String url, int splashscreenTime);
|
|
||||||
|
|
||||||
void loadUrlNow(String url);
|
|
||||||
|
|
||||||
void loadUrlIntoView(final String url);
|
|
||||||
|
|
||||||
void loadUrlIntoView(final String url, boolean recreatePlugins);
|
|
||||||
|
|
||||||
void loadUrlIntoView(final String url, final int splashscreenTime);
|
|
||||||
|
|
||||||
void stopLoading();
|
void stopLoading();
|
||||||
|
|
||||||
@ -63,10 +37,6 @@ public interface CordovaWebView {
|
|||||||
|
|
||||||
void handleDestroy();
|
void handleDestroy();
|
||||||
|
|
||||||
void postMessage(String id, Object data);
|
|
||||||
|
|
||||||
void addJavascript(String statement);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send JavaScript statement back to JavaScript.
|
* Send JavaScript statement back to JavaScript.
|
||||||
* (This is a convenience method)
|
* (This is a convenience method)
|
||||||
@ -93,32 +63,14 @@ public interface CordovaWebView {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
void sendJavascript(String statememt);
|
void sendJavascript(String statememt);
|
||||||
|
|
||||||
CordovaChromeClient getWebChromeClient();
|
|
||||||
|
|
||||||
CordovaPlugin getPlugin(String initCallbackClass);
|
|
||||||
|
|
||||||
void showWebPage(String errorUrl, boolean b, boolean c, HashMap<String, Object> params);
|
void showWebPage(String errorUrl, boolean b, boolean c, HashMap<String, Object> params);
|
||||||
|
|
||||||
Object getFocusedChild();
|
|
||||||
|
|
||||||
boolean isCustomViewShowing();
|
boolean isCustomViewShowing();
|
||||||
|
|
||||||
void showCustomView(View view, CustomViewCallback callback);
|
void showCustomView(View view, CustomViewCallback callback);
|
||||||
|
|
||||||
void hideCustomView();
|
void hideCustomView();
|
||||||
|
|
||||||
Context getContext();
|
|
||||||
|
|
||||||
boolean onOverrideUrlLoading(String url);
|
|
||||||
|
|
||||||
int getVisibility();
|
|
||||||
|
|
||||||
void incUrlTimeout();
|
|
||||||
|
|
||||||
void setOverScrollMode(int overScrollNever);
|
|
||||||
|
|
||||||
void setNetworkAvailable(boolean online);
|
|
||||||
|
|
||||||
CordovaResourceApi getResourceApi();
|
CordovaResourceApi getResourceApi();
|
||||||
|
|
||||||
void setButtonPlumbedToJs(int keyCode, boolean override);
|
void setButtonPlumbedToJs(int keyCode, boolean override);
|
||||||
@ -128,12 +80,15 @@ public interface CordovaWebView {
|
|||||||
|
|
||||||
PluginManager getPluginManager();
|
PluginManager getPluginManager();
|
||||||
|
|
||||||
void setLayoutParams(android.widget.FrameLayout.LayoutParams layoutParams);
|
|
||||||
|
|
||||||
// Required for test
|
|
||||||
String getUrl();
|
|
||||||
boolean isPaused();
|
|
||||||
|
|
||||||
Whitelist getWhitelist();
|
Whitelist getWhitelist();
|
||||||
CordovaPreferences getPreferences();
|
CordovaPreferences getPreferences();
|
||||||
|
|
||||||
|
void onFilePickerResult(Uri uri);
|
||||||
|
|
||||||
|
void setNetworkAvailable(boolean online);
|
||||||
|
|
||||||
|
// TODO: Work on deleting these by removing refs from plugins.
|
||||||
|
Context getContext();
|
||||||
|
void loadUrl(String url);
|
||||||
|
Object postMessage(String id, Object data);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
public interface CordovaWebViewClient {
|
|
||||||
void onReceivedError(int errorCode, String description, String url);
|
|
||||||
}
|
|
@ -75,7 +75,7 @@ public class CoreAndroid extends CordovaPlugin {
|
|||||||
// indicative of what this actually does (shows the webview).
|
// indicative of what this actually does (shows the webview).
|
||||||
cordova.getActivity().runOnUiThread(new Runnable() {
|
cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
webView.postMessage("spinner", "stop");
|
webView.getPluginManager().postMessage("spinner", "stop");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ public class CoreAndroid extends CordovaPlugin {
|
|||||||
* Exit the Android application.
|
* Exit the Android application.
|
||||||
*/
|
*/
|
||||||
public void exitApp() {
|
public void exitApp() {
|
||||||
this.webView.postMessage("exit", null);
|
this.webView.getPluginManager().postMessage("exit", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -271,15 +271,15 @@ public class CoreAndroid extends CordovaPlugin {
|
|||||||
String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
|
String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
|
||||||
if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
|
if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
|
||||||
LOG.i(TAG, "Telephone RINGING");
|
LOG.i(TAG, "Telephone RINGING");
|
||||||
webView.postMessage("telephone", "ringing");
|
webView.getPluginManager().postMessage("telephone", "ringing");
|
||||||
}
|
}
|
||||||
else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
|
else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
|
||||||
LOG.i(TAG, "Telephone OFFHOOK");
|
LOG.i(TAG, "Telephone OFFHOOK");
|
||||||
webView.postMessage("telephone", "offhook");
|
webView.getPluginManager().postMessage("telephone", "offhook");
|
||||||
}
|
}
|
||||||
else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
|
else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
|
||||||
LOG.i(TAG, "Telephone IDLE");
|
LOG.i(TAG, "Telephone IDLE");
|
||||||
webView.postMessage("telephone", "idle");
|
webView.getPluginManager().postMessage("telephone", "idle");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import android.webkit.WebResourceResponse;
|
|||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||||
public class IceCreamCordovaWebViewClient extends AndroidWebViewClient implements CordovaWebViewClient{
|
public class IceCreamCordovaWebViewClient extends AndroidWebViewClient {
|
||||||
|
|
||||||
private static final String TAG = "IceCreamCordovaWebViewClient";
|
private static final String TAG = "IceCreamCordovaWebViewClient";
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ public class NativeToJsMessageQueue {
|
|||||||
public void run() {
|
public void run() {
|
||||||
String js = popAndEncodeAsJs();
|
String js = popAndEncodeAsJs();
|
||||||
if (js != null) {
|
if (js != null) {
|
||||||
webView.loadUrlNow("javascript:" + js);
|
webView.loadUrlIntoView("javascript:" + js, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -53,17 +53,9 @@ public class PluginManager {
|
|||||||
|
|
||||||
private Set<String> pluginIdWhitelist;
|
private Set<String> pluginIdWhitelist;
|
||||||
|
|
||||||
PluginManager(CordovaWebView cordovaWebView, CordovaInterface cordova, List<PluginEntry> pluginEntries) {
|
public PluginManager(CordovaWebView cordovaWebView, CordovaInterface cordova, List<PluginEntry> pluginEntries) {
|
||||||
this.ctx = cordova;
|
this.ctx = cordova;
|
||||||
this.app = cordovaWebView;
|
this.app = cordovaWebView;
|
||||||
setPluginEntries(pluginEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPluginEntries(List<PluginEntry> pluginEntries) {
|
|
||||||
this.onPause(false);
|
|
||||||
this.onDestroy();
|
|
||||||
this.clearPluginObjects();
|
|
||||||
entries.clear();
|
|
||||||
for (PluginEntry entry : pluginEntries) {
|
for (PluginEntry entry : pluginEntries) {
|
||||||
addService(entry);
|
addService(entry);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user