You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2014/07/08 20:46:26 UTC

[1/9] android commit: Change getProperty -> prefs.get* within CordovaActivity

Repository: cordova-android
Updated Branches:
  refs/heads/4.0.x eca05e6ba -> 25a7b6629
  refs/heads/master d51abdd73 -> 04ccb06e3


Change getProperty -> prefs.get* within CordovaActivity


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/9b25d45b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/9b25d45b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/9b25d45b

Branch: refs/heads/4.0.x
Commit: 9b25d45b9355ec1fe76a96f5694577a7f1edf680
Parents: d51abdd
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:08:15 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:08:15 2014 -0400

----------------------------------------------------------------------
 .../src/org/apache/cordova/CordovaActivity.java    | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/9b25d45b/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index ff96667..d3cc9c6 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -360,7 +360,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         }
         
         // If keepRunning
-        this.keepRunning = this.getBooleanProperty("KeepRunning", true);
+        this.keepRunning = preferences.getBoolean("KeepRunning", true);
 
         //Check if the view is attached to anything
         if(appView.getParent() != null)
@@ -401,10 +401,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         // If loadingDialog property, then show the App loading dialog for first page of app
         String loading = null;
         if ((this.appView == null) || !this.appView.canGoBack()) {
-            loading = this.getStringProperty("LoadingDialog", null);
+            loading = preferences.getString("LoadingDialog", null);
         }
         else {
-            loading = this.getStringProperty("LoadingPageDialog", null);
+            loading = preferences.getString("LoadingPageDialog", null);
         }
         if (loading != null) {
 
@@ -785,8 +785,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         final CordovaActivity me = this;
 
         // If errorUrl specified, then load it
-        final String errorUrl = me.getStringProperty("errorUrl", null);
-        if ((errorUrl != null) && (errorUrl.startsWith("file://") || Config.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
+        final String errorUrl = preferences.getString("errorUrl", null);
+        if ((errorUrl != null) && (errorUrl.startsWith("file://") || whitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
 
             // Load URL on UI thread
             me.runOnUiThread(new Runnable() {
@@ -924,7 +924,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
                 root.setMinimumHeight(display.getHeight());
                 root.setMinimumWidth(display.getWidth());
                 root.setOrientation(LinearLayout.VERTICAL);
-                root.setBackgroundColor(that.getIntegerProperty("backgroundColor", Color.BLACK));
+                root.setBackgroundColor(preferences.getInteger("backgroundColor", Color.BLACK));
                 root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                         ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
                 root.setBackgroundResource(that.splashscreen);
@@ -1002,7 +1002,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
             else {
                 // If the splash dialog is showing don't try to show it again
                 if (this.splashDialog == null || !this.splashDialog.isShowing()) {
-                    this.splashscreen = this.getIntegerProperty("SplashScreen", 0);
+                    String splashResource = preferences.getString("SplashScreen", null);
+                    if (splashResource != null) {
+                        splashscreen = getResources().getIdentifier(splashResource, "drawable", getClass().getPackage().getName());
+                    }
                     this.showSplashScreen(this.splashscreenTime);
                 }
             }


[6/9] android commit: Provide CordovaPlugin with CordovaPreferences. Add new Plugin.initialize()

Posted by ag...@apache.org.
Provide CordovaPlugin with CordovaPreferences. Add new Plugin.initialize()

This adds CordovaPlugin.initialize() (no args) and deprecates
CordovaPlugin.initialize(app, webView). This will allow us to refactor
more easily by using the package-private privateInitialize() to set
fields.


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/04ccb06e
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/04ccb06e
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/04ccb06e

Branch: refs/heads/4.0.x
Commit: 04ccb06e3f6297f3956d847507423c66006eae08
Parents: d31ee20
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:26:21 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:26:21 2014 -0400

----------------------------------------------------------------------
 framework/src/org/apache/cordova/App.java       |  8 ++------
 .../src/org/apache/cordova/CordovaActivity.java |  3 ++-
 .../src/org/apache/cordova/CordovaPlugin.java   | 21 +++++++++++++++-----
 .../src/org/apache/cordova/CordovaWebView.java  |  8 +++++++-
 .../src/org/apache/cordova/PluginEntry.java     |  2 +-
 5 files changed, 28 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/App.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/App.java b/framework/src/org/apache/cordova/App.java
index 2112519..c488f10 100755
--- a/framework/src/org/apache/cordova/App.java
+++ b/framework/src/org/apache/cordova/App.java
@@ -47,16 +47,12 @@ public class App extends CordovaPlugin {
     /**
      * Sets the context of the Command. This can then be used to do things like
      * get file paths associated with the Activity.
-     *
-     * @param cordova The context of the main Activity.
-     * @param webView The CordovaWebView Cordova is running in.
      */
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-        super.initialize(cordova, webView);
+    @Override
+    public void initialize() {
         this.initTelephonyReceiver();
     }
 
-
     /**
      * Executes the request and returns PluginResult.
      *

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index 0d07957..371172c 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -227,7 +227,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         }
 
         appView = makeWebView();
-        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist);
+        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist, preferences);
 
         // TODO: Have the views set this themselves.
         if (preferences.getBoolean("DisallowOverscroll", false)) {
@@ -240,6 +240,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         setVolumeControlStream(AudioManager.STREAM_MUSIC);
     }
 
+    @SuppressWarnings("deprecation")
     protected void loadConfig() {
         ConfigXmlParser parser = new ConfigXmlParser();
         parser.parse(this);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/CordovaPlugin.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java b/framework/src/org/apache/cordova/CordovaPlugin.java
index 8111e7b..eff66c8 100644
--- a/framework/src/org/apache/cordova/CordovaPlugin.java
+++ b/framework/src/org/apache/cordova/CordovaPlugin.java
@@ -32,21 +32,32 @@ import android.net.Uri;
  * Plugins must extend this class and override one of the execute methods.
  */
 public class CordovaPlugin {
+    @Deprecated // This is never set.
     public String id;
     public CordovaWebView webView;					// WebView object
     public CordovaInterface cordova;
+    protected CordovaPreferences preferences;
 
-    /**
-     * @param cordova The context of the main Activity.
-     * @param webView The associated CordovaWebView.
-     */
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+    void privateInitialize(CordovaInterface cordova, CordovaWebView webView, CordovaPreferences preferences) {
         assert this.cordova == null;
         this.cordova = cordova;
         this.webView = webView;
+        this.preferences = preferences;
+        initialize(cordova, webView);
+        initialize();
+    }
+
+    @Deprecated // Override initialize() instead.
+    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
     }
 
     /**
+     * This is where you can do start-up logic with protected fields set.
+     */
+    protected void initialize() {
+    }
+    
+    /**
      * Executes the request.
      *
      * This method is called from the WebView thread. To do a non-trivial amount of work, use:

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index fb442cc..7c1974c 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -92,6 +92,7 @@ public class CordovaWebView extends WebView {
     private Whitelist whitelist;
     // The URL passed to loadUrl(), not necessarily the URL of the current page.
     String loadedUrl;
+    private CordovaPreferences preferences;
 
     class ActivityResult {
         
@@ -135,7 +136,7 @@ public class CordovaWebView extends WebView {
 
     // Use two-phase init so that the control will work with XML layouts.
     public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
-            List<PluginEntry> pluginEntries, Whitelist whitelist) {
+            List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) {
         if (this.cordova != null) {
             throw new IllegalStateException();
         }
@@ -143,6 +144,7 @@ public class CordovaWebView extends WebView {
         this.viewClient = webViewClient;
         this.chromeClient = webChromeClient;
         this.whitelist = whitelist;
+        this.preferences = preferences;
         super.setWebChromeClient(webChromeClient);
         super.setWebViewClient(webViewClient);
 
@@ -903,4 +905,8 @@ public class CordovaWebView extends WebView {
     public CordovaResourceApi getResourceApi() {
         return resourceApi;
     }
+
+    public CordovaPreferences getPreferences() {
+        return preferences;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/PluginEntry.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginEntry.java b/framework/src/org/apache/cordova/PluginEntry.java
index c54f6cb..e94cf1c 100755
--- a/framework/src/org/apache/cordova/PluginEntry.java
+++ b/framework/src/org/apache/cordova/PluginEntry.java
@@ -98,7 +98,7 @@ public class PluginEntry {
             Class<?> c = getClassByName(this.pluginClass);
             if (isCordovaPlugin(c)) {
                 this.plugin = (CordovaPlugin) c.newInstance();
-                this.plugin.initialize(ctx, webView);
+                this.plugin.privateInitialize(ctx, webView, webView.getPreferences());
                 return plugin;
             }
         } catch (Exception e) {


[4/9] android commit: Convert usages of Config.* to use the non-static versions

Posted by ag...@apache.org.
Convert usages of Config.* to use the non-static versions


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/d31ee20b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/d31ee20b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/d31ee20b

Branch: refs/heads/4.0.x
Commit: d31ee20ba568aed498896a4165e27d87b509f946
Parents: 9b25d45
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:11:14 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:11:14 2014 -0400

----------------------------------------------------------------------
 framework/src/org/apache/cordova/Config.java    |  5 ++++
 .../src/org/apache/cordova/CordovaActivity.java |  5 ++--
 .../org/apache/cordova/CordovaChromeClient.java |  3 +-
 .../org/apache/cordova/CordovaUriHelper.java    |  2 +-
 .../src/org/apache/cordova/CordovaWebView.java  | 31 ++++++++++----------
 .../cordova/IceCreamCordovaWebViewClient.java   |  2 +-
 6 files changed, 26 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/Config.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/Config.java b/framework/src/org/apache/cordova/Config.java
index dfb039d..c13d397 100644
--- a/framework/src/org/apache/cordova/Config.java
+++ b/framework/src/org/apache/cordova/Config.java
@@ -22,6 +22,7 @@ package org.apache.cordova;
 import android.app.Activity;
 import android.util.Log;
 
+@Deprecated // Use Whitelist, CordovaPrefences, etc. directly.
 public class Config {
     private static final String TAG = "Config";
 
@@ -82,4 +83,8 @@ public class Config {
     public static String getErrorUrl() {
         return parser.getPreferences().getString("errorurl", null);
     }
+
+    public static Whitelist getWhitelist() {
+        return parser.getWhitelist();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index d3cc9c6..0d07957 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -227,7 +227,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         }
 
         appView = makeWebView();
-        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries);
+        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist);
 
         // TODO: Have the views set this themselves.
         if (preferences.getBoolean("DisallowOverscroll", false)) {
@@ -844,8 +844,9 @@ 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 Config.isUrlWhiteListed(url);
+        return whitelist.isUrlWhiteListed(url);
     }
 
     /*

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java
index 0337098..cebabba 100755
--- a/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -240,11 +240,10 @@ public class CordovaChromeClient extends WebChromeClient {
         }
 
         else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
-            String startUrl = Config.getStartUrl();
             // 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") && startUrl.startsWith(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);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaUriHelper.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaUriHelper.java b/framework/src/org/apache/cordova/CordovaUriHelper.java
index a6a0dcc..f189f1c 100644
--- a/framework/src/org/apache/cordova/CordovaUriHelper.java
+++ b/framework/src/org/apache/cordova/CordovaUriHelper.java
@@ -49,7 +49,7 @@ class CordovaUriHelper {
         if(url.startsWith("http:") || url.startsWith("https:"))
         {
             // We only need to whitelist sites on the Internet! 
-            if(Config.isUrlWhiteListed(url))
+            if(appView.getWhitelist().isUrlWhiteListed(url))
             {
                 return false;
             }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 4650588..fb442cc 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -26,12 +26,6 @@ import java.util.HashSet;
 import java.util.List;
 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 android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
@@ -80,11 +74,8 @@ public class CordovaWebView extends WebView {
     /** 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;
 
@@ -97,9 +88,10 @@ public class CordovaWebView extends WebView {
     private View mCustomView;
     private WebChromeClient.CustomViewCallback mCustomViewCallback;
 
-    private ActivityResult mResult = null;
-
     private CordovaResourceApi resourceApi;
+    private Whitelist whitelist;
+    // The URL passed to loadUrl(), not necessarily the URL of the current page.
+    String loadedUrl;
 
     class ActivityResult {
         
@@ -142,13 +134,15 @@ public class CordovaWebView extends WebView {
     }
 
     // Use two-phase init so that the control will work with XML layouts.
-    public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient, List<PluginEntry> pluginEntries) {
+    public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
+            List<PluginEntry> pluginEntries, Whitelist whitelist) {
         if (this.cordova != null) {
             throw new IllegalStateException();
         }
         this.cordova = cordova;
         this.viewClient = webViewClient;
         this.chromeClient = webChromeClient;
+        this.whitelist = whitelist;
         super.setWebChromeClient(webChromeClient);
         super.setWebViewClient(webViewClient);
 
@@ -310,6 +304,11 @@ public class CordovaWebView extends WebView {
         return this.chromeClient;
     }
 
+    
+    public Whitelist getWhitelist() {
+        return this.whitelist;
+    }
+    
     /**
      * Load the url into the webview.
      *
@@ -357,7 +356,7 @@ public class CordovaWebView extends WebView {
         LOG.d(TAG, ">>> loadUrl(" + url + ")");
 
         if (recreatePlugins) {
-            this.url = url;
+            this.loadedUrl = url;
             this.pluginManager.init();
         }
 
@@ -413,7 +412,7 @@ public class CordovaWebView extends WebView {
         if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
             LOG.d(TAG, ">>> loadUrlNow()");
         }
-        if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
+        if (url.startsWith("file://") || url.startsWith("javascript:") || whitelist.isUrlWhiteListed(url)) {
             super.loadUrl(url);
         }
     }
@@ -549,7 +548,7 @@ public class CordovaWebView extends WebView {
         if (!openExternal) {
 
             // Make sure url is in whitelist
-            if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
+            if (url.startsWith("file://") || whitelist.isUrlWhiteListed(url)) {
                 // TODO: What about params?
                 // Load new URL
                 this.loadUrl(url);
@@ -897,8 +896,8 @@ public class CordovaWebView extends WebView {
         return myList;
     }
 
+    @Deprecated // This never did anything
     public void storeResult(int requestCode, int resultCode, Intent intent) {
-        mResult = new ActivityResult(requestCode, resultCode, intent);
     }
     
     public CordovaResourceApi getResourceApi() {

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index 67793d7..27bb5ef 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -77,7 +77,7 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
     }
 
     private boolean isUrlHarmful(String url) {
-        return ((url.startsWith("http:") || url.startsWith("https:")) && !Config.isUrlWhiteListed(url))
+        return ((url.startsWith("http:") || url.startsWith("https:")) && !appView.getWhitelist().isUrlWhiteListed(url))
             || url.contains("app_webview");
     }
 


[2/9] android commit: Change getProperty -> prefs.get* within CordovaActivity

Posted by ag...@apache.org.
Change getProperty -> prefs.get* within CordovaActivity


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/9b25d45b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/9b25d45b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/9b25d45b

Branch: refs/heads/master
Commit: 9b25d45b9355ec1fe76a96f5694577a7f1edf680
Parents: d51abdd
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:08:15 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:08:15 2014 -0400

----------------------------------------------------------------------
 .../src/org/apache/cordova/CordovaActivity.java    | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/9b25d45b/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index ff96667..d3cc9c6 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -360,7 +360,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         }
         
         // If keepRunning
-        this.keepRunning = this.getBooleanProperty("KeepRunning", true);
+        this.keepRunning = preferences.getBoolean("KeepRunning", true);
 
         //Check if the view is attached to anything
         if(appView.getParent() != null)
@@ -401,10 +401,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         // If loadingDialog property, then show the App loading dialog for first page of app
         String loading = null;
         if ((this.appView == null) || !this.appView.canGoBack()) {
-            loading = this.getStringProperty("LoadingDialog", null);
+            loading = preferences.getString("LoadingDialog", null);
         }
         else {
-            loading = this.getStringProperty("LoadingPageDialog", null);
+            loading = preferences.getString("LoadingPageDialog", null);
         }
         if (loading != null) {
 
@@ -785,8 +785,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         final CordovaActivity me = this;
 
         // If errorUrl specified, then load it
-        final String errorUrl = me.getStringProperty("errorUrl", null);
-        if ((errorUrl != null) && (errorUrl.startsWith("file://") || Config.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
+        final String errorUrl = preferences.getString("errorUrl", null);
+        if ((errorUrl != null) && (errorUrl.startsWith("file://") || whitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
 
             // Load URL on UI thread
             me.runOnUiThread(new Runnable() {
@@ -924,7 +924,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
                 root.setMinimumHeight(display.getHeight());
                 root.setMinimumWidth(display.getWidth());
                 root.setOrientation(LinearLayout.VERTICAL);
-                root.setBackgroundColor(that.getIntegerProperty("backgroundColor", Color.BLACK));
+                root.setBackgroundColor(preferences.getInteger("backgroundColor", Color.BLACK));
                 root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                         ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
                 root.setBackgroundResource(that.splashscreen);
@@ -1002,7 +1002,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
             else {
                 // If the splash dialog is showing don't try to show it again
                 if (this.splashDialog == null || !this.splashDialog.isShowing()) {
-                    this.splashscreen = this.getIntegerProperty("SplashScreen", 0);
+                    String splashResource = preferences.getString("SplashScreen", null);
+                    if (splashResource != null) {
+                        splashscreen = getResources().getIdentifier(splashResource, "drawable", getClass().getPackage().getName());
+                    }
                     this.showSplashScreen(this.splashscreenTime);
                 }
             }


[7/9] Merge branch 'master' into 4.0.x (remove Config.* references)

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/CordovaWebView.java
index dc871ac,7c1974c..977ad4d
mode 100644,100755..100644
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@@ -1,76 -1,467 +1,77 @@@
 -/*
 -       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.HashMap;
 -import java.util.HashSet;
  import java.util.List;
 -import java.util.Locale;
  
 -import android.annotation.SuppressLint;
 -import android.annotation.TargetApi;
 -import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
 -import android.content.IntentFilter;
 -import android.content.pm.ApplicationInfo;
 -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.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;
 +import android.webkit.WebChromeClient.CustomViewCallback;
 +import android.widget.LinearLayout.LayoutParams;
  
 -/*
 - * 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 CordovaWebView extends WebView {
 +public interface CordovaWebView {
 +    public static final String CORDOVA_VERSION = "4.0.0-dev";
  
-     void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient, List<PluginEntry> pluginEntries);
 -    public static final String TAG = "CordovaWebView";
 -    public static final String CORDOVA_VERSION = "3.6.0-dev";
++    void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
++              List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences);
  
 -    private HashSet<Integer> boundKeyCodes = new HashSet<Integer>();
 +    View getView();
  
 -    public PluginManager pluginManager;
 -    private boolean paused;
 +    CordovaWebViewClient makeWebViewClient(CordovaInterface cordova);
  
 -    private BroadcastReceiver receiver;
 +    CordovaChromeClient makeWebChromeClient(CordovaInterface cordova);
 +        
 +    void setWebViewClient(CordovaWebViewClient webViewClient);
  
 +    void setWebChromeClient(CordovaChromeClient webChromeClient);
  
 -    /** Activities and other important classes **/
 -    private CordovaInterface cordova;
 -    CordovaWebViewClient viewClient;
 -    private CordovaChromeClient chromeClient;
 +    void setId(int i);
  
 -    // Flag to track that a loadUrl timeout occurred
 -    int loadUrlTimeout = 0;
 +    void setLayoutParams(LayoutParams layoutParams);
  
 -    private long lastMenuEventTime = 0;
 +    void setVisibility(int invisible);
  
 -    NativeToJsMessageQueue jsMessageQueue;
 -    ExposedJsApi exposedJsApi;
 +    Object getParent();
  
 -    /** custom view created by the browser (a video player for example) */
 -    private View mCustomView;
 -    private WebChromeClient.CustomViewCallback mCustomViewCallback;
 +    void loadUrl(String url);
  
 -    private CordovaResourceApi resourceApi;
 -    private Whitelist whitelist;
 -    // The URL passed to loadUrl(), not necessarily the URL of the current page.
 -    String loadedUrl;
 -    private CordovaPreferences preferences;
 +    void loadUrl(String url, int splashscreenTime);
  
 -    class ActivityResult {
 -        
 -        int request;
 -        int result;
 -        Intent incoming;
 -        
 -        public ActivityResult(int req, int res, Intent intent) {
 -            request = req;
 -            result = res;
 -            incoming = intent;
 -        }
 +    void loadUrlNow(String url);
  
 -        
 -    }
 -    
 -    static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
 -            new FrameLayout.LayoutParams(
 -            ViewGroup.LayoutParams.MATCH_PARENT,
 -            ViewGroup.LayoutParams.MATCH_PARENT,
 -            Gravity.CENTER);
 -    
 -    public CordovaWebView(Context context) {
 -        this(context, null);
 -    }
 -
 -    public CordovaWebView(Context context, AttributeSet attrs) {
 -        super(context, attrs);
 -    }
 +    void loadUrlIntoView(final String url);
  
 -    @Deprecated
 -    public CordovaWebView(Context context, AttributeSet attrs, int defStyle) {
 -        super(context, attrs, defStyle);
 -    }
 +    void loadUrlIntoView(final String url, boolean recreatePlugins);
  
 -    @TargetApi(11)
 -    @Deprecated
 -    public CordovaWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
 -        super(context, attrs, defStyle, privateBrowsing);
 -    }
 -
 -    // Use two-phase init so that the control will work with XML layouts.
 -    public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
 -            List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) {
 -        if (this.cordova != null) {
 -            throw new IllegalStateException();
 -        }
 -        this.cordova = cordova;
 -        this.viewClient = webViewClient;
 -        this.chromeClient = webChromeClient;
 -        this.whitelist = whitelist;
 -        this.preferences = preferences;
 -        super.setWebChromeClient(webChromeClient);
 -        super.setWebViewClient(webViewClient);
 -
 -        pluginManager = new PluginManager(this, this.cordova, pluginEntries);
 -        jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
 -        exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue);
 -        resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
 -
 -        pluginManager.addService("App", "org.apache.cordova.App");
 -        initWebViewSettings();
 -        exposeJsInterface();
 -    }
 -
 -    @SuppressLint("SetJavaScriptEnabled")
 -    @SuppressWarnings("deprecation")
 -    private void initWebViewSettings() {
 -        this.setInitialScale(0);
 -        this.setVerticalScrollBarEnabled(false);
 -        // TODO: The Activity is the one that should call requestFocus().
 -        if (shouldRequestFocusOnInit()) {
 -			this.requestFocusFromTouch();
 -		}
 -		// Enable JavaScript
 -        WebSettings settings = this.getSettings();
 -        settings.setJavaScriptEnabled(true);
 -        settings.setJavaScriptCanOpenWindowsAutomatically(true);
 -        settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
 -        
 -        // Set the nav dump for HTC 2.x devices (disabling for ICS, deprecated entirely for Jellybean 4.2)
 -        try {
 -            Method gingerbread_getMethod =  WebSettings.class.getMethod("setNavDump", new Class[] { boolean.class });
 -            
 -            String manufacturer = android.os.Build.MANUFACTURER;
 -            Log.d(TAG, "CordovaWebView is running on device made by: " + manufacturer);
 -            if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB &&
 -                    android.os.Build.MANUFACTURER.contains("HTC"))
 -            {
 -                gingerbread_getMethod.invoke(settings, true);
 -            }
 -        } catch (NoSuchMethodException e) {
 -            Log.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8");
 -        } catch (IllegalArgumentException e) {
 -            Log.d(TAG, "Doing the NavDump failed with bad arguments");
 -        } catch (IllegalAccessException e) {
 -            Log.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore");
 -        } catch (InvocationTargetException e) {
 -            Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore.");
 -        }
 -
 -        //We don't save any form data in the application
 -        settings.setSaveFormData(false);
 -        settings.setSavePassword(false);
 -        
 -        // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
 -        // while we do this
 -        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
 -            Level16Apis.enableUniversalAccess(settings);
 -        // Enable database
 -        // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
 -        String databasePath = getContext().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!
 -        ApplicationInfo appInfo = getContext().getApplicationContext().getApplicationInfo();
 -        if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 &&
 -            android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
 -            enableRemoteDebugging();
 -        }
 -        
 -        settings.setGeolocationDatabasePath(databasePath);
 +    void loadUrlIntoView(final String url, final int splashscreenTime);
  
 -        // Enable DOM storage
 -        settings.setDomStorageEnabled(true);
 +    void stopLoading();
  
 -        // Enable built-in geolocation
 -        settings.setGeolocationEnabled(true);
 -        
 -        // Enable AppCache
 -        // Fix for CB-2282
 -        settings.setAppCacheMaxSize(5 * 1048576);
 -        settings.setAppCachePath(databasePath);
 -        settings.setAppCacheEnabled(true);
 -        
 -        // Fix for CB-1405
 -        // Google issue 4641
 -        settings.getUserAgentString();
 -        
 -        IntentFilter intentFilter = new IntentFilter();
 -        intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
 -        if (this.receiver == null) {
 -            this.receiver = new BroadcastReceiver() {
 -                @Override
 -                public void onReceive(Context context, Intent intent) {
 -                    getSettings().getUserAgentString();
 -                }
 -            };
 -            getContext().registerReceiver(this.receiver, intentFilter);
 -        }
 -        // end CB-1405
 -    }
 -
 -    @TargetApi(Build.VERSION_CODES.KITKAT)
 -    private void enableRemoteDebugging() {
 -        try {
 -            WebView.setWebContentsDebuggingEnabled(true);
 -        } catch (IllegalArgumentException e) {
 -            Log.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! ");
 -            e.printStackTrace();
 -        }
 -    }
 -
 -    public CordovaChromeClient makeWebChromeClient(CordovaInterface cordova) {
 -        return new CordovaChromeClient(cordova, this);
 -    }
 -
 -    public CordovaWebViewClient makeWebViewClient(CordovaInterface cordova) {
 -        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
 -            return new CordovaWebViewClient(cordova, this);
 -        }
 -        return new IceCreamCordovaWebViewClient(cordova, this);
 -    }
 -
 -	/**
 -	 * Override this method to decide whether or not you need to request the
 -	 * focus when your application start
 -	 * 
 -	 * @return true unless this method is overriden to return a different value
 -	 */
 -    protected boolean shouldRequestFocusOnInit() {
 -		return true;
 -	}
 -
 -    private void exposeJsInterface() {
 -        if ((Build.VERSION.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");
 -    }
 -
 -    @Override
 -    public void setWebViewClient(WebViewClient client) {
 -        this.viewClient = (CordovaWebViewClient)client;
 -        super.setWebViewClient(client);
 -    }
 -
 -    @Override
 -    public void setWebChromeClient(WebChromeClient client) {
 -        this.chromeClient = (CordovaChromeClient)client;
 -        super.setWebChromeClient(client);
 -    }
 -    
 -    public CordovaChromeClient getWebChromeClient() {
 -        return this.chromeClient;
 -    }
 +    boolean canGoBack();
  
 -    
 -    public Whitelist getWhitelist() {
 -        return this.whitelist;
 -    }
 -    
 -    /**
 -     * 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 {
 -            this.loadUrlIntoView(url);
 -        }
 -    }
 +    void clearCache(boolean b);
  
 -    /**
 -     * 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);
 -    }
 +    void clearHistory();
  
 -    /**
 -     * Load the url into the webview.
 -     *
 -     * @param url
 -     */
 -    public void loadUrlIntoView(final String url, boolean recreatePlugins) {
 -        LOG.d(TAG, ">>> loadUrl(" + url + ")");
 -
 -        if (recreatePlugins) {
 -            this.loadedUrl = url;
 -            this.pluginManager.init();
 -        }
 -
 -        // Create a timeout timer for loadUrl
 -        final CordovaWebView me = this;
 -        final int currentLoadUrlTimeout = me.loadUrlTimeout;
 -        final int loadUrlTimeoutValue = Integer.parseInt(this.getProperty("LoadUrlTimeoutValue", "20000"));
 -
 -        // Timeout error method
 -        final Runnable loadError = new Runnable() {
 -            public void run() {
 -                me.stopLoading();
 -                LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
 -                if (viewClient != null) {
 -                    viewClient.onReceivedError(me, -6, "The connection to the server was unsuccessful.", url);
 -                }
 -            }
 -        };
 -
 -        // Timeout timer method
 -        final Runnable timeoutCheck = new Runnable() {
 -            public void run() {
 -                try {
 -                    synchronized (this) {
 -                        wait(loadUrlTimeoutValue);
 -                    }
 -                } catch (InterruptedException e) {
 -                    e.printStackTrace();
 -                }
 -
 -                // If timeout, then stop loading and handle error
 -                if (me.loadUrlTimeout == currentLoadUrlTimeout) {
 -                    me.cordova.getActivity().runOnUiThread(loadError);
 -                }
 -            }
 -        };
 -
 -        // Load url
 -        this.cordova.getActivity().runOnUiThread(new Runnable() {
 -            public void run() {
 -                cordova.getThreadPool().execute(timeoutCheck);
 -                me.loadUrlNow(url);
 -            }
 -        });
 -    }
 +    boolean backHistory();
  
 -    /**
 -     * Load URL in webview.
 -     *
 -     * @param url
 -     */
 -    void loadUrlNow(String url) {
 -        if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
 -            LOG.d(TAG, ">>> loadUrlNow()");
 -        }
 -        if (url.startsWith("file://") || url.startsWith("javascript:") || whitelist.isUrlWhiteListed(url)) {
 -            super.loadUrl(url);
 -        }
 -    }
 +    void handlePause(boolean keepRunning);
  
 -    /**
 -     * 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) {
 +    void onNewIntent(Intent intent);
  
 -        // If not first page of app, then load immediately
 -        // Add support for browser history if we use it.
 -        if ((url.startsWith("javascript:")) || this.canGoBack()) {
 -        }
 +    void handleResume(boolean keepRunning, boolean activityResultKeepRunning);
  
 -        // If first page, then show splashscreen
 -        else {
 +    void handleDestroy();
  
 -            LOG.d(TAG, "loadUrlIntoView(%s, %d)", url, time);
 +    void postMessage(String id, Object data);
  
 -            // Send message to show splashscreen now if desired
 -            this.postMessage("splashscreen", "show");
 -        }
 +    void addJavascript(String statement);
  
 -        // Load url
 -        this.loadUrlIntoView(url);
 -    }
 -    
 -    @Override
 -    public void stopLoading() {
 -        viewClient.isCurrentlyLoading = false;
 -        super.stopLoading();
 -    }
 -    
 -    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);
 -    }
 -    
      /**
       * Send JavaScript statement back to JavaScript.
 +     * (This is a convenience method)
 +     *
 +     * @param statement
       * Deprecated (https://issues.apache.org/jira/browse/CB-6851)
       * Instead of executing snippets of JS, you should use the exec bridge
       * to create a Java->JS communication channel.
@@@ -90,47 -481,432 +91,49 @@@
       *    savedCallbackContext.sendPluginResult(dataResult);
       */
      @Deprecated
 -    public void sendJavascript(String statement) {
 -        this.jsMessageQueue.addJavaScript(statement);
 -    }
 +    void sendJavascript(String statememt);
  
 -    /**
 -     * 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);
 -    }
 +    CordovaChromeClient getWebChromeClient();
  
 -    /**
 -     * 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);
 -        }
 -    }
 +    CordovaPlugin getPlugin(String initCallbackClass);
  
 +    void showWebPage(String errorUrl, boolean b, boolean c, HashMap<String, Object> params);
  
 -    /**
 -     * Go to previous page in history.  (We manage our own history)
 -     *
 -     * @return true if we went back, false if we are already at top
 -     */
 -    public boolean backHistory() {
 +    Object getFocusedChild();
  
 -        // Check webview first to see if there is a history
 -        // This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
 -        if (super.canGoBack()) {
 -            printBackForwardList();
 -            super.goBack();
 -            
 -            return true;
 -        }
 -        return false;
 -    }
 +    boolean isCustomViewShowing();
  
 +    void showCustomView(View view, CustomViewCallback callback);
  
 -    /**
 -     * 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
 -     */
 -    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://") || whitelist.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);
 -        }
 -    }
 +    void hideCustomView();
  
 -    /**
 -     * 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();
 -    }
 -
 -    @Override
 -    public boolean onKeyDown(int keyCode, KeyEvent event)
 -    {
 -        if(boundKeyCodes.contains(keyCode))
 -        {
 -            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
 -                    this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');");
 -                    return true;
 -            }
 -            // If volumeup key
 -            else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
 -                    this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');");
 -                    return true;
 -            }
 -            else
 -            {
 -                return super.onKeyDown(keyCode, event);
 -            }
 -        }
 -        else if(keyCode == KeyEvent.KEYCODE_BACK)
 -        {
 -            return !(this.startOfHistory()) || isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK);
 -        }
 -        else if(keyCode == KeyEvent.KEYCODE_MENU)
 -        {
 -            //How did we get here?  Is there a childView?
 -            View childView = this.getFocusedChild();
 -            if(childView != null)
 -            {
 -                //Make sure we close the keyboard if it's present
 -                InputMethodManager imm = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
 -                imm.hideSoftInputFromWindow(childView.getWindowToken(), 0);
 -                cordova.getActivity().openOptionsMenu();
 -                return true;
 -            } else {
 -                return super.onKeyDown(keyCode, event);
 -            }
 -        }
 -        return super.onKeyDown(keyCode, event);
 -    }
 -
 -    @Override
 -    public boolean onKeyUp(int keyCode, KeyEvent event)
 -    {
 -        // If back key
 -        if (keyCode == KeyEvent.KEYCODE_BACK) {
 -            // A custom view is currently displayed  (e.g. playing a video)
 -            if(mCustomView != null) {
 -                this.hideCustomView();
 -                return true;
 -            } else {
 -                // The webview is currently displayed
 -                // If back key is bound, then send event to JavaScript
 -                if (isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK)) {
 -                    this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');");
 -                    return true;
 -                } else {
 -                    // If not bound
 -                    // Go to previous page in webview if it is possible to go back
 -                    if (this.backHistory()) {
 -                        return true;
 -                    }
 -                    // If not, then invoke default behavior
 -                }
 -            }
 -        }
 -        // Legacy
 -        else if (keyCode == KeyEvent.KEYCODE_MENU) {
 -            if (this.lastMenuEventTime < event.getEventTime()) {
 -                this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');");
 -            }
 -            this.lastMenuEventTime = event.getEventTime();
 -            return super.onKeyUp(keyCode, event);
 -        }
 -        // If search key
 -        else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
 -            this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');");
 -            return true;
 -        }
 -
 -        //Does webkit change this behavior?
 -        return super.onKeyUp(keyCode, event);
 -    }
 -
 -    public void setButtonPlumbedToJs(int keyCode, boolean value) {
 -        switch (keyCode) {
 -            case KeyEvent.KEYCODE_VOLUME_DOWN:
 -            case KeyEvent.KEYCODE_VOLUME_UP:
 -            case KeyEvent.KEYCODE_BACK:
 -                // TODO: Why are search and menu buttons handled separately?
 -                boundKeyCodes.add(keyCode);
 -                return;
 -            default:
 -                throw new IllegalArgumentException("Unsupported keycode: " + keyCode);
 -        }
 -    }
 -
 -    @Deprecated // Use setButtonPlumbedToJs() instead.
 -    public void bindButton(boolean override)
 -    {
 -        setButtonPlumbedToJs(KeyEvent.KEYCODE_BACK, override);
 -    }
 -
 -    @Deprecated // Use setButtonPlumbedToJs() instead.
 -    public void bindButton(String button, boolean override) {
 -        if (button.compareTo("volumeup")==0) {
 -            setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_UP, override);
 -        }
 -        else if (button.compareTo("volumedown")==0) {
 -            setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_DOWN, override);
 -        }
 -    }
 -
 -    @Deprecated // Use setButtonPlumbedToJs() instead.
 -    public void bindButton(int keyCode, boolean keyDown, boolean override) {
 -        setButtonPlumbedToJs(keyCode, override);
 -    }
 -
 -    @Deprecated // Use isButtonPlumbedToJs
 -    public boolean isBackButtonBound()
 -    {
 -        return isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK);
 -    }
 -
 -    public boolean isButtonPlumbedToJs(int keyCode)
 -    {
 -        return boundKeyCodes.contains(keyCode);
 -    }
 -
 -    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)
 -    {
 +    Context getContext();
  
 -        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 {
 -                getContext().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;
 -    }
 -
 -    @Deprecated // This never did anything.
 -    public boolean hadKeyEvent() {
 -        return false;
 -    }
 -
 -    // 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)
 -    private static class Level16Apis {
 -        static void enableUniversalAccess(WebSettings settings) {
 -            settings.setAllowUniversalAccessFromFileURLs(true);
 -        }
 -    }
 -    
 -    public void printBackForwardList() {
 -        WebBackForwardList currentList = this.copyBackForwardList();
 -        int currentSize = currentList.getSize();
 -        for(int i = 0; i < currentSize; ++i)
 -        {
 -            WebHistoryItem item = currentList.getItemAtIndex(i);
 -            String url = item.getUrl();
 -            LOG.d(TAG, "The URL at index: " + Integer.toString(i) + " is " + url );
 -        }
 -    }
 -    
 -    
 -    //Can Go Back is BROKEN!
 -    public boolean startOfHistory()
 -    {
 -        WebBackForwardList currentList = this.copyBackForwardList();
 -        WebHistoryItem item = currentList.getItemAtIndex(0);
 -        if( item!=null){	// Null-fence in case they haven't called loadUrl yet (CB-2458)
 -	        String url = item.getUrl();
 -	        String currentUrl = this.getUrl();
 -	        LOG.d(TAG, "The current URL is: " + currentUrl);
 -	        LOG.d(TAG, "The URL at item 0 is: " + url);
 -	        return currentUrl.equals(url);
 -        }
 -        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;
 -    }
 +    boolean onOverrideUrlLoading(String url);
 +
 +    int getVisibility();
 +
 +    void incUrlTimeout();
 +
 +    void setOverScrollMode(int overScrollNever);
 +
 +    void setNetworkAvailable(boolean online);
 +
 +    CordovaResourceApi getResourceApi();
 +
 +    void setButtonPlumbedToJs(int keyCode, boolean override);
 +    boolean isButtonPlumbedToJs(int keyCode);
 +
 +    void sendPluginResult(PluginResult cr, String callbackId);
 +
 +    PluginManager getPluginManager();
 +
 +    void setLayoutParams(android.widget.FrameLayout.LayoutParams layoutParams);
      
 -    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();
 -        return myList;
 -    }
 -
 -    @Deprecated // This never did anything
 -    public void storeResult(int requestCode, int resultCode, Intent intent) {
 -    }
 +    // Required for test
 +    String getUrl();
 +    boolean isPaused();
- 
+     
 -    public CordovaResourceApi getResourceApi() {
 -        return resourceApi;
 -    }
 -
 -    public CordovaPreferences getPreferences() {
 -        return preferences;
 -    }
++    Whitelist getWhitelist();
++    CordovaPreferences getPreferences();
  }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/CoreAndroid.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/CoreAndroid.java
index 56c7e64,0000000..6403673
mode 100755,000000..100755
--- a/framework/src/org/apache/cordova/CoreAndroid.java
+++ b/framework/src/org/apache/cordova/CoreAndroid.java
@@@ -1,305 -1,0 +1,301 @@@
 +/*
 +       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.CallbackContext;
 +import org.apache.cordova.CordovaPlugin;
 +import org.apache.cordova.LOG;
 +import org.apache.cordova.PluginResult;
 +import org.json.JSONArray;
 +import org.json.JSONException;
 +import org.json.JSONObject;
 +
 +import android.content.BroadcastReceiver;
 +import android.content.Context;
 +import android.content.Intent;
 +import android.content.IntentFilter;
 +import android.telephony.TelephonyManager;
 +import android.view.KeyEvent;
 +
 +import java.util.HashMap;
 +
 +/**
 + * This class exposes methods in Cordova that can be called from JavaScript.
 + */
 +public class CoreAndroid extends CordovaPlugin {
 +
 +    protected static final String TAG = "CordovaApp";
 +    private BroadcastReceiver telephonyReceiver;
 +
 +    /**
 +     * Sets the context of the Command. This can then be used to do things like
 +     * get file paths associated with the Activity.
-      *
-      * @param cordova The context of the main Activity.
-      * @param webView The CordovaWebView Cordova is running in.
 +     */
-     public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-         super.initialize(cordova, webView);
++    @Override
++    public void initialize() {
 +        this.initTelephonyReceiver();
 +    }
 +
- 
 +    /**
 +     * Executes the request and returns PluginResult.
 +     *
 +     * @param action            The action to execute.
 +     * @param args              JSONArry of arguments for the plugin.
 +     * @param callbackContext   The callback context from which we were invoked.
 +     * @return                  A PluginResult object with a status and message.
 +     */
 +    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
 +        PluginResult.Status status = PluginResult.Status.OK;
 +        String result = "";
 +
 +        try {
 +            if (action.equals("clearCache")) {
 +                this.clearCache();
 +            }
 +            else if (action.equals("show")) {
 +                // This gets called from JavaScript onCordovaReady to show the webview.
 +                // I recommend we change the name of the Message as spinner/stop is not
 +                // indicative of what this actually does (shows the webview).
 +                cordova.getActivity().runOnUiThread(new Runnable() {
 +                    public void run() {
 +                        webView.postMessage("spinner", "stop");
 +                    }
 +                });
 +            }
 +            else if (action.equals("loadUrl")) {
 +                this.loadUrl(args.getString(0), args.optJSONObject(1));
 +            }
 +            else if (action.equals("cancelLoadUrl")) {
 +                //this.cancelLoadUrl();
 +            }
 +            else if (action.equals("clearHistory")) {
 +                this.clearHistory();
 +            }
 +            else if (action.equals("backHistory")) {
 +                this.backHistory();
 +            }
 +            else if (action.equals("overrideButton")) {
 +                this.overrideButton(args.getString(0), args.getBoolean(1));
 +            }
 +            else if (action.equals("overrideBackbutton")) {
 +                this.overrideBackbutton(args.getBoolean(0));
 +            }
 +            else if (action.equals("exitApp")) {
 +                this.exitApp();
 +            }
 +            callbackContext.sendPluginResult(new PluginResult(status, result));
 +            return true;
 +        } catch (JSONException e) {
 +            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
 +            return false;
 +        }
 +    }
 +
 +    //--------------------------------------------------------------------------
 +    // LOCAL METHODS
 +    //--------------------------------------------------------------------------
 +
 +    /**
 +     * Clear the resource cache.
 +     */
 +    public void clearCache() {
 +        cordova.getActivity().runOnUiThread(new Runnable() {
 +            public void run() {
 +                webView.clearCache(true);
 +            }
 +        });
 +    }
 +
 +    /**
 +     * Load the url into the webview.
 +     *
 +     * @param url
 +     * @param props			Properties that can be passed in to the Cordova activity (i.e. loadingDialog, wait, ...)
 +     * @throws JSONException
 +     */
 +    public void loadUrl(String url, JSONObject props) throws JSONException {
 +        LOG.d("App", "App.loadUrl("+url+","+props+")");
 +        int wait = 0;
 +        boolean openExternal = false;
 +        boolean clearHistory = false;
 +
 +        // If there are properties, then set them on the Activity
 +        HashMap<String, Object> params = new HashMap<String, Object>();
 +        if (props != null) {
 +            JSONArray keys = props.names();
 +            for (int i = 0; i < keys.length(); i++) {
 +                String key = keys.getString(i);
 +                if (key.equals("wait")) {
 +                    wait = props.getInt(key);
 +                }
 +                else if (key.equalsIgnoreCase("openexternal")) {
 +                    openExternal = props.getBoolean(key);
 +                }
 +                else if (key.equalsIgnoreCase("clearhistory")) {
 +                    clearHistory = props.getBoolean(key);
 +                }
 +                else {
 +                    Object value = props.get(key);
 +                    if (value == null) {
 +
 +                    }
 +                    else if (value.getClass().equals(String.class)) {
 +                        params.put(key, (String)value);
 +                    }
 +                    else if (value.getClass().equals(Boolean.class)) {
 +                        params.put(key, (Boolean)value);
 +                    }
 +                    else if (value.getClass().equals(Integer.class)) {
 +                        params.put(key, (Integer)value);
 +                    }
 +                }
 +            }
 +        }
 +
 +        // If wait property, then delay loading
 +
 +        if (wait > 0) {
 +            try {
 +                synchronized(this) {
 +                    this.wait(wait);
 +                }
 +            } catch (InterruptedException e) {
 +                e.printStackTrace();
 +            }
 +        }
 +        this.webView.showWebPage(url, openExternal, clearHistory, params);
 +    }
 +
 +    /**
 +     * Clear page history for the app.
 +     */
 +    public void clearHistory() {
 +        cordova.getActivity().runOnUiThread(new Runnable() {
 +            public void run() {
 +                webView.clearHistory();
 +            }
 +        });
 +    }
 +
 +    /**
 +     * Go to previous page displayed.
 +     * This is the same as pressing the backbutton on Android device.
 +     */
 +    public void backHistory() {
 +        cordova.getActivity().runOnUiThread(new Runnable() {
 +            public void run() {
 +                webView.backHistory();
 +            }
 +        });
 +    }
 +
 +    /**
 +     * Override the default behavior of the Android back button.
 +     * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
 +     *
 +     * @param override		T=override, F=cancel override
 +     */
 +    public void overrideBackbutton(boolean override) {
 +        LOG.i("App", "WARNING: Back Button Default Behavior will be overridden.  The backbutton event will be fired!");
 +        webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_BACK, override);
 +    }
 +
 +    /**
 +     * Override the default behavior of the Android volume buttons.
 +     * If overridden, when the volume button is pressed, the "volume[up|down]button" JavaScript event will be fired.
 +     *
 +     * @param button        volumeup, volumedown
 +     * @param override      T=override, F=cancel override
 +     */
 +    public void overrideButton(String button, boolean override) {
 +        LOG.i("App", "WARNING: Volume Button Default Behavior will be overridden.  The volume event will be fired!");
 +        if (button.equals("volumeup")) {
 +            webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_UP, override);
 +        }
 +        else if (button.equals("volumedown")) {
 +            webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_DOWN, override);
 +        }
 +    }
 +
 +    /**
 +     * Return whether the Android back button is overridden by the user.
 +     *
 +     * @return boolean
 +     */
 +    public boolean isBackbuttonOverridden() {
 +        return webView.isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK);
 +    }
 +
 +    /**
 +     * Exit the Android application.
 +     */
 +    public void exitApp() {
 +        this.webView.postMessage("exit", null);
 +    }
 +    
 +
 +    /**
 +     * Listen for telephony events: RINGING, OFFHOOK and IDLE
 +     * Send these events to all plugins using
 +     *      CordovaActivity.onMessage("telephone", "ringing" | "offhook" | "idle")
 +     */
 +    private void initTelephonyReceiver() {
 +        IntentFilter intentFilter = new IntentFilter();
 +        intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
 +        //final CordovaInterface mycordova = this.cordova;
 +        this.telephonyReceiver = new BroadcastReceiver() {
 +
 +            @Override
 +            public void onReceive(Context context, Intent intent) {
 +
 +                // If state has changed
 +                if ((intent != null) && intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
 +                    if (intent.hasExtra(TelephonyManager.EXTRA_STATE)) {
 +                        String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
 +                        if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
 +                            LOG.i(TAG, "Telephone RINGING");
 +                            webView.postMessage("telephone", "ringing");
 +                        }
 +                        else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
 +                            LOG.i(TAG, "Telephone OFFHOOK");
 +                            webView.postMessage("telephone", "offhook");
 +                        }
 +                        else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
 +                            LOG.i(TAG, "Telephone IDLE");
 +                            webView.postMessage("telephone", "idle");
 +                        }
 +                    }
 +                }
 +            }
 +        };
 +
 +        // Register the receiver
 +        this.cordova.getActivity().registerReceiver(this.telephonyReceiver, intentFilter);
 +    }
 +
 +    /*
 +     * Unregister the receiver
 +     *
 +     */
 +    public void onDestroy()
 +    {
 +        this.cordova.getActivity().unregisterReceiver(this.telephonyReceiver);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/PluginEntry.java
----------------------------------------------------------------------


[9/9] android commit: Delete deprecated methods from PluginManager

Posted by ag...@apache.org.
Delete deprecated methods from PluginManager


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/25a7b662
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/25a7b662
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/25a7b662

Branch: refs/heads/4.0.x
Commit: 25a7b6629632f7b0b0270a733b9551eaf64d429a
Parents: ac194cd
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:46:05 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:46:05 2014 -0400

----------------------------------------------------------------------
 framework/src/org/apache/cordova/PluginManager.java | 9 ---------
 1 file changed, 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/25a7b662/framework/src/org/apache/cordova/PluginManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java
index 5770738..9a28361 100755
--- a/framework/src/org/apache/cordova/PluginManager.java
+++ b/framework/src/org/apache/cordova/PluginManager.java
@@ -84,10 +84,6 @@ public class PluginManager {
         this.startupPlugins();
     }
 
-    @Deprecated
-    public void loadPlugins() {
-    }
-
     /**
      * Delete all plugin objects.
      */
@@ -157,11 +153,6 @@ public class PluginManager {
         }
     }
 
