Compare commits

...

17 Commits

Author SHA1 Message Date
Ian Clelland
857d841adb Fix plumbing of key events to instance webview 2014-05-20 15:16:10 -04:00
Ian Clelland
c66135d4de Make jsMessageQueue visible to out-of-package subclasses 2014-05-20 13:50:58 -04:00
Ian Clelland
4a3ed323db Promote CordovaWebView to an abstract base class.
This resolves the problem where pluginManager was not available as a
field on a generic CordovaWebView, which broke backwards-compatibility
with existing plugins (including core Cordova plugins).

This also necessitates splitting AndroidWebView into two classes, so
that it now *has* a WebView, rather than *is* a WebView, due to Java's
lack of multiple inheritance. All WebView-defined methods are now
implemented on the AndroidWebViewImpl class, and are delegated from the
AndroidWebView class as necessary.
2014-05-16 16:40:54 -04:00
Ian Clelland
97008305ff Merge branch 'master' into pluggable_webview
Conflicts:
	framework/src/org/apache/cordova/CordovaWebView.java
2014-05-15 15:59:11 -04:00
Ian Clelland
1a17083e8c Add more required methods on CordovaWebView interface 2014-05-15 15:56:10 -04:00
Joe Bowser
b6664cc859 Added two more required methods to CordovaWebView to get the Junit tests running, removed tests that make no sense 2014-05-14 11:09:21 -07:00
Steven Gill
50c4aef873 Update JS snapshot to version 3.6.0-dev (via coho) 2014-05-08 15:32:28 -07:00
Joe Bowser
cf42d31214 Update JS snapshot to version 3.6.0-dev (via coho) 2014-05-06 15:51:17 -07:00
Joe Bowser
00caa1c0a0 Set VERSION to 3.6.0-dev (via coho) 2014-05-06 15:51:14 -07:00
Joe Bowser
93c8ba920a Added dash to test push 2014-05-06 13:59:13 -07:00
Andrew Grieve
8702c04d39 Revert accidentally removed lines from NOTICE 2014-05-06 15:18:31 -04:00
Ian Clelland
e595c313a1 Use correct client object in recent versions of android again 2014-05-02 10:29:53 -04:00
Ian Clelland
955da2e360 Clean up merge commit
Reinstate fix for github issue #96 (b715d20)
Re-remove extra calls to set up client objects (8e31ef7b)
Reinstate license header in CordovaChromeClient.java
2014-05-02 10:22:38 -04:00
Steven Gill
c349892c5b CB-6552: updated author to apache software foundation in pacakge.json 2014-04-30 12:55:28 -07:00
Steven Gill
3d4b8ce99b CB-6552: updated test field 2014-04-30 11:59:29 -07:00
Steven Gill
64fd87134f CB-6552: added top level package.json 2014-04-30 10:54:58 -07:00
Marcel Kinard
82bba44538 CB-6491 add CONTRIBUTING.md 2014-04-30 08:44:21 -04:00
22 changed files with 1174 additions and 980 deletions

16
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,16 @@
# Contributing to Apache Cordova
Anyone can contribute to Cordova. And we need your contributions.
There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
For instructions on this, start with the
[contribution overview](http://cordova.apache.org/#contribute).
The details are explained there, but the important items are:
- Sign and submit an Apache ICLA (Contributor License Agreement).
- Have a Jira issue open that corresponds to your contribution.
- Run the tests so your patch doesn't break existing functionality.
We look forward to your contributions!

16
NOTICE
View File

@@ -1,5 +1,17 @@
Apache Cordova
Copyright 2012 The Apache Software Foundation
Copyright 2014 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
The Apache Software Foundation (http://www.apache.org)
=========================================================================
== NOTICE file corresponding to the section 4 d of ==
== the Apache License, Version 2.0, ==
== in this case for the Android-specific code. ==
=========================================================================
This product includes software developed as part of
The Android Open Source Project (http://source.android.com).
This software includes software developed at Square, Inc.
Copyright (C) 2013 Square, Inc.

View File

@@ -84,7 +84,7 @@ Running Tests
Please see details under test/README.md.
Further Reading
---
----
- [http://developer.android.com](http://developer.android.com)
- [http://cordova.apache.org/](http://cordova.apache.org)

View File

@@ -1 +1 @@
3.5.0-dev
3.6.0-dev

View File

@@ -20,6 +20,6 @@
*/
// Coho updates this line:
var VERSION = "3.5.0-dev";
var VERSION = "3.6.0-dev";
console.log(VERSION);

View File

@@ -1,5 +1,5 @@
// Platform: android
// 3.5.0-dev-81f9a00
// 3.6.0-dev-7e845f3
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,7 +19,7 @@
under the License.
*/
;(function() {
var CORDOVA_JS_BUILD_LABEL = '3.5.0-dev-81f9a00';
var CORDOVA_JS_BUILD_LABEL = '3.6.0-dev-7e845f3';
// file: src/scripts/require.js
/*jshint -W079 */
@@ -825,6 +825,7 @@ channel.createSticky('onNativeReady');
channel.createSticky('onCordovaReady');
// Event to indicate that all automatically loaded JS plugins are loaded and ready.
// FIXME remove this
channel.createSticky('onPluginsReady');
// Event to indicate that Cordova is ready
@@ -1245,6 +1246,111 @@ channel.join(function() {
}, platformInitChannelsArray);
});
// file: src/common/init_b.js
define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel');
var cordova = require('cordova');
var platform = require('cordova/platform');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady];
// setting exec
cordova.exec = require('cordova/exec');
function logUnfiredChannels(arr) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i].state != 2) {
console.log('Channel not fired: ' + arr[i].type);
}
}
}
window.setTimeout(function() {
if (channel.onDeviceReady.state != 2) {
console.log('deviceready has not fired after 5 seconds.');
logUnfiredChannels(platformInitChannelsArray);
logUnfiredChannels(channel.deviceReadyChannelsArray);
}
}, 5000);
// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
// We replace it so that properties that can't be clobbered can instead be overridden.
function replaceNavigator(origNavigator) {
var CordovaNavigator = function() {};
CordovaNavigator.prototype = origNavigator;
var newNavigator = new CordovaNavigator();
// This work-around really only applies to new APIs that are newer than Function.bind.
// Without it, APIs such as getGamepads() break.
if (CordovaNavigator.bind) {
for (var key in origNavigator) {
if (typeof origNavigator[key] == 'function') {
newNavigator[key] = origNavigator[key].bind(origNavigator);
}
}
}
return newNavigator;
}
if (window.navigator) {
window.navigator = replaceNavigator(window.navigator);
}
if (!window.console) {
window.console = {
log: function(){}
};
}
if (!window.console.warn) {
window.console.warn = function(msg) {
this.log("warn: " + msg);
};
}
// Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
// Listen for DOMContentLoaded and notify our channel subscribers.
if (document.readyState == 'complete' || document.readyState == 'interactive') {
channel.onDOMContentLoaded.fire();
} else {
document.addEventListener('DOMContentLoaded', function() {
channel.onDOMContentLoaded.fire();
}, false);
}
// _nativeReady is global variable that the native side can set
// to signify that the native code is ready. It is a global since
// it may be called before any cordova JS is ready.
if (window._nativeReady) {
channel.onNativeReady.fire();
}
// Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap();
/**
* Create all cordova objects once native side is ready.
*/
channel.join(function() {
platform.initialize && platform.initialize();
// Fire event to notify that all objects are created
channel.onCordovaReady.fire();
// Fire onDeviceReady event once page has fully loaded, all
// constructors have run and cordova info has been received from native
// side.
channel.join(function() {
require('cordova').fireDocumentEvent('deviceready');
}, channel.deviceReadyChannelsArray);
}, platformInitChannelsArray);
});
// file: src/common/modulemapper.js