-    @Deprecated
-    public void exec(String service, String action, String callbackId, String jsonArgs, boolean async) {
-        exec(service, action, callbackId, jsonArgs);
-    }
-
     /**
      * Get the plugin object that implements the service.
      * If the plugin object does not already exist, then create it.


[8/9] android commit: Merge branch 'master' into 4.0.x (remove Config.* references)

Posted by ag...@apache.org.
Merge branch 'master' into 4.0.x (remove Config.* references)

Conflicts:
	framework/src/org/apache/cordova/CordovaActivity.java
	framework/src/org/apache/cordova/CordovaChromeClient.java
	framework/src/org/apache/cordova/CordovaWebView.java


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/ac194cd3
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/ac194cd3
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/ac194cd3

Branch: refs/heads/4.0.x
Commit: ac194cd34fd7f3d2e504d39f4f51d5f25d89bcd6
Parents: eca05e6 04ccb06
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:45:41 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:45:41 2014 -0400

----------------------------------------------------------------------
 .../org/apache/cordova/AndroidChromeClient.java |  3 +-
 .../src/org/apache/cordova/AndroidWebView.java  | 42 ++++++++++----------
 framework/src/org/apache/cordova/Config.java    |  5 +++
 .../src/org/apache/cordova/CordovaActivity.java |  9 +++--
 .../src/org/apache/cordova/CordovaPlugin.java   | 23 +++++++----
 .../org/apache/cordova/CordovaUriHelper.java    |  2 +-
 .../src/org/apache/cordova/CordovaWebView.java  |  7 +++-
 .../src/org/apache/cordova/CoreAndroid.java     |  8 +---
 .../cordova/IceCreamCordovaWebViewClient.java   |  2 +-
 .../src/org/apache/cordova/PluginEntry.java     |  2 +-
 10 files changed, 58 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/AndroidChromeClient.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/AndroidChromeClient.java
index 73e9724,0000000..a683ec6
mode 100755,000000..100755
--- a/framework/src/org/apache/cordova/AndroidChromeClient.java
+++ b/framework/src/org/apache/cordova/AndroidChromeClient.java
@@@ -1,383 -1,0 +1,382 @@@
 +/*
 +       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.CordovaInterface;
 +import org.apache.cordova.LOG;
 +import org.json.JSONArray;
 +import org.json.JSONException;
 +
 +import android.annotation.TargetApi;
 +import android.app.AlertDialog;
 +import android.content.DialogInterface;
 +import android.content.Intent;
 +import android.net.Uri;
 +import android.view.Gravity;
 +import android.view.KeyEvent;
 +import android.view.View;
 +import android.view.ViewGroup.LayoutParams;
 +import android.webkit.ConsoleMessage;
 +import android.webkit.JsPromptResult;
 +import android.webkit.JsResult;
 +import android.webkit.ValueCallback;
 +import android.webkit.WebChromeClient;
 +import android.webkit.WebStorage;
 +import android.webkit.WebView;
 +import android.webkit.GeolocationPermissions.Callback;
 +import android.widget.EditText;
 +import android.widget.LinearLayout;
 +import android.widget.ProgressBar;
 +import android.widget.RelativeLayout;
 +import android.util.Log;
 +
 +/**
 + * This class is the WebChromeClient that implements callbacks for our web view.
 + * The kind of callbacks that happen here are on the chrome outside the document,
 + * such as onCreateWindow(), onConsoleMessage(), onProgressChanged(), etc. Related
 + * to but different than CordovaWebViewClient.
 + *
 + * @see <a href="http://developer.android.com/reference/android/webkit/WebChromeClient.html">WebChromeClient</a>
 + * @see <a href="http://developer.android.com/guide/webapps/webview.html">WebView guide</a>
 + * @see CordovaWebViewClient
 + * @see CordovaWebView
 + */
 +public class AndroidChromeClient extends WebChromeClient implements CordovaChromeClient {
 +
 +    public static final int FILECHOOSER_RESULTCODE = 5173;
 +    private static final String LOG_TAG = "AndroidChromeClient";
 +    private long MAX_QUOTA = 100 * 1024 * 1024;
 +    protected final CordovaInterface cordova;
 +    protected final AndroidWebView appView;
 +
 +    // the video progress view
 +    private View mVideoProgressView;
 +    
 +    // File Chooser
 +    public ValueCallback<Uri> mUploadMessage;
 +    
 +    public AndroidChromeClient(CordovaInterface ctx, AndroidWebView app) {
 +        this.cordova = ctx;
 +        this.appView = app;
 +    }
 +
 +    /**
 +     * Tell the client to display a javascript alert dialog.
 +     *
 +     * @param view
 +     * @param url
 +     * @param message
 +     * @param result
 +     * @see Other implementation in the Dialogs plugin.
 +     */
 +    @Override
 +    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
 +        AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
 +        dlg.setMessage(message);
 +        dlg.setTitle("Alert");
 +        //Don't let alerts break the back button
 +        dlg.setCancelable(true);
 +        dlg.setPositiveButton(android.R.string.ok,
 +                new AlertDialog.OnClickListener() {
 +                    public void onClick(DialogInterface dialog, int which) {
 +                        result.confirm();
 +                    }
 +                });
 +        dlg.setOnCancelListener(
 +                new DialogInterface.OnCancelListener() {
 +                    public void onCancel(DialogInterface dialog) {
 +                        result.cancel();
 +                    }
 +                });
 +        dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
 +            //DO NOTHING
 +            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
 +                if (keyCode == KeyEvent.KEYCODE_BACK)
 +                {
 +                    result.confirm();
 +                    return false;
 +                }
 +                else
 +                    return true;
 +            }
 +        });
 +        dlg.show();
 +        return true;
 +    }
 +
 +    /**
 +     * Tell the client to display a confirm dialog to the user.
 +     *
 +     * @param view
 +     * @param url
 +     * @param message
 +     * @param result
 +     * @see Other implementation in the Dialogs plugin.
 +     */
 +    @Override
 +    public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
 +        AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
 +        dlg.setMessage(message);
 +        dlg.setTitle("Confirm");
 +        dlg.setCancelable(true);
 +        dlg.setPositiveButton(android.R.string.ok,
 +                new DialogInterface.OnClickListener() {
 +                    public void onClick(DialogInterface dialog, int which) {
 +                        result.confirm();
 +                    }
 +                });
 +        dlg.setNegativeButton(android.R.string.cancel,
 +                new DialogInterface.OnClickListener() {
 +                    public void onClick(DialogInterface dialog, int which) {
 +                        result.cancel();
 +                    }
 +                });
 +        dlg.setOnCancelListener(
 +                new DialogInterface.OnCancelListener() {
 +                    public void onCancel(DialogInterface dialog) {
 +                        result.cancel();
 +                    }
 +                });
 +        dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
 +            //DO NOTHING
 +            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
 +                if (keyCode == KeyEvent.KEYCODE_BACK)
 +                {
 +                    result.cancel();
 +                    return false;
 +                }
 +                else
 +                    return true;
 +            }
 +        });
 +        dlg.show();
 +        return true;
 +    }
 +
 +    /**
 +     * Tell the client to display a prompt dialog to the user.
 +     * If the client returns true, WebView will assume that the client will
 +     * handle the prompt dialog and call the appropriate JsPromptResult method.
 +     *
 +     * Since we are hacking prompts for our own purposes, we should not be using them for
 +     * this purpose, perhaps we should hack console.log to do this instead!
 +     *
 +     * @see Other implementation in the Dialogs plugin.
 +     */
 +    @Override
 +    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.
 +        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 = 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:")) {