View File

@@ -139,7 +139,6 @@ public class AndroidChromeClient extends WebChromeClient implements CordovaChrom
return true;
}
});
dlg.create();
dlg.show();
return true;
}
@@ -188,7 +187,6 @@ public class AndroidChromeClient extends WebChromeClient implements CordovaChrom
return true;
}
});
dlg.create();
dlg.show();
return true;
}
@@ -284,7 +282,6 @@ public class AndroidChromeClient extends WebChromeClient implements CordovaChrom
res.cancel();
}
});
dlg.create();
dlg.show();
}
return true;

View File

@@ -0,0 +1,837 @@
/*
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 java.util.HashMap;
import java.util.Locale;
import org.apache.cordova.Config;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.LOG;
import org.apache.cordova.PluginManager;
import org.apache.cordova.PluginResult;
import org.json.JSONException;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
/*
* This class is our web view.
*
* @see <a href="http://developer.android.com/guide/webapps/webview.html">WebView guide</a>
* @see <a href="http://developer.android.com/reference/android/webkit/WebView.html">WebView</a>
*/
public class AndroidCordovaWebView extends CordovaWebView {
public static final String TAG = "CordovaWebView";
public static final String CORDOVA_VERSION = "3.6.0-dev";
private boolean paused;
private BroadcastReceiver receiver;
private AndroidWebView webview;
/** Activities and other important classes **/
private CordovaInterface cordova;
private CordovaWebViewClient viewClient;
private CordovaChromeClient chromeClient;
private String url;
// Flag to track that a loadUrl timeout occurred
int loadUrlTimeout = 0;
private boolean bound;
private boolean handleButton = false;
ExposedJsApi exposedJsApi;
/** custom view created by the browser (a video player for example) */
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private ActivityResult mResult = null;
private CordovaResourceApi resourceApi;
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 =
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER);
/**
* Constructor.
*
* @param context
*/
public AndroidCordovaWebView(Context context) {
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
webview = new AndroidWebView(context);
webview.setCordovaWebView(this);
this.loadConfiguration();
this.setup();
}
/**
* Constructor.
*
* @param context
* @param attrs
*/
public AndroidCordovaWebView(Context context, AttributeSet attrs) {
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
webview = new AndroidWebView(context, attrs);
webview.setCordovaWebView(this);
this.loadConfiguration();
this.setup();
}
/**
* Constructor.
*
* @param context
* @param attrs
* @param defStyle
*
*/
public AndroidCordovaWebView(Context context, AttributeSet attrs, int defStyle) {
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
webview = new AndroidWebView(context, attrs, defStyle);
webview.setCordovaWebView(this);
this.loadConfiguration();
this.setup();
}
/**
* Constructor.
*
* @param context
* @param attrs
* @param defStyle
* @param privateBrowsing
*/
@TargetApi(11)
public AndroidCordovaWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
webview = new AndroidWebView(context, attrs, defStyle, privateBrowsing);
webview.setCordovaWebView(this);
this.loadConfiguration();
this.setup();
}
/**
* Create a default WebViewClient object for this webview. This can be overridden by the
* main application's CordovaActivity subclass.
*
* There are two possible client objects that can be returned:
* AndroidWebViewClient for android < 3.0
* IceCreamCordovaWebViewClient for Android >= 3.0 (Supports shouldInterceptRequest)
*/
@Override
public CordovaWebViewClient makeWebViewClient() {
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
{
return (CordovaWebViewClient) new AndroidWebViewClient(this.cordova, this);
}
else
{
return (CordovaWebViewClient) new IceCreamCordovaWebViewClient(this.cordova, this);
}
}
/**
* Create a default WebViewClient object for this webview. This can be overridden by the
* main application's CordovaActivity subclass.
*/
@Override
public CordovaChromeClient makeWebChromeClient() {
return (CordovaChromeClient) new AndroidChromeClient(this.cordova);
}
/**
* Initialize webview.
*/
private void setup() {
pluginManager = new PluginManager(this, this.cordova);
jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
exposedJsApi = new AndroidExposedJsApi(pluginManager, jsMessageQueue);
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
exposeJsInterface();
}
private void exposeJsInterface() {
int SDK_INT = Build.VERSION.SDK_INT;
if ((SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
Log.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
// Bug being that Java Strings do not get converted to JS strings automatically.
// This isn't hard to work-around on the JS side, but it's easier to just
// use the prompt bridge instead.
return;
}
webview.addJavascriptInterface(exposedJsApi, "_cordovaNative");
}
/**
* Set the WebViewClient.
*
* @param client
*/
@Override
public void setWebViewClient(CordovaWebViewClient client) {
this.viewClient = client;
webview.setWebViewClient((WebViewClient) client);
}
// @Override
public CordovaWebViewClient getWebViewClient() {
return this.viewClient;
}
/**
* Set the WebChromeClient.
*
* @param client
*/
@Override
public void setWebChromeClient(CordovaChromeClient client) {
this.chromeClient = client;
webview.setWebChromeClient((WebChromeClient) client);
}
@Override
public CordovaChromeClient getWebChromeClient() {
return this.chromeClient;
}
/**
* Load the url into the webview.
*
* @param url
*/
@Override
public void loadUrl(String url) {
if (url.equals("about:blank") || url.startsWith("javascript:")) {
this.loadUrlNow(url);
}
else {
String initUrl = getProperty("url", null);
// If first page of app, then set URL to load to be the one passed in
if (initUrl == null) {
this.loadUrlIntoView(url);
}
// Otherwise use the URL specified in the activity's extras bundle
else {
this.loadUrlIntoView(initUrl);
}
}
}
/**
* 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
*/
@Override
public void loadUrl(final String url, int time) {
String initUrl = getProperty("url", null);
// If first page of app, then set URL to load to be the one passed in
if (initUrl == null) {
this.loadUrlIntoView(url, time);
}
// Otherwise use the URL specified in the activity's extras bundle
else {
this.loadUrlIntoView(initUrl);
}
}
@Override
public void loadUrlIntoView(final String url) {
loadUrlIntoView(url, true);
}
/**
* Load the url into the webview.
*
* @param url
*/
@Override
public void loadUrlIntoView(final String url, boolean recreatePlugins) {
if (recreatePlugins) {
this.url = url;
this.pluginManager.init();
}
webview.loadUrlIntoView(url);
}
/**
* Load URL in webview.
*
* @param url
*/
@Override
public void loadUrlNow(String url) {
webview.loadUrlNow(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
*/
@Override
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
postMessage("splashscreen", "show");
}
// Load url
this.loadUrlIntoView(url);
}
@Override
public void stopLoading() {
//viewClient.isCurrentlyLoading = false;
webview.stopLoading();
}
/**
* Send JavaScript statement back to JavaScript.
* (This is a convenience method)
*
* @param statement
*/
@Override
public void sendJavascript(String statement) {
this.jsMessageQueue.addJavaScript(statement);
}
/**
* Send a plugin result back to JavaScript.
* (This is a convenience method)
*
* @param result
* @param callbackId
*/
@Override
public void sendPluginResult(PluginResult result, String callbackId) {
this.jsMessageQueue.addPluginResult(result, callbackId);
}
/**
* Send a message to all plugins.
*
* @param id The message id
* @param data The message data
*/
@Override
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)
*
* @return true if we went back, false if we are already at top
*/
@Override
public boolean backHistory() {
return webview.backHistory();
}
/**
* Load the specified URL in the Cordova webview or a new browser instance.
*
* NOTE: If openExternal is false, only URLs listed in whitelist can be loaded.
*
* @param url The url to load.
* @param openExternal Load url in browser instead of Cordova webview.
* @param clearHistory Clear the history stack, so new page becomes top of history
* @param params Parameters for new app
*/
@Override
public void showWebPage(String url, boolean openExternal, boolean clearHistory, HashMap<String, Object> params) {
LOG.d(TAG, "showWebPage(%s, %b, %b, HashMap", url, openExternal, clearHistory);
// If clearing history
if (clearHistory) {
this.clearHistory();
}
// If loading into our webview
if (!openExternal) {
// Make sure url is in whitelist
if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
// TODO: What about params?
// Load new URL
this.loadUrl(url);
return;
}
// Load in default viewer if not
LOG.w(TAG, "showWebPage: Cannot load URL into webview since it is not in white list. Loading into browser instead. (URL=" + url + ")");
}
try {
// Omitting the MIME type for file: URLs causes "No Activity found to handle Intent".
// Adding the MIME type to http: URLs causes them to not be handled by the downloader.
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse(url);
if ("file".equals(uri.getScheme())) {
intent.setDataAndType(uri, resourceApi.getMimeType(uri));
} else {
intent.setData(uri);
}
cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);
}
}
/**
* Check configuration parameters from Config.
* Approved list of URLs that can be loaded into Cordova
* <access origin="http://server regexp" subdomains="true" />
* Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
* <log level="DEBUG" />
*/
private void loadConfiguration() {
if ("true".equals(this.getProperty("Fullscreen", "false"))) {
this.cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
this.cordova.getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
/**
* 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
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return webview.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return webview.onKeyUp(keyCode, event);
}
@Override
public void bindButton(boolean override)
{
this.bound = override;
}
@Override
public void bindButton(String button, boolean override) {
if (button.compareTo("volumeup")==0) {
webview.bindButton(KeyEvent.KEYCODE_VOLUME_UP, true);
}
else if (button.compareTo("volumedown")==0) {
webview.bindButton(KeyEvent.KEYCODE_VOLUME_DOWN, true);
}
}
@Override
public boolean isBackButtonBound()
{
return this.bound;
}
@Override
public void handlePause(boolean keepRunning)
{
LOG.d(TAG, "Handle the pause");
// Send pause event to JavaScript
this.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onPause(keepRunning);
}
// If app doesn't want to run in background
if (!keepRunning) {
// Pause JavaScript timers (including setInterval)
webview.pauseTimers();
}
paused = true;
}
@Override
public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
{
this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onResume(keepRunning);
}
// Resume JavaScript timers (including setInterval)
webview.resumeTimers();
paused = false;
}
@Override
public void handleDestroy()
{
// Send destroy event to JavaScript
this.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
// Load blank page so that JavaScript onunload is called
this.loadUrl("about:blank");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onDestroy();
}
// unregister the receiver
if (this.receiver != null) {
try {
this.cordova.getActivity().unregisterReceiver(this.receiver);
} catch (Exception e) {
Log.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e);
}
}
}
@Override
public void onNewIntent(Intent intent)
{
//Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onNewIntent(intent);
}
}
@Override
public boolean isPaused()
{
return paused;
}
/* CB-1146 */
public boolean hadKeyEvent() {
return handleButton;
}
@Override
public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {
// This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0
Log.d(TAG, "showing Custom View");
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
// Store the view and its callback for later (to kill it properly)
mCustomView = view;
mCustomViewCallback = callback;
// Add the custom view to its container.
ViewGroup parent = (ViewGroup) this.getParent();
parent.addView(view, COVER_SCREEN_GRAVITY_CENTER);
// Hide the content view.
this.setVisibility(View.GONE);
// Finally show the custom view container.
parent.setVisibility(View.VISIBLE);
parent.bringToFront();
}
@Override
public void hideCustomView() {
// This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0
Log.d(TAG, "Hiding Custom View");
if (mCustomView == null) return;
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
ViewGroup parent = (ViewGroup) this.getParent();
parent.removeView(mCustomView);
mCustomView = null;
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
this.setVisibility(View.VISIBLE);
}
/**
* if the video overlay is showing then we need to know
* as it effects back button handling
*
* @return true if custom view is showing
*/
@Override
public boolean isCustomViewShowing() {
return mCustomView != null;
}
public void storeResult(int requestCode, int resultCode, Intent intent) {
mResult = new ActivityResult(requestCode, resultCode, intent);
}
/* git:5ca233779d11177ec2bef97afa2910d383d6d4a2 */
public CordovaResourceApi getResourceApi() {
return resourceApi;
}
@Override
public void setLayoutParams(
android.widget.LinearLayout.LayoutParams layoutParams) {
webview.setLayoutParams(layoutParams);
}
@SuppressLint("NewApi")
@Override
public void setOverScrollMode(int mode) {
webview.setOverScrollMode(mode);
}
@Override
public void addJavascript(String statement) {
this.jsMessageQueue.addJavaScript(statement);
}
@Override
public CordovaPlugin getPlugin(String initCallbackClass) {
return this.pluginManager.getPlugin(initCallbackClass);
}
@Override
public String exec(String service, String action, String callbackId,
String message) throws JSONException {
return this.exposedJsApi.exec(service, action, callbackId, message);
}
@Override
public void setNativeToJsBridgeMode(int parseInt) {
this.exposedJsApi.setNativeToJsBridgeMode(parseInt);
}
@Override
public String retrieveJsMessages(boolean equals) {
return this.exposedJsApi.retrieveJsMessages(equals);
}
@Override
public boolean onOverrideUrlLoading(String url) {
return this.pluginManager.onOverrideUrlLoading(url);
}
@Override
public void resetJsMessageQueue() {
this.jsMessageQueue.reset();
}
@Override
public void onReset() {
this.pluginManager.onReset();
}
@Override
public void incUrlTimeout() {
this.loadUrlTimeout++;
}
@Override
public PluginManager getPluginManager() {
return this.pluginManager;
}
@Override
public void setLayoutParams(
android.widget.FrameLayout.LayoutParams layoutParams) {
webview.setLayoutParams(layoutParams);
}
@Override
public View getView() {
return webview;
}
@Override
public void setId(int i) {
webview.setId(i);
}
@Override
public int getVisibility() {
return webview.getVisibility();
}
@Override
public void setVisibility(int invisible) {
webview.setVisibility(invisible);
}
@Override
public Object getParent() {
return webview.getParent();
}
@Override
public boolean canGoBack() {
return webview.canGoBack();
}
@Override
public void clearCache(boolean b) {
webview.clearCache(b);
}
@Override
public void clearHistory() {
webview.clearHistory();
}
@Override
public Object getFocusedChild() {
return webview.getFocusedChild();
}
@Override
public Context getContext() {
return webview.getContext();
}
@Override
public void setNetworkAvailable(boolean online) {
webview.setNetworkAvailable(online);
}
@Override
public String getUrl() {
return webview.getUrl();
}
}

689
framework/src/org/apache/cordova/AndroidWebView.java Executable file → Normal file
View File

@@ -1,36 +1,8 @@
/*
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 java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import org.apache.cordova.Config;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.LOG;
import org.apache.cordova.PluginManager;
import org.apache.cordova.PluginResult;
import org.json.JSONException;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@@ -41,96 +13,40 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebBackForwardList;
import android.webkit.WebHistoryItem;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
/*
* This class is our web view.
*
* @see <a href="http://developer.android.com/guide/webapps/webview.html">WebView guide</a>
* @see <a href="http://developer.android.com/reference/android/webkit/WebView.html">WebView</a>
*/
public class AndroidWebView extends WebView implements CordovaWebView {
public class AndroidWebView extends WebView {
public static final String TAG = "CordovaWebView";
public static final String CORDOVA_VERSION = "3.5.0-dev";
public static final String CORDOVA_VERSION = "3.6.0-dev";
private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
PluginManager pluginManager;
private boolean paused;
private BroadcastReceiver receiver;
private AndroidCordovaWebView cordovaWebView;
/** Activities and other important classes **/
private CordovaInterface cordova;
CordovaWebViewClient viewClient;
@SuppressWarnings("unused")
private CordovaChromeClient chromeClient;
private String url;
// Flag to track that a loadUrl timeout occurred
int loadUrlTimeout = 0;
private boolean bound;
private boolean handleButton = false;
private long lastMenuEventTime = 0;
NativeToJsMessageQueue jsMessageQueue;
ExposedJsApi exposedJsApi;
/** custom view created by the browser (a video player for example) */
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private ActivityResult mResult = null;
private CordovaResourceApi resourceApi;
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 =
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER);
/**
* Constructor.
*
@@ -138,16 +54,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
*/
public AndroidWebView(Context context) {
super(context);
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
this.loadConfiguration();
this.setup();
this.setup((CordovaInterface)context);
}
/**
@@ -158,17 +65,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
*/
public AndroidWebView(Context context, AttributeSet attrs) {
super(context, attrs);
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
this.setWebChromeClient(this.makeWebChromeClient());
this.loadConfiguration();
this.setup();
this.setup((CordovaInterface)context);
}
/**
@@ -181,17 +78,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
*/
public AndroidWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
this.setWebChromeClient(this.makeWebChromeClient());
this.loadConfiguration();
this.setup();
this.setup((CordovaInterface)context);
}
/**
@@ -202,57 +89,20 @@ public class AndroidWebView extends WebView implements CordovaWebView {
* @param defStyle
* @param privateBrowsing
*/
@TargetApi(11)
@SuppressWarnings("deprecation")
@TargetApi(11)
public AndroidWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
super(context, attrs, defStyle, privateBrowsing);
if (CordovaInterface.class.isInstance(context))
{
this.cordova = (CordovaInterface) context;
}
else
{
Log.d(TAG, "Your activity must implement CordovaInterface to work");
}
this.setWebChromeClient(this.makeWebChromeClient());
this.loadConfiguration();
this.setup();
}
/**
* Create a default WebViewClient object for this webview. This can be overridden by the
* main application's CordovaActivity subclass.
*
* By default, it creates an AndroidWebViewClient, but we provide special case handling for
* IceCreamSandwich.
*/
@Override
public CordovaWebViewClient makeWebViewClient() {
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB ||
android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
{
return (CordovaWebViewClient) new AndroidWebViewClient(this.cordova, this);
}
else
{
return (CordovaWebViewClient) new IceCreamCordovaWebViewClient(this.cordova, this);
}
}
/**
* Create a default WebViewClient object for this webview. This can be overridden by the
* main application's CordovaActivity subclass.
*/
@Override
public CordovaChromeClient makeWebChromeClient() {
return (CordovaChromeClient) new AndroidChromeClient(this.cordova);
this.setup((CordovaInterface)context);
}
/**
* Initialize webview.
*/
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void setup() {
@SuppressLint({ "NewApi", "SetJavaScriptEnabled" })
private void setup(CordovaInterface cordova) {
this.cordova = cordova;
this.setInitialScale(0);
this.setVerticalScrollBarEnabled(false);
if (shouldRequestFocusOnInit()) {
@@ -295,15 +145,15 @@ public class AndroidWebView extends WebView implements CordovaWebView {
Level16Apis.enableUniversalAccess(settings);
// Enable database
// We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
String databasePath = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
String databasePath = cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
settings.setDatabaseEnabled(true);
settings.setDatabasePath(databasePath);
//Determine whether we're in debug or release mode, and turn on Debugging!
try {
final String packageName = this.cordova.getActivity().getPackageName();
final PackageManager pm = this.cordova.getActivity().getPackageManager();
final String packageName = cordova.getActivity().getPackageName();
final PackageManager pm = cordova.getActivity().getPackageManager();
ApplicationInfo appInfo;
appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
@@ -332,13 +182,13 @@ public class AndroidWebView extends WebView implements CordovaWebView {
// Enable AppCache
// Fix for CB-2282
settings.setAppCacheMaxSize(5 * 1048576);
String pathToCache = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
String pathToCache = cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
settings.setAppCachePath(pathToCache);
settings.setAppCacheEnabled(true);
// Fix for CB-1405
// Google issue 4641
this.updateUserAgentString();
updateUserAgentString();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -349,15 +199,10 @@ public class AndroidWebView extends WebView implements CordovaWebView {
updateUserAgentString();
}
};
this.cordova.getActivity().registerReceiver(this.receiver, intentFilter);
cordova.getActivity().registerReceiver(this.receiver, intentFilter);
}
// end CB-1405
pluginManager = new PluginManager(this, this.cordova);
jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
exposedJsApi = new AndroidExposedJsApi(pluginManager, jsMessageQueue);
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
exposeJsInterface();
}
/**
@@ -374,41 +219,13 @@ public class AndroidWebView extends WebView implements CordovaWebView {
this.getSettings().getUserAgentString();
}
private void exposeJsInterface() {
int SDK_INT = Build.VERSION.SDK_INT;
if ((SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
Log.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
// Bug being that Java Strings do not get converted to JS strings automatically.
// This isn't hard to work-around on the JS side, but it's easier to just
// use the prompt bridge instead.
return;
}
this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
}
public AndroidCordovaWebView getCordovaWebView() {
return cordovaWebView;
}
/**
* Set the WebViewClient.
*
* @param client
*/
public void setWebViewClient(CordovaWebViewClient client) {
this.viewClient = client;
super.setWebViewClient((WebViewClient) client);
}
/**
* Set the WebChromeClient.
*
* @param client
*/
public void setWebChromeClient(CordovaChromeClient client) {
this.chromeClient = client;
super.setWebChromeClient((WebChromeClient) client);
}
public CordovaChromeClient getWebChromeClient() {
return this.chromeClient;
}
public void setCordovaWebView(AndroidCordovaWebView cordovaWebView) {
this.cordovaWebView = cordovaWebView;
}
/**
* Load the url into the webview.
@@ -417,46 +234,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
*/
@Override
public void loadUrl(String url) {
if (url.equals("about:blank") || url.startsWith("javascript:")) {
this.loadUrlNow(url);
}
else {
String initUrl = this.getProperty("url", null);
// If first page of app, then set URL to load to be the one passed in
if (initUrl == null) {
this.loadUrlIntoView(url);
}
// Otherwise use the URL specified in the activity's extras bundle
else {
this.loadUrlIntoView(initUrl);
}
}
}
/**
* 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 loadUrl(final String url, int time) {
String initUrl = this.getProperty("url", null);
// If first page of app, then set URL to load to be the one passed in
if (initUrl == null) {
this.loadUrlIntoView(url, time);
}
// Otherwise use the URL specified in the activity's extras bundle
else {
this.loadUrlIntoView(initUrl);
}
}
public void loadUrlIntoView(final String url) {
loadUrlIntoView(url, true);
this.getCordovaWebView().loadUrl(url);
}
/**
@@ -464,26 +242,22 @@ public class AndroidWebView extends WebView implements CordovaWebView {
*
* @param url
*/
public void loadUrlIntoView(final String url, boolean recreatePlugins) {
public void loadUrlIntoView(final String url) {
LOG.d(TAG, ">>> loadUrl(" + url + ")");
if (recreatePlugins) {
this.url = url;
this.pluginManager.init();
}
// Create a timeout timer for loadUrl
final AndroidWebView me = this;
final int currentLoadUrlTimeout = me.loadUrlTimeout;
final int loadUrlTimeoutValue = Integer.parseInt(this.getProperty("LoadUrlTimeoutValue", "20000"));
final int loadUrlTimeoutValue = Integer.parseInt(getCordovaWebView().getProperty("LoadUrlTimeoutValue", "20000"));
// Timeout error method
final Runnable loadError = new Runnable() {
public void run() {
me.stopLoading();
LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
CordovaWebViewClient viewClient = me.getCordovaWebView().getWebViewClient();
if (viewClient != null) {
viewClient.onReceivedError(me, -6, "The connection to the server was unsuccessful.", url);
viewClient.onReceivedError(me.getCordovaWebView(), -6, "The connection to the server was unsuccessful.", url);
}
}
};
@@ -529,80 +303,21 @@ 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
public void stopLoading() {
//viewClient.isCurrentlyLoading = false;
super.stopLoading();
}
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt)
{
super.onScrollChanged(l, t, oldl, oldt);
//We should post a message that the scroll changed
ScrollEvent myEvent = new ScrollEvent(l, t, oldl, oldt, this);
this.postMessage("onScrollChanged", myEvent);
getCordovaWebView().postMessage("onScrollChanged", myEvent);
}
/**
* Send JavaScript statement back to JavaScript.
* (This is a convenience method)
*
* @param statement
*/
public void sendJavascript(String statement) {
this.jsMessageQueue.addJavaScript(statement);
}
/**
* Send a plugin result back to JavaScript.
* (This is a convenience method)
*
* @param result
* @param callbackId
*/
public void sendPluginResult(PluginResult result, String callbackId) {
this.jsMessageQueue.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)
@@ -622,88 +337,19 @@ public class AndroidWebView extends WebView implements CordovaWebView {
return false;
}
/**
* Load the specified URL in the Cordova webview or a new browser instance.
*
* NOTE: If openExternal is false, only URLs listed in whitelist can be loaded.
*
* @param url The url to load.
* @param openExternal Load url in browser instead of Cordova webview.
* @param clearHistory Clear the history stack, so new page becomes top of history
* @param params Parameters for new app
/*
* Add a key code to either the keyUp or keyDown handler lists.
*/
public void showWebPage(String url, boolean openExternal, boolean clearHistory, HashMap<String, Object> params) {
LOG.d(TAG, "showWebPage(%s, %b, %b, HashMap", url, openExternal, clearHistory);
// If clearing history
if (clearHistory) {
this.clearHistory();
void bindButton(int keyCode, boolean keyDown) {
if(keyDown)
{
keyDownCodes.add(keyCode);
}
// If loading into our webview
if (!openExternal) {
// Make sure url is in whitelist
if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
// TODO: What about params?
// Load new URL
this.loadUrl(url);
return;
}
// Load in default viewer if not
LOG.w(TAG, "showWebPage: Cannot load URL into webview since it is not in white list. Loading into browser instead. (URL=" + url + ")");
else
{
keyUpCodes.add(keyCode);
}
try {
// Omitting the MIME type for file: URLs causes "No Activity found to handle Intent".
// Adding the MIME type to http: URLs causes them to not be handled by the downloader.
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse(url);
if ("file".equals(uri.getScheme())) {
intent.setDataAndType(uri, resourceApi.getMimeType(uri));
} else {
intent.setData(uri);
}
cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);
}
}
/**
* Check configuration parameters from Config.
* Approved list of URLs that can be loaded into Cordova
* <access origin="http://server regexp" subdomains="true" />
* Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
* <log level="DEBUG" />
*/
private void loadConfiguration() {
if ("true".equals(this.getProperty("Fullscreen", "false"))) {
this.cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
this.cordova.getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
/**
* 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
@@ -752,7 +398,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
@@ -760,8 +405,8 @@ public class AndroidWebView extends WebView implements CordovaWebView {
// If back key
if (keyCode == KeyEvent.KEYCODE_BACK) {
// A custom view is currently displayed (e.g. playing a video)
if(mCustomView != null) {
this.hideCustomView();
if(getCordovaWebView().isCustomViewShowing()) {
getCordovaWebView().hideCustomView();
} else {
// The webview is currently displayed
// If back key is bound, then send event to JavaScript
@@ -807,113 +452,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
return super.onKeyUp(keyCode, event);
}
public void bindButton(boolean override)
{
this.bound = override;
}
public void bindButton(String button, boolean override) {
// TODO Auto-generated method stub
if (button.compareTo("volumeup")==0) {
keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_UP);
}
else if (button.compareTo("volumedown")==0) {
keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_DOWN);
}
}
public void bindButton(int keyCode, boolean keyDown, boolean override) {
if(keyDown)
{
keyDownCodes.add(keyCode);
}
else
{
keyUpCodes.add(keyCode);
}
}
public boolean isBackButtonBound()
{
return this.bound;
}
public void handlePause(boolean keepRunning)
{
LOG.d(TAG, "Handle the pause");
// Send pause event to JavaScript
this.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onPause(keepRunning);
}
// If app doesn't want to run in background
if (!keepRunning) {
// Pause JavaScript timers (including setInterval)
this.pauseTimers();
}
paused = true;
}
public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
{
this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onResume(keepRunning);
}
// Resume JavaScript timers (including setInterval)
this.resumeTimers();
paused = false;
}
public void handleDestroy()
{
// Send destroy event to JavaScript
this.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
// Load blank page so that JavaScript onunload is called
this.loadUrl("about:blank");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onDestroy();
}
// unregister the receiver
if (this.receiver != null) {
try {
this.cordova.getActivity().unregisterReceiver(this.receiver);
} catch (Exception e) {
Log.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e);
}
}
}
public void onNewIntent(Intent intent)
{
//Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onNewIntent(intent);
}
}
public boolean isPaused()
{
return paused;
}
public boolean hadKeyEvent() {
return handleButton;
}
// Wrapping these functions in their own class prevents warnings in adb like:
// VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs
@TargetApi(16)
@@ -934,7 +472,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
}
}
//Can Go Back is BROKEN!
public boolean startOfHistory()
{
@@ -950,150 +487,14 @@ public class AndroidWebView extends WebView implements CordovaWebView {
return false;
}
public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {
// This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0
Log.d(TAG, "showing Custom View");
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
// Store the view and its callback for later (to kill it properly)
mCustomView = view;
mCustomViewCallback = callback;
// Add the custom view to its container.
ViewGroup parent = (ViewGroup) this.getParent();
parent.addView(view, COVER_SCREEN_GRAVITY_CENTER);
// Hide the content view.
this.setVisibility(View.GONE);
// Finally show the custom view container.
parent.setVisibility(View.VISIBLE);
parent.bringToFront();
}
public void hideCustomView() {
// This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0
Log.d(TAG, "Hiding Custom View");
if (mCustomView == null) return;
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
ViewGroup parent = (ViewGroup) this.getParent();
parent.removeView(mCustomView);
mCustomView = null;
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
this.setVisibility(View.VISIBLE);
}
/**
* if the video overlay is showing then we need to know
* as it effects back button handling
*
* @return true if custom view is showing
*/
public boolean isCustomViewShowing() {
return mCustomView != null;
}
@Override
public WebBackForwardList restoreState(Bundle savedInstanceState)
{
WebBackForwardList myList = super.restoreState(savedInstanceState);
Log.d(TAG, "WebView restoration crew now restoring!");
//Initialize the plugin manager once more
this.pluginManager.init();
getCordovaWebView().pluginManager.init();
return myList;
}
public void storeResult(int requestCode, int resultCode, Intent intent) {
mResult = new ActivityResult(requestCode, resultCode, intent);
}
public CordovaResourceApi getResourceApi() {
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 String exec(String service, String action, String callbackId,
String message) throws JSONException {
return this.exposedJsApi.exec(service, action, callbackId, message);
}
@Override
public void setNativeToJsBridgeMode(int parseInt) {
this.exposedJsApi.setNativeToJsBridgeMode(parseInt);
}
@Override
public String retrieveJsMessages(boolean equals) {
return this.exposedJsApi.retrieveJsMessages(equals);
}
@Override
public boolean onOverrideUrlLoading(String url) {
return this.pluginManager.onOverrideUrlLoading(url);
}
@Override
public void resetJsMessageQueue() {
this.jsMessageQueue.reset();
}
@Override
public void onReset() {
this.pluginManager.onReset();
}
@Override
public void incUrlTimeout() {
this.loadUrlTimeout++;
}
@Override
public PluginManager getPluginManager() {
// TODO Auto-generated method stub
return this.pluginManager;
}
@Override
public void setLayoutParams(
android.widget.FrameLayout.LayoutParams layoutParams) {
super.setLayoutParams(layoutParams);
}
@Override
public View getView() {
return this;
}
}

View File

@@ -214,11 +214,12 @@ public class CordovaActivity extends Activity implements CordovaInterface {
* require a more specialized web view.
*/
protected CordovaWebView makeWebView() {
String r = this.getStringProperty("webView", "org.apache.cordova.AndroidWebView");
String r = this.getStringProperty("webView", "org.apache.cordova.AndroidCordovaWebView");
try {
Class webViewClass = Class.forName(r);
Constructor<CordovaWebView> [] webViewConstructors = webViewClass.getConstructors();
if(CordovaWebView.class.isAssignableFrom(webViewClass)) {
for (Constructor<CordovaWebView> constructor : webViewConstructors) {
try {
@@ -243,7 +244,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
}
// If all else fails, return a default WebView
return (CordovaWebView) new AndroidWebView(CordovaActivity.this);
return (CordovaWebView) new AndroidCordovaWebView(CordovaActivity.this);
}
/**
@@ -269,7 +270,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
* @param webView the default constructed web view object
*/
protected CordovaChromeClient makeChromeClient(CordovaWebView webView) {
return webView.makeWebChromeClient();
return webView.makeWebChromeClient();
}
/**

View File

@@ -1,3 +1,21 @@
/*
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;

View File

@@ -11,108 +11,121 @@ import android.view.View;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.widget.LinearLayout.LayoutParams;
public interface CordovaWebView {
public abstract class CordovaWebView {
String OVER_SCROLL_NEVER = null;
Object pluginManager = null;
Object jsMessageQueue = null;
public PluginManager pluginManager = null;
protected NativeToJsMessageQueue jsMessageQueue = null;
View getView();
public abstract View getView();
CordovaWebViewClient makeWebViewClient();
public abstract CordovaWebViewClient makeWebViewClient();
CordovaChromeClient makeWebChromeClient();
public abstract CordovaChromeClient makeWebChromeClient();
void setWebViewClient(CordovaWebViewClient webViewClient);
public abstract void setWebViewClient(CordovaWebViewClient webViewClient);
void setWebChromeClient(CordovaChromeClient webChromeClient);
public abstract void setWebChromeClient(CordovaChromeClient webChromeClient);
void setId(int i);
public abstract void setId(int i);
void setLayoutParams(LayoutParams layoutParams);
public abstract void setLayoutParams(LayoutParams layoutParams);
void setVisibility(int invisible);
public abstract void setVisibility(int invisible);
Object getParent();
public abstract Object getParent();
void loadUrl(String url, int splashscreenTime);
public abstract void loadUrl(String url);
void loadUrl(String url);
public abstract void loadUrl(String url, int splashscreenTime);
boolean canGoBack();
public abstract void loadUrlNow(String url);
void clearCache(boolean b);
public abstract void loadUrlIntoView(final String url);
void clearHistory();
public abstract void loadUrlIntoView(final String url, boolean recreatePlugins);
boolean backHistory();
public abstract void loadUrlIntoView(final String url, final int splashscreenTime);
void handlePause(boolean keepRunning);
public abstract void stopLoading();
void onNewIntent(Intent intent);
public abstract boolean canGoBack();
void handleResume(boolean keepRunning, boolean activityResultKeepRunning);
public abstract void clearCache(boolean b);
void handleDestroy();
public abstract void clearHistory();
void postMessage(String id, Object data);
public abstract boolean backHistory();
void addJavascript(String statement);
public abstract void handlePause(boolean keepRunning);
public abstract void onNewIntent(Intent intent);
public abstract void handleResume(boolean keepRunning, boolean activityResultKeepRunning);
public abstract void handleDestroy();
public abstract void postMessage(String id, Object data);
public abstract void addJavascript(String statement);
public abstract void sendJavascript(String statememt);
public abstract CordovaChromeClient getWebChromeClient();
public abstract CordovaPlugin getPlugin(String initCallbackClass);
public abstract void showWebPage(String errorUrl, boolean b, boolean c, HashMap<String, Object> params);
public abstract Object getFocusedChild();
public abstract boolean isCustomViewShowing();
public abstract boolean onKeyUp(int keyCode, KeyEvent event);
public abstract boolean onKeyDown(int keyCode, KeyEvent event);
public abstract String exec(String service, String action, String callbackId, String message) throws JSONException;
public abstract void setNativeToJsBridgeMode(int parseInt);
public abstract String retrieveJsMessages(boolean equals);
public abstract void showCustomView(View view, CustomViewCallback callback);
public abstract void hideCustomView();
public abstract Context getContext();
public abstract boolean onOverrideUrlLoading(String url);
public abstract void resetJsMessageQueue();
public abstract void onReset();
public abstract int getVisibility();
public abstract void incUrlTimeout();
public abstract void setOverScrollMode(int overScrollNever);
public abstract void setNetworkAvailable(boolean online);
public abstract CordovaResourceApi getResourceApi();
public abstract void bindButton(boolean override);
public abstract void bindButton(String button, boolean override);
public abstract boolean isBackButtonBound();
public abstract void sendPluginResult(PluginResult cr, String callbackId);
public abstract PluginManager getPluginManager();
public abstract void setLayoutParams(android.widget.FrameLayout.LayoutParams layoutParams);
void sendJavascript(String statememt);
CordovaChromeClient getWebChromeClient();
CordovaPlugin getPlugin(String initCallbackClass);
void showWebPage(String errorUrl, boolean b, boolean c, HashMap<String, Object> params);
Object getFocusedChild();
boolean isCustomViewShowing();
boolean onKeyUp(int keyCode, KeyEvent event);
boolean onKeyDown(int keyCode, KeyEvent event);
String exec(String service, String action, String callbackId, String message) throws JSONException;
void setNativeToJsBridgeMode(int parseInt);
String retrieveJsMessages(boolean equals);
void showCustomView(View view, CustomViewCallback callback);
void hideCustomView();
Context getContext();
boolean onOverrideUrlLoading(String url);
void resetJsMessageQueue();
void onReset();
int getVisibility();
void incUrlTimeout();
void setOverScrollMode(int overScrollNever);
void loadUrlNow(String string);
void setNetworkAvailable(boolean online);
CordovaResourceApi getResourceApi();
void bindButton(boolean override);
void bindButton(String button, boolean override);
boolean isBackButtonBound();
void sendPluginResult(PluginResult cr, String callbackId);
PluginManager getPluginManager();
void setLayoutParams(android.widget.FrameLayout.LayoutParams layoutParams);
// Required for test
public abstract String getUrl();
public abstract boolean isPaused();
}

21
package.json Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "cordova-android",
"version": "3.4.0",
"description": "cordova-android release",
"main": "bin/create",
"repository": {
"type": "git",
"url": "https://git-wip-us.apache.org/repos/asf/cordova-android.git"
},
"keywords": [
"android",
"cordova",
"apache"
],
"author": "Apache Software Foundation",
"license": "Apache version 2.0",
"dependencies": {
"q": "^0.9.0",
"shelljs": "^0.2.6"
}
}

View File

@@ -22,7 +22,7 @@
android:layout_height="fill_parent"
android:orientation="vertical" >
<org.apache.cordova.CordovaWebView
<org.apache.cordova.AndroidWebView
android:id="@+id/cordovaWebView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

View File

@@ -1,44 +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.test;
import android.os.Bundle;
import org.apache.cordova.*;
public class basicauth extends DroidGap {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
// LogCat: onReceivedHttpAuthRequest(browserspy.dk:80,BrowserSpy.dk - HTTP Password Test)
AuthenticationToken token = new AuthenticationToken();
token.setUserName("test");
token.setPassword("test");
super.setAuthenticationToken(token, "browserspy.dk:80", "BrowserSpy.dk - HTTP Password Test");
// Add web site to whitelist
Config.init();
Config.addWhiteListEntry("http://browserspy.dk*", true);
// Load test
super.loadUrl("file:///android_asset/www/basicauth/index.html");
}
}

View File

@@ -27,6 +27,7 @@ import org.apache.cordova.test.backbuttonmultipage;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -174,7 +175,7 @@ public class BackButtonMultiPageTest extends ActivityInstrumentationTestCase2<ba
{
String url = testView.getUrl();
assertTrue(url.endsWith("sample3.html"));
BaseInputConnection viewConnection = new BaseInputConnection(testView, true);
BaseInputConnection viewConnection = new BaseInputConnection((View) testView, true);
KeyEvent backDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
KeyEvent backUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
viewConnection.sendKeyEvent(backDown);
@@ -187,7 +188,7 @@ public class BackButtonMultiPageTest extends ActivityInstrumentationTestCase2<ba
{
String url = testView.getUrl();
assertTrue(url.endsWith("sample2.html"));
BaseInputConnection viewConnection = new BaseInputConnection(testView, true);
BaseInputConnection viewConnection = new BaseInputConnection((View) testView, true);
KeyEvent backDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
KeyEvent backUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
viewConnection.sendKeyEvent(backDown);

View File

@@ -65,7 +65,7 @@ public class CordovaResourceApiTest extends ActivityInstrumentationTestCase2<Cor
cordovaWebView = activity.cordovaWebView;
resourceApi = cordovaWebView.getResourceApi();
resourceApi.setThreadCheckingEnabled(false);
cordovaWebView.pluginManager.addService(new PluginEntry("CordovaResourceApiTestPlugin1", new CordovaPlugin() {
cordovaWebView.getPluginManager().addService(new PluginEntry("CordovaResourceApiTestPlugin1", new CordovaPlugin() {
@Override
public Uri remapUri(Uri uri) {
if (uri.getQuery() != null && uri.getQuery().contains("pluginRewrite")) {

View File

@@ -1,32 +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.test.junit;
import org.apache.cordova.test.menus;
import android.test.ActivityInstrumentationTestCase2;
public class MenuTest extends ActivityInstrumentationTestCase2<menus> {
public MenuTest() {
super("org.apache.cordova.test", menus.class);
}
}

View File

@@ -1,73 +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.test.junit;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.ScrollEvent;
import org.apache.cordova.pluginApi.pluginStub;
import org.apache.cordova.test.CordovaWebViewTestActivity;
import org.apache.cordova.test.R;
import com.jayway.android.robotium.solo.By;
import com.jayway.android.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
public class MessageTest extends
ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
private CordovaWebViewTestActivity testActivity;
private CordovaWebView testView;
private pluginStub testPlugin;
private int TIMEOUT = 1000;
private Solo solo;
public MessageTest() {
super("org.apache.cordova.test.activities", CordovaWebViewTestActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
testActivity = this.getActivity();
testView = (CordovaWebView) testActivity.findViewById(R.id.cordovaWebView);
testPlugin = (pluginStub) testView.pluginManager.getPlugin("PluginStub");
solo = new Solo(getInstrumentation(), getActivity());
}
public void testOnScrollChanged()
{
solo.waitForWebElement(By.textContent("Cordova Android Tests"));
solo.scrollDown();
sleep();
Object data = testPlugin.data;
assertTrue(data.getClass().getSimpleName().equals("ScrollEvent"));
}
private void sleep() {
try {
Thread.sleep(TIMEOUT);
} catch (InterruptedException e) {
fail("Unexpected Timeout");
}
}
}

View File

@@ -1,80 +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.test;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import org.apache.cordova.*;
import org.apache.cordova.LOG;
public class menus extends DroidGap {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
super.registerForContextMenu(super.appView);
super.loadUrl("file:///android_asset/www/menus/index.html");
}
// Demonstrate how to add your own menus to app
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
int base = Menu.FIRST;
// Group, item id, order, title
menu.add(base, base, base, "Item1");
menu.add(base, base + 1, base + 1, "Item2");
menu.add(base, base + 2, base + 2, "Item3");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
LOG.d("menus", "Item " + item.getItemId() + " pressed.");
this.appView.loadUrl("javascript:alert('Menu " + item.getItemId() + " pressed.')");
return super.onOptionsItemSelected(item);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
LOG.d("menus", "onPrepareOptionsMenu()");
// this.appView.loadUrl("javascript:alert('onPrepareOptionsMenu()')");
return true;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info) {
LOG.d("menus", "onCreateContextMenu()");
menu.setHeaderTitle("Test Context Menu");
menu.add(200, 200, 200, "Context Item1");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
this.appView.loadUrl("javascript:alert('Context Menu " + item.getItemId() + " pressed.')");
return true;
}
}

View File

@@ -25,7 +25,7 @@ import android.webkit.GeolocationPermissions.Callback;
import org.apache.cordova.*;
import org.apache.cordova.LOG;
public class userwebview extends DroidGap {
public class userwebview extends CordovaActivity {
public TestViewClient testViewClient;
public TestChromeClient testChromeClient;
@@ -35,12 +35,12 @@ public class userwebview extends DroidGap {
super.onCreate(savedInstanceState);
testViewClient = new TestViewClient(this);
testChromeClient = new TestChromeClient(this);
super.init(new CordovaWebView(this), new TestViewClient(this), new TestChromeClient(this));
super.init(new AndroidWebView(this), new TestViewClient(this), new TestChromeClient(this));
super.loadUrl("file:///android_asset/www/userwebview/index.html");
}
public class TestChromeClient extends CordovaChromeClient {
public TestChromeClient(DroidGap arg0) {
public class TestChromeClient extends AndroidChromeClient {
public TestChromeClient(CordovaActivity arg0) {
super(arg0);
LOG.d("userwebview", "TestChromeClient()");
}
@@ -56,8 +56,8 @@ public class userwebview extends DroidGap {
/**
* This class can be used to override the GapViewClient and receive notification of webview events.
*/
public class TestViewClient extends CordovaWebViewClient {
public TestViewClient(DroidGap arg0) {
public class TestViewClient extends AndroidWebViewClient {
public TestViewClient(CordovaActivity arg0) {
super(arg0);
LOG.d("userwebview", "TestViewClient()");
}

View File

@@ -24,20 +24,20 @@ import android.webkit.WebView;
import org.apache.cordova.*;
import org.apache.cordova.LOG;
public class whitelist extends DroidGap {
public class whitelist extends CordovaActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init(new CordovaWebView(this), new TestViewClient(this), new CordovaChromeClient(this));
super.init(new AndroidWebView(this), new TestViewClient(this), new AndroidChromeClient(this));
super.loadUrl("file:///android_asset/www/whitelist/index.html");
}
/**
* This class can be used to override the GapViewClient and receive notification of webview events.
*/
public class TestViewClient extends CordovaWebViewClient {
public class TestViewClient extends AndroidWebViewClient {
public TestViewClient(DroidGap arg0) {
public TestViewClient(CordovaActivity arg0) {
super(arg0);
}