-             String startUrl = Config.getStartUrl();
 +            // 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") && startUrl.startsWith(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 {
 +            // Returning false would also show a dialog, but the default one shows the origin (ugly).
 +            final JsPromptResult res = result;
 +            AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
 +            dlg.setMessage(message);
 +            final EditText input = new EditText(this.cordova.getActivity());
 +            if (defaultValue != null) {
 +                input.setText(defaultValue);
 +            }
 +            dlg.setView(input);
 +            dlg.setCancelable(false);
 +            dlg.setPositiveButton(android.R.string.ok,
 +                    new DialogInterface.OnClickListener() {
 +                        public void onClick(DialogInterface dialog, int which) {
 +                            String usertext = input.getText().toString();
 +                            res.confirm(usertext);
 +                        }
 +                    });
 +            dlg.setNegativeButton(android.R.string.cancel,
 +                    new DialogInterface.OnClickListener() {
 +                        public void onClick(DialogInterface dialog, int which) {
 +                            res.cancel();
 +                        }
 +                    });
 +            dlg.show();
 +        }
 +        return true;
 +    }
 +
 +    /**
 +     * Handle database quota exceeded notification.
 +     */
 +    @Override
 +    public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
 +            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
 +    {
 +        LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d  currentQuota: %d  totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
 +        quotaUpdater.updateQuota(MAX_QUOTA);
 +    }
 +
 +    // console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
 +    // Expect this to not compile in a future Android release!
 +    @SuppressWarnings("deprecation")
 +    @Override
 +    public void onConsoleMessage(String message, int lineNumber, String sourceID)
 +    {
 +        //This is only for Android 2.1
 +        if(android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.ECLAIR_MR1)
 +        {
 +            LOG.d(LOG_TAG, "%s: Line %d : %s", sourceID, lineNumber, message);
 +            super.onConsoleMessage(message, lineNumber, sourceID);
 +        }
 +    }
 +
 +    @TargetApi(8)
 +    @Override
 +    public boolean onConsoleMessage(ConsoleMessage consoleMessage)
 +    {
 +        if (consoleMessage.message() != null)
 +            LOG.d(LOG_TAG, "%s: Line %d : %s" , consoleMessage.sourceId() , consoleMessage.lineNumber(), consoleMessage.message());
 +         return super.onConsoleMessage(consoleMessage);
 +    }
 +
 +    @Override
 +    /**
 +     * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
 +     *
 +     * @param origin
 +     * @param callback
 +     */
 +    public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
 +        super.onGeolocationPermissionsShowPrompt(origin, callback);
 +        callback.invoke(origin, true, false);
 +    }
 +    
 +    // API level 7 is required for this, see if we could lower this using something else
 +    @Override
 +    public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
 +        this.appView.showCustomView(view, callback);
 +    }
 +
 +    @Override
 +    public void onHideCustomView() {
 +        this.appView.hideCustomView();
 +    }
 +    
 +    @Override
 +    /**
 +     * Ask the host application for a custom progress view to show while
 +     * a <video> is loading.
 +     * @return View The progress view.
 +     */
 +    public View getVideoLoadingProgressView() {
 +
 +        if (mVideoProgressView == null) {            
 +            // Create a new Loading view programmatically.
 +            
 +            // create the linear layout
 +            LinearLayout layout = new LinearLayout(this.appView.getContext());
 +            layout.setOrientation(LinearLayout.VERTICAL);
 +            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
 +            layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
 +            layout.setLayoutParams(layoutParams);
 +            // the proress bar
 +            ProgressBar bar = new ProgressBar(this.appView.getContext());
 +            LinearLayout.LayoutParams barLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
 +            barLayoutParams.gravity = Gravity.CENTER;
 +            bar.setLayoutParams(barLayoutParams);   
 +            layout.addView(bar);
 +            
 +            mVideoProgressView = layout;
 +        }
 +    return mVideoProgressView; 
 +    }
 +    
 +    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
 +        this.openFileChooser(uploadMsg, "*/*");
 +    }
 +    
 +    public void openFileChooser( ValueCallback<Uri> uploadMsg, String acceptType ) {
 +        this.openFileChooser(uploadMsg, acceptType, null);
 +    }
 +    
 +    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
 +    {
 +        mUploadMessage = uploadMsg;
 +        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
 +        i.addCategory(Intent.CATEGORY_OPENABLE);
 +        i.setType("*/*");
 +        this.cordova.getActivity().startActivityForResult(Intent.createChooser(i, "File Browser"),
 +                FILECHOOSER_RESULTCODE);
 +    }
 +    
 +    public ValueCallback<Uri> getValueCallback() {
 +        return this.mUploadMessage;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/AndroidWebView.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/AndroidWebView.java
index c8c3c90,0000000..8499caf
mode 100755,000000..100755
--- a/framework/src/org/apache/cordova/AndroidWebView.java
+++ b/framework/src/org/apache/cordova/AndroidWebView.java
@@@ -1,930 -1,0 +1,930 @@@
 +/*
 +       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.HashMap;
 +import java.util.HashSet;
 +import java.util.List;
 +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 android.annotation.SuppressLint;
 +import android.annotation.TargetApi;
 +import android.content.BroadcastReceiver;
 +import android.content.Context;
 +import android.content.Intent;
 +import android.content.IntentFilter;
 +import android.content.pm.ApplicationInfo;
 +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.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 static final String TAG = "AndroidWebView";
 +
 +    private HashSet<Integer> boundKeyCodes = new HashSet<Integer>();
 +
 +    PluginManager pluginManager;
 +    private boolean paused;
 +
 +    private BroadcastReceiver receiver;
 +
 +
 +    /** 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 long lastMenuEventTime = 0;
 +
 +    NativeToJsMessageQueue jsMessageQueue;
 +    AndroidExposedJsApi 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;
- 
++    private Whitelist whitelist;
++    private CordovaPreferences preferences;
++    // The URL passed to loadUrl(), not necessarily the URL of the current page.
++    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 =
 +            new FrameLayout.LayoutParams(
 +            ViewGroup.LayoutParams.MATCH_PARENT,
 +            ViewGroup.LayoutParams.MATCH_PARENT,
 +            Gravity.CENTER);
 +    
 +    /** Used when created via reflection. */
 +    public AndroidWebView(Context context) {
 +        this(context, null);
 +    }
 +
 +    /** Required to allow view to be used within XML layouts. */
 +    public AndroidWebView(Context context, AttributeSet attrs) {
 +        super(context, attrs);
 +    }
 +
 +    // Use two-phase init so that the control will work with XML layouts.
 +    @Override
-     public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient, List<PluginEntry> pluginEntries) {
++    public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
++                     List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) {
 +        if (this.cordova != null) {
 +            throw new IllegalStateException();
 +        }
 +        this.cordova = cordova;
 +        setWebChromeClient(webChromeClient);
 +        setWebViewClient(webViewClient);
++        this.whitelist = whitelist;
++        this.preferences = preferences;
 +
 +        pluginManager = new PluginManager(this, this.cordova, pluginEntries);
 +        jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
 +        exposedJsApi = new AndroidExposedJsApi(pluginManager, jsMessageQueue);
 +        resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
 +
 +        pluginManager.addService("App", "org.apache.cordova.CoreAndroid");
 +        initWebViewSettings();
 +        exposeJsInterface();
 +    }
 +
 +    @SuppressLint("SetJavaScriptEnabled")
 +    @SuppressWarnings("deprecation")
 +    private void initWebViewSettings() {
 +        this.setInitialScale(0);
 +        this.setVerticalScrollBarEnabled(false);
 +        // TODO: The Activity is the one that should call requestFocus().
 +        if (shouldRequestFocusOnInit()) {
 +            this.requestFocusFromTouch();
 +        }
 +        this.setInitialScale(0);
 +        this.setVerticalScrollBarEnabled(false);
 +        if (shouldRequestFocusOnInit()) {
 +            this.requestFocusFromTouch();
 +        }
 +        // Enable JavaScript
 +        final WebSettings settings = this.getSettings();
 +        settings.setJavaScriptEnabled(true);
 +        settings.setJavaScriptCanOpenWindowsAutomatically(true);
 +        settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
 +        
 +        // Set the nav dump for HTC 2.x devices (disabling for ICS, deprecated entirely for Jellybean 4.2)
 +        try {
 +            Method gingerbread_getMethod =  WebSettings.class.getMethod("setNavDump", new Class[] { boolean.class });
 +            
 +            String manufacturer = android.os.Build.MANUFACTURER;
 +            Log.d(TAG, "CordovaWebView is running on device made by: " + manufacturer);
 +            if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB &&
 +                    android.os.Build.MANUFACTURER.contains("HTC"))
 +            {
 +                gingerbread_getMethod.invoke(settings, true);
 +            }
 +        } catch (NoSuchMethodException e) {
 +            Log.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8");
 +        } catch (IllegalArgumentException e) {
 +            Log.d(TAG, "Doing the NavDump failed with bad arguments");
 +        } catch (IllegalAccessException e) {
 +            Log.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore");
 +        } catch (InvocationTargetException e) {
 +            Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore.");
 +        }
 +
 +        //We don't save any form data in the application
 +        settings.setSaveFormData(false);
 +        settings.setSavePassword(false);
 +        
 +        // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
 +        // while we do this
 +        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
 +            Level16Apis.enableUniversalAccess(settings);
 +        // Enable database
 +        // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
 +        String databasePath = getContext().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!
 +        ApplicationInfo appInfo = getContext().getApplicationContext().getApplicationInfo();
 +        if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 &&
 +            android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
 +            enableRemoteDebugging();
 +        }
 +        
 +        settings.setGeolocationDatabasePath(databasePath);
 +
 +        // Enable DOM storage
 +        settings.setDomStorageEnabled(true);
 +
 +        // Enable built-in geolocation
 +        settings.setGeolocationEnabled(true);
 +        
 +        // Enable AppCache
 +        // Fix for CB-2282
 +        settings.setAppCacheMaxSize(5 * 1048576);
 +        settings.setAppCachePath(databasePath);
 +        settings.setAppCacheEnabled(true);
 +        
 +        // Fix for CB-1405
 +        // Google issue 4641
 +        settings.getUserAgentString();
 +        
 +        IntentFilter intentFilter = new IntentFilter();
 +        intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
 +        if (this.receiver == null) {
 +            this.receiver = new BroadcastReceiver() {
 +                @Override
 +                public void onReceive(Context context, Intent intent) {
 +                    settings.getUserAgentString();
 +                }
 +            };
 +            getContext().registerReceiver(this.receiver, intentFilter);
 +        }
 +        // end CB-1405
 +    }
 +
 +    @TargetApi(Build.VERSION_CODES.KITKAT)
 +    private void enableRemoteDebugging() {
 +        try {
 +            WebView.setWebContentsDebuggingEnabled(true);
 +        } catch (IllegalArgumentException e) {
 +            Log.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! ");
 +            e.printStackTrace();
 +        }
 +    }
 +
 +    @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
 +	 * focus when your application start
 +	 * 
 +	 * @return true unless this method is overriden to return a different value
 +	 */
 +    protected boolean shouldRequestFocusOnInit() {
 +		return true;
 +	}
 +
 +    private void exposeJsInterface() {
 +        if ((Build.VERSION.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");
 +    }
 +
 +    @Override
 +    public void setWebViewClient(WebViewClient client) {
 +        this.viewClient = (CordovaWebViewClient)client;
 +        super.setWebViewClient(client);
 +    }
 +
 +    @Override
 +    public void setWebChromeClient(WebChromeClient client) {
 +        this.chromeClient = (CordovaChromeClient)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.
 +     *
 +     * @param url
 +     */
 +    @Override
 +    public void loadUrl(String url) {
 +        if (url.equals("about:blank") || url.startsWith("javascript:")) {
 +            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.
 +     *
 +     * @param url
 +     */
 +    public void loadUrlIntoView(final String url, boolean recreatePlugins) {
 +        LOG.d(TAG, ">>> loadUrl(" + url + ")");
 +
 +        if (recreatePlugins) {
-             this.url = url;
++            this.loadedUrl = 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"));
 +
 +        // Timeout error method
 +        final Runnable loadError = new Runnable() {
 +            public void run() {
 +                me.stopLoading();
 +                LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
 +                if (viewClient != null) {
 +                    viewClient.onReceivedError(-6, "The connection to the server was unsuccessful.", url);
 +                }
 +            }
 +        };
 +
 +        // Timeout timer method
 +        final Runnable timeoutCheck = new Runnable() {
 +            public void run() {
 +                try {
 +                    synchronized (this) {
 +                        wait(loadUrlTimeoutValue);
 +                    }
 +                } catch (InterruptedException e) {
 +                    e.printStackTrace();
 +                }
 +
 +                // If timeout, then stop loading and handle error
 +                if (me.loadUrlTimeout == currentLoadUrlTimeout) {
 +                    me.cordova.getActivity().runOnUiThread(loadError);
 +                }
 +            }
 +        };
 +
 +        // Load url
 +        this.cordova.getActivity().runOnUiThread(new Runnable() {
 +            public void run() {
 +                cordova.getThreadPool().execute(timeoutCheck);
 +                me.loadUrlNow(url);
 +            }
 +        });
 +    }
 +
 +    /**
 +     * Load URL in webview.
 +     *
 +     * @param url
 +     */
 +    public void loadUrlNow(String url) {
 +        if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
 +            LOG.d(TAG, ">>> loadUrlNow()");
 +        }
-         if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
++        if (url.startsWith("file://") || url.startsWith("javascript:") || whitelist.isUrlWhiteListed(url)) {
 +            super.loadUrl(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
 +     */
 +    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();
 +    }
 +    
 +    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);
 +    }
 +    
 +    /**
 +     * 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)
 +     *
 +     * @return true if we went back, false if we are already at top
 +     */
 +    public boolean backHistory() {
 +
 +        // Check webview first to see if there is a history
 +        // This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
 +        if (super.canGoBack()) {
 +            printBackForwardList();
 +            super.goBack();
 +            
 +            return true;
 +        }
 +        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
 +     */
 +    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)) {
++            if (url.startsWith("file://") || whitelist.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);
 +        }
 +    }
 +
 +    /**
 +     * 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)
 +    {
 +        if(boundKeyCodes.contains(keyCode))
 +        {
 +            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
 +                    this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');");
 +                    return true;
 +            }
 +            else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
 +                    this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');");
 +                    return true;
 +            }
 +            else
 +            {
 +                return super.onKeyDown(keyCode, event);
 +            }
 +        }
 +        else if(keyCode == KeyEvent.KEYCODE_BACK)
 +        {
 +            return !(this.startOfHistory()) || isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK);
 +
 +        }
 +        else if(keyCode == KeyEvent.KEYCODE_MENU)
 +        {
 +            //How did we get here?  Is there a childView?
 +            View childView = this.getFocusedChild();
 +            if(childView != null)
 +            {
 +                //Make sure we close the keyboard if it's present
 +                InputMethodManager imm = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
 +                imm.hideSoftInputFromWindow(childView.getWindowToken(), 0);
 +                cordova.getActivity().openOptionsMenu();
 +                return true;
 +            } else {
 +                return super.onKeyDown(keyCode, event);
 +            }
 +        }
 +        return super.onKeyDown(keyCode, event);
 +    }
 +
 +    @Override
 +    public boolean onKeyUp(int keyCode, KeyEvent event)
 +    {
 +        // If back key
 +        if (keyCode == KeyEvent.KEYCODE_BACK) {
 +            // A custom view is currently displayed  (e.g. playing a video)
 +            if(mCustomView != null) {
 +                this.hideCustomView();
 +                return true;
 +            } else {
 +                // The webview is currently displayed
 +                // If back key is bound, then send event to JavaScript
 +                if (isButtonPlumbedToJs(KeyEvent.KEYCODE_BACK)) {
 +                    this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');");
 +                    return true;
 +                } else {
 +                    // If not bound
 +                    // Go to previous page in webview if it is possible to go back
 +                    if (this.backHistory()) {
 +                        return true;
 +                    }
 +                    // If not, then invoke default behavior
 +                }
 +            }
 +        }
 +        // Legacy
 +        else if (keyCode == KeyEvent.KEYCODE_MENU) {
 +            if (this.lastMenuEventTime < event.getEventTime()) {
 +                this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');");
 +            }
 +            this.lastMenuEventTime = event.getEventTime();
 +            return super.onKeyUp(keyCode, event);
 +        }
 +        // If search key
 +        else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
 +            this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');");
 +            return true;
 +        }
 +
 +        //Does webkit change this behavior?
 +        return super.onKeyUp(keyCode, event);
 +    }
 +
 +    @Override
 +    public void setButtonPlumbedToJs(int keyCode, boolean value) {
 +        switch (keyCode) {
 +            case KeyEvent.KEYCODE_VOLUME_DOWN:
 +            case KeyEvent.KEYCODE_VOLUME_UP:
 +            case KeyEvent.KEYCODE_BACK:
 +                // TODO: Why are search and menu buttons handled separately?
 +                boundKeyCodes.add(keyCode);
 +                return;
 +            default:
 +                throw new IllegalArgumentException("Unsupported keycode: " + keyCode);
 +        }
 +    }
 +
 +    @Override
 +    public boolean isButtonPlumbedToJs(int keyCode)
 +    {
 +        return boundKeyCodes.contains(keyCode);
 +    }
 +
 +    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 {
 +                getContext().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;
 +    }
 +
 +    // 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)
 +    private static class Level16Apis {
 +        static void enableUniversalAccess(WebSettings settings) {
 +            settings.setAllowUniversalAccessFromFileURLs(true);
 +        }
 +    }
 +    
 +    public void printBackForwardList() {
 +        WebBackForwardList currentList = this.copyBackForwardList();
 +        int currentSize = currentList.getSize();
 +        for(int i = 0; i < currentSize; ++i)
 +        {
 +            WebHistoryItem item = currentList.getItemAtIndex(i);
 +            String url = item.getUrl();
 +            LOG.d(TAG, "The URL at index: " + Integer.toString(i) + " is " + url );
 +        }
 +    }
 +    
 +    
 +    //Can Go Back is BROKEN!
 +    public boolean startOfHistory()
 +    {
 +        WebBackForwardList currentList = this.copyBackForwardList();
 +        WebHistoryItem item = currentList.getItemAtIndex(0);
 +        if( item!=null){	// Null-fence in case they haven't called loadUrl yet (CB-2458)
 +	        String url = item.getUrl();
 +	        String currentUrl = this.getUrl();
 +	        LOG.d(TAG, "The current URL is: " + currentUrl);
 +	        LOG.d(TAG, "The URL at item 0 is: " + url);
 +	        return currentUrl.equals(url);
 +        }
 +        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;
 +    }
 +    
 +    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();
 +        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 boolean onOverrideUrlLoading(String url) {
 +        return this.pluginManager.onOverrideUrlLoading(url);
 +    }
 +
 +    void onPageReset() {
 +        boundKeyCodes.clear();
 +        pluginManager.onReset();
 +        jsMessageQueue.reset();
 +        exposedJsApi.clearBridgeSecret();
 +    }
 +
 +    @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;
 +    }
 +
- 
++    @Override
++    public Whitelist getWhitelist() {
++        return this.whitelist;
++    }
++    
++    @Override
++    public CordovaPreferences getPreferences() {
++        return preferences;
++    }
 +}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/CordovaActivity.java
index 059a552,371172c..dbb6fee
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@@ -581,8 -787,8 +582,7 @@@ public class CordovaActivity extends Ac
  
          // If errorUrl specified, then load it
          final String errorUrl = preferences.getString("errorUrl", null);
-         if ((errorUrl != null) && (errorUrl.startsWith("file://") || Config.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
- 
+         if ((errorUrl != null) && (errorUrl.startsWith("file://") || whitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
 -
              // Load URL on UI thread
              me.runOnUiThread(new Runnable() {
                  public void run() {

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/CordovaPlugin.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/CordovaPlugin.java
index 8111e7b,eff66c8..2e7a932
--- a/framework/src/org/apache/cordova/CordovaPlugin.java
+++ b/framework/src/org/apache/cordova/CordovaPlugin.java
@@@ -32,15 -32,13 +32,11 @@@ import android.net.Uri
   * Plugins must extend this class and override one of the execute methods.
   */
  public class CordovaPlugin {
-     public String id;
-     public CordovaWebView webView;					// WebView object
 -    @Deprecated // This is never set.
 -    public String id;
 -    public CordovaWebView webView;					// WebView object
++    public CordovaWebView webView;
      public CordovaInterface cordova;
+     protected CordovaPreferences preferences;
  
-     /**
-      * @param cordova The context of the main Activity.
-      * @param webView The associated CordovaWebView.
-      */
-     public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+     void privateInitialize(CordovaInterface cordova, CordovaWebView webView, CordovaPreferences preferences) {
          assert this.cordova == null;
          this.cordova = cordova;
          this.webView = webView;

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ac194cd3/framework/src/org/apache/cordova/CordovaUriHelper.java
----------------------------------------------------------------------


[5/9] android commit: Provide CordovaPlugin with CordovaPreferences. Add new Plugin.initialize()

Posted by ag...@apache.org.
Provide CordovaPlugin with CordovaPreferences. Add new Plugin.initialize()

This adds CordovaPlugin.initialize() (no args) and deprecates
CordovaPlugin.initialize(app, webView). This will allow us to refactor
more easily by using the package-private privateInitialize() to set
fields.


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/04ccb06e
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/04ccb06e
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/04ccb06e

Branch: refs/heads/master
Commit: 04ccb06e3f6297f3956d847507423c66006eae08
Parents: d31ee20
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:26:21 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:26:21 2014 -0400

----------------------------------------------------------------------
 framework/src/org/apache/cordova/App.java       |  8 ++------
 .../src/org/apache/cordova/CordovaActivity.java |  3 ++-
 .../src/org/apache/cordova/CordovaPlugin.java   | 21 +++++++++++++++-----
 .../src/org/apache/cordova/CordovaWebView.java  |  8 +++++++-
 .../src/org/apache/cordova/PluginEntry.java     |  2 +-
 5 files changed, 28 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/App.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/App.java b/framework/src/org/apache/cordova/App.java
index 2112519..c488f10 100755
--- a/framework/src/org/apache/cordova/App.java
+++ b/framework/src/org/apache/cordova/App.java
@@ -47,16 +47,12 @@ public class App extends CordovaPlugin {
     /**
      * Sets the context of the Command. This can then be used to do things like
      * get file paths associated with the Activity.
-     *
-     * @param cordova The context of the main Activity.
-     * @param webView The CordovaWebView Cordova is running in.
      */
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-        super.initialize(cordova, webView);
+    @Override
+    public void initialize() {
         this.initTelephonyReceiver();
     }
 
-
     /**
      * Executes the request and returns PluginResult.
      *

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index 0d07957..371172c 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -227,7 +227,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         }
 
         appView = makeWebView();
-        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist);
+        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist, preferences);
 
         // TODO: Have the views set this themselves.
         if (preferences.getBoolean("DisallowOverscroll", false)) {
@@ -240,6 +240,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         setVolumeControlStream(AudioManager.STREAM_MUSIC);
     }
 
+    @SuppressWarnings("deprecation")
     protected void loadConfig() {
         ConfigXmlParser parser = new ConfigXmlParser();
         parser.parse(this);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/CordovaPlugin.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java b/framework/src/org/apache/cordova/CordovaPlugin.java
index 8111e7b..eff66c8 100644
--- a/framework/src/org/apache/cordova/CordovaPlugin.java
+++ b/framework/src/org/apache/cordova/CordovaPlugin.java
@@ -32,21 +32,32 @@ import android.net.Uri;
  * Plugins must extend this class and override one of the execute methods.
  */
 public class CordovaPlugin {
+    @Deprecated // This is never set.
     public String id;
     public CordovaWebView webView;					// WebView object
     public CordovaInterface cordova;
+    protected CordovaPreferences preferences;
 
-    /**
-     * @param cordova The context of the main Activity.
-     * @param webView The associated CordovaWebView.
-     */
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+    void privateInitialize(CordovaInterface cordova, CordovaWebView webView, CordovaPreferences preferences) {
         assert this.cordova == null;
         this.cordova = cordova;
         this.webView = webView;
+        this.preferences = preferences;
+        initialize(cordova, webView);
+        initialize();
+    }
+
+    @Deprecated // Override initialize() instead.
+    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
     }
 
     /**
+     * This is where you can do start-up logic with protected fields set.
+     */
+    protected void initialize() {
+    }
+    
+    /**
      * Executes the request.
      *
      * This method is called from the WebView thread. To do a non-trivial amount of work, use:

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index fb442cc..7c1974c 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -92,6 +92,7 @@ public class CordovaWebView extends WebView {
     private Whitelist whitelist;
     // The URL passed to loadUrl(), not necessarily the URL of the current page.
     String loadedUrl;
+    private CordovaPreferences preferences;
 
     class ActivityResult {
         
@@ -135,7 +136,7 @@ public class CordovaWebView extends WebView {
 
     // Use two-phase init so that the control will work with XML layouts.
     public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
-            List<PluginEntry> pluginEntries, Whitelist whitelist) {
+            List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) {
         if (this.cordova != null) {
             throw new IllegalStateException();
         }
@@ -143,6 +144,7 @@ public class CordovaWebView extends WebView {
         this.viewClient = webViewClient;
         this.chromeClient = webChromeClient;
         this.whitelist = whitelist;
+        this.preferences = preferences;
         super.setWebChromeClient(webChromeClient);
         super.setWebViewClient(webViewClient);
 
@@ -903,4 +905,8 @@ public class CordovaWebView extends WebView {
     public CordovaResourceApi getResourceApi() {
         return resourceApi;
     }
+
+    public CordovaPreferences getPreferences() {
+        return preferences;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ccb06e/framework/src/org/apache/cordova/PluginEntry.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginEntry.java b/framework/src/org/apache/cordova/PluginEntry.java
index c54f6cb..e94cf1c 100755
--- a/framework/src/org/apache/cordova/PluginEntry.java
+++ b/framework/src/org/apache/cordova/PluginEntry.java
@@ -98,7 +98,7 @@ public class PluginEntry {
             Class<?> c = getClassByName(this.pluginClass);
             if (isCordovaPlugin(c)) {
                 this.plugin = (CordovaPlugin) c.newInstance();
-                this.plugin.initialize(ctx, webView);
+                this.plugin.privateInitialize(ctx, webView, webView.getPreferences());
                 return plugin;
             }
         } catch (Exception e) {


[3/9] android commit: Convert usages of Config.* to use the non-static versions

Posted by ag...@apache.org.
Convert usages of Config.* to use the non-static versions


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/d31ee20b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/d31ee20b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/d31ee20b

Branch: refs/heads/master
Commit: d31ee20ba568aed498896a4165e27d87b509f946
Parents: 9b25d45
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 8 14:11:14 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 8 14:11:14 2014 -0400

----------------------------------------------------------------------
 framework/src/org/apache/cordova/Config.java    |  5 ++++
 .../src/org/apache/cordova/CordovaActivity.java |  5 ++--
 .../org/apache/cordova/CordovaChromeClient.java |  3 +-
 .../org/apache/cordova/CordovaUriHelper.java    |  2 +-
 .../src/org/apache/cordova/CordovaWebView.java  | 31 ++++++++++----------
 .../cordova/IceCreamCordovaWebViewClient.java   |  2 +-
 6 files changed, 26 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/Config.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/Config.java b/framework/src/org/apache/cordova/Config.java
index dfb039d..c13d397 100644
--- a/framework/src/org/apache/cordova/Config.java
+++ b/framework/src/org/apache/cordova/Config.java
@@ -22,6 +22,7 @@ package org.apache.cordova;
 import android.app.Activity;
 import android.util.Log;
 
+@Deprecated // Use Whitelist, CordovaPrefences, etc. directly.
 public class Config {
     private static final String TAG = "Config";
 
@@ -82,4 +83,8 @@ public class Config {
     public static String getErrorUrl() {
         return parser.getPreferences().getString("errorurl", null);
     }
+
+    public static Whitelist getWhitelist() {
+        return parser.getWhitelist();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index d3cc9c6..0d07957 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -227,7 +227,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
         }
 
         appView = makeWebView();
-        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries);
+        appView.init(this, makeWebViewClient(appView), makeChromeClient(appView), pluginEntries, whitelist);
 
         // TODO: Have the views set this themselves.
         if (preferences.getBoolean("DisallowOverscroll", false)) {
@@ -844,8 +844,9 @@ 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 Config.isUrlWhiteListed(url);
+        return whitelist.isUrlWhiteListed(url);
     }
 
     /*

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java
index 0337098..cebabba 100755
--- a/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -240,11 +240,10 @@ public class CordovaChromeClient extends WebChromeClient {
         }
 
         else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
-            String startUrl = Config.getStartUrl();
             // 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") && startUrl.startsWith(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);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaUriHelper.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaUriHelper.java b/framework/src/org/apache/cordova/CordovaUriHelper.java
index a6a0dcc..f189f1c 100644
--- a/framework/src/org/apache/cordova/CordovaUriHelper.java
+++ b/framework/src/org/apache/cordova/CordovaUriHelper.java
@@ -49,7 +49,7 @@ class CordovaUriHelper {
         if(url.startsWith("http:") || url.startsWith("https:"))
         {
             // We only need to whitelist sites on the Internet! 
-            if(Config.isUrlWhiteListed(url))
+            if(appView.getWhitelist().isUrlWhiteListed(url))
             {
                 return false;
             }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 4650588..fb442cc 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -26,12 +26,6 @@ import java.util.HashSet;
 import java.util.List;
 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 android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
@@ -80,11 +74,8 @@ public class CordovaWebView extends WebView {
     /** 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;
 
@@ -97,9 +88,10 @@ public class CordovaWebView extends WebView {
     private View mCustomView;
     private WebChromeClient.CustomViewCallback mCustomViewCallback;
 
-    private ActivityResult mResult = null;
-
     private CordovaResourceApi resourceApi;
+    private Whitelist whitelist;
+    // The URL passed to loadUrl(), not necessarily the URL of the current page.
+    String loadedUrl;
 
     class ActivityResult {
         
@@ -142,13 +134,15 @@ public class CordovaWebView extends WebView {
     }
 
     // Use two-phase init so that the control will work with XML layouts.
-    public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient, List<PluginEntry> pluginEntries) {
+    public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
+            List<PluginEntry> pluginEntries, Whitelist whitelist) {
         if (this.cordova != null) {
             throw new IllegalStateException();
         }
         this.cordova = cordova;
         this.viewClient = webViewClient;
         this.chromeClient = webChromeClient;
+        this.whitelist = whitelist;
         super.setWebChromeClient(webChromeClient);
         super.setWebViewClient(webViewClient);
 
@@ -310,6 +304,11 @@ public class CordovaWebView extends WebView {
         return this.chromeClient;
     }
 
+    
+    public Whitelist getWhitelist() {
+        return this.whitelist;
+    }
+    
     /**
      * Load the url into the webview.
      *
@@ -357,7 +356,7 @@ public class CordovaWebView extends WebView {
         LOG.d(TAG, ">>> loadUrl(" + url + ")");
 
         if (recreatePlugins) {
-            this.url = url;
+            this.loadedUrl = url;
             this.pluginManager.init();
         }
 
@@ -413,7 +412,7 @@ public class CordovaWebView extends WebView {
         if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
             LOG.d(TAG, ">>> loadUrlNow()");
         }
-        if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
+        if (url.startsWith("file://") || url.startsWith("javascript:") || whitelist.isUrlWhiteListed(url)) {
             super.loadUrl(url);
         }
     }
@@ -549,7 +548,7 @@ public class CordovaWebView extends WebView {
         if (!openExternal) {
 
             // Make sure url is in whitelist
-            if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
+            if (url.startsWith("file://") || whitelist.isUrlWhiteListed(url)) {
                 // TODO: What about params?
                 // Load new URL
                 this.loadUrl(url);
@@ -897,8 +896,8 @@ public class CordovaWebView extends WebView {
         return myList;
     }
 
+    @Deprecated // This never did anything
     public void storeResult(int requestCode, int resultCode, Intent intent) {
-        mResult = new ActivityResult(requestCode, resultCode, intent);
     }
     
     public CordovaResourceApi getResourceApi() {

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d31ee20b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index 67793d7..27bb5ef 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -77,7 +77,7 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
     }
 
     private boolean isUrlHarmful(String url) {
-        return ((url.startsWith("http:") || url.startsWith("https:")) && !Config.isUrlWhiteListed(url))
+        return ((url.startsWith("http:") || url.startsWith("https:")) && !appView.getWhitelist().isUrlWhiteListed(url))
             || url.contains("app_webview");
     }