You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by bo...@apache.org on 2014/06/24 21:30:40 UTC

android commit: Refactoring the URI handling on Cordova, removing dead code

Repository: cordova-android
Updated Branches:
  refs/heads/master 4b4a2e9f9 -> b0b628ffc


Refactoring the URI handling on Cordova, removing dead code


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

Branch: refs/heads/master
Commit: b0b628ffc24bdd952e86908cf6cb4064b6f3c405
Parents: 4b4a2e9
Author: Joe Bowser <bo...@apache.org>
Authored: Tue Jun 24 12:30:12 2014 -0700
Committer: Joe Bowser <bo...@apache.org>
Committed: Tue Jun 24 12:30:34 2014 -0700

----------------------------------------------------------------------
 .../org/apache/cordova/CordovaUriHelper.java    | 112 +++++++++++++++++++
 .../src/org/apache/cordova/CordovaWebView.java  |  27 ++---
 .../apache/cordova/CordovaWebViewClient.java    | 110 +-----------------
 .../cordova/IceCreamCordovaWebViewClient.java   |  11 +-
 4 files changed, 133 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/b0b628ff/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
new file mode 100644
index 0000000..1a113de
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaUriHelper.java
@@ -0,0 +1,112 @@
+/*
+       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.json.JSONException;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+import android.webkit.WebView;
+
+public class CordovaUriHelper {
+    
+    private static final String TAG = "CordovaUriHelper";
+    private static final String CORDOVA_EXEC_URL_PREFIX = "http://cdv_exec/";
+    
+    private CordovaWebView appView;
+    private CordovaInterface cordova;
+    
+    CordovaUriHelper(CordovaInterface cdv, CordovaWebView webView)
+    {
+        appView = webView;
+        cordova = cdv;
+    }
+    
+    
+    // Parses commands sent by setting the webView's URL to:
+    // cdvbrg:service/action/callbackId#jsonArgs
+    void handleExecUrl(String url) {
+        int idx1 = CORDOVA_EXEC_URL_PREFIX.length();
+        int idx2 = url.indexOf('#', idx1 + 1);
+        int idx3 = url.indexOf('#', idx2 + 1);
+        int idx4 = url.indexOf('#', idx3 + 1);
+        if (idx1 == -1 || idx2 == -1 || idx3 == -1 || idx4 == -1) {
+            Log.e(TAG, "Could not decode URL command: " + url);
+            return;
+        }
+        String service    = url.substring(idx1, idx2);
+        String action     = url.substring(idx2 + 1, idx3);
+        String callbackId = url.substring(idx3 + 1, idx4);
+        String jsonArgs   = url.substring(idx4 + 1);
+        appView.pluginManager.exec(service, action, callbackId, jsonArgs);
+        //There is no reason to not send this directly to the pluginManager
+    }
+    
+
+    /**
+     * Give the host application a chance to take over the control when a new url
+     * is about to be loaded in the current WebView.
+     *
+     * @param view          The WebView that is initiating the callback.
+     * @param url           The url to be loaded.
+     * @return              true to override, false for default behavior
+     */
+    public boolean shouldOverrideUrlLoading(WebView view, String url) {
+        // The WebView should support http and https when going on the Internet
+        if(url.startsWith("http:") || url.startsWith("https:"))
+        {
+            // Check if it's an exec() bridge command message.
+            if (NativeToJsMessageQueue.ENABLE_LOCATION_CHANGE_EXEC_MODE && url.startsWith(CORDOVA_EXEC_URL_PREFIX)) {
+                handleExecUrl(url);
+            }
+            // We only need to whitelist sites on the Internet! 
+            else if(Config.isUrlWhiteListed(url))
+            {
+                return false;
+            }
+        }
+        // Give plugins the chance to handle the url
+        else if (this.appView.pluginManager.onOverrideUrlLoading(url)) {
+            
+        }
+        else if(url.startsWith("file://") | url.startsWith("data:"))
+        {
+            //This directory on WebKit/Blink based webviews contains SQLite databases!
+            //DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING!
+            return url.contains("app_webview");
+        }
+        else
+        {
+            try {
+                Intent intent = new Intent(Intent.ACTION_VIEW);
+                intent.setData(Uri.parse(url));
+                this.cordova.getActivity().startActivity(intent);
+            } catch (android.content.ActivityNotFoundException e) {
+                LOG.e(TAG, "Error loading url " + url, e);
+            }
+        }
+        //Default behaviour should be to load the default intent, let's see what happens! 
+        return true;
+    }
+
+    
+
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/b0b628ff/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 b31eec5..ad5c0f0 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -401,17 +401,7 @@ public class CordovaWebView extends WebView {
             this.loadUrlNow(url);
         }
         else {
-
-            String initUrl = this.getProperty("url", null);
-
-            // If first page of app, then set URL to load to be the one passed in
-            if (initUrl == null) {
-                this.loadUrlIntoView(url);
-            }
-            // Otherwise use the URL specified in the activity's extras bundle
-            else {
-                this.loadUrlIntoView(initUrl);
-            }
+            this.loadUrlIntoView(url);
         }
     }
 
@@ -422,16 +412,15 @@ public class CordovaWebView extends WebView {
      * @param url
      * @param time              The number of ms to wait before loading webview
      */
+    @Deprecated
     public void loadUrl(final String url, int time) {
-        String initUrl = this.getProperty("url", null);
-
-        // If first page of app, then set URL to load to be the one passed in
-        if (initUrl == null) {
-            this.loadUrlIntoView(url, time);
+        if(url == null)
+        {
+            this.loadUrlIntoView(Config.getStartUrl());
         }
-        // Otherwise use the URL specified in the activity's extras bundle
-        else {
-            this.loadUrlIntoView(initUrl);
+        else
+        {
+            this.loadUrlIntoView(url);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/b0b628ff/framework/src/org/apache/cordova/CordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebViewClient.java b/framework/src/org/apache/cordova/CordovaWebViewClient.java
index 407c1fb..4a72fea 100755
--- a/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/CordovaWebViewClient.java
@@ -61,6 +61,7 @@ public class CordovaWebViewClient extends WebViewClient {
 	private static final String CORDOVA_EXEC_URL_PREFIX = "http://cdv_exec/";
     CordovaInterface cordova;
     CordovaWebView appView;
+    CordovaUriHelper helper;
     private boolean doClearHistory = false;
     boolean isCurrentlyLoading;
 
@@ -85,6 +86,7 @@ public class CordovaWebViewClient extends WebViewClient {
     public CordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) {
         this.cordova = cordova;
         this.appView = view;
+        helper = new CordovaUriHelper(cordova, view);
     }
 
     /**
@@ -94,6 +96,7 @@ public class CordovaWebViewClient extends WebViewClient {
      */
     public void setWebView(CordovaWebView view) {
         this.appView = view;
+        helper = new CordovaUriHelper(cordova, view);
     }
 
 
@@ -125,112 +128,7 @@ public class CordovaWebViewClient extends WebViewClient {
      */
 	@Override
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
-    	// Check if it's an exec() bridge command message.
-    	if (NativeToJsMessageQueue.ENABLE_LOCATION_CHANGE_EXEC_MODE && url.startsWith(CORDOVA_EXEC_URL_PREFIX)) {
-    		handleExecUrl(url);
-    	}
-
-        // Give plugins the chance to handle the url
-    	else if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
-        }
-
-        // If dialing phone (tel:5551212)
-        else if (url.startsWith(WebView.SCHEME_TEL)) {
-            try {
-                Intent intent = new Intent(Intent.ACTION_DIAL);
-                intent.setData(Uri.parse(url));
-                this.cordova.getActivity().startActivity(intent);
-            } catch (android.content.ActivityNotFoundException e) {
-                LOG.e(TAG, "Error dialing " + url + ": " + e.toString());
-            }
-        }
-
-        // If displaying map (geo:0,0?q=address)
-        else if (url.startsWith("geo:")) {
-            try {
-                Intent intent = new Intent(Intent.ACTION_VIEW);
-                intent.setData(Uri.parse(url));
-                this.cordova.getActivity().startActivity(intent);
-            } catch (android.content.ActivityNotFoundException e) {
-                LOG.e(TAG, "Error showing map " + url + ": " + e.toString());
-            }
-        }
-
-        // If sending email (mailto:abc@corp.com)
-        else if (url.startsWith(WebView.SCHEME_MAILTO)) {
-            try {
-                Intent intent = new Intent(Intent.ACTION_VIEW);
-                intent.setData(Uri.parse(url));
-                this.cordova.getActivity().startActivity(intent);
-            } catch (android.content.ActivityNotFoundException e) {
-                LOG.e(TAG, "Error sending email " + url + ": " + e.toString());
-            }
-        }
-
-        // If sms:5551212?body=This is the message
-        else if (url.startsWith("sms:")) {
-            try {
-                Intent intent = new Intent(Intent.ACTION_VIEW);
-
-                // Get address
-                String address = null;
-                int parmIndex = url.indexOf('?');
-                if (parmIndex == -1) {
-                    address = url.substring(4);
-                }
-                else {
-                    address = url.substring(4, parmIndex);
-
-                    // If body, then set sms body
-                    Uri uri = Uri.parse(url);
-                    String query = uri.getQuery();
-                    if (query != null) {
-                        if (query.startsWith("body=")) {
-                            intent.putExtra("sms_body", query.substring(5));
-                        }
-                    }
-                }
-                intent.setData(Uri.parse("sms:" + address));
-                intent.putExtra("address", address);
-                intent.setType("vnd.android-dir/mms-sms");
-                this.cordova.getActivity().startActivity(intent);
-            } catch (android.content.ActivityNotFoundException e) {
-                LOG.e(TAG, "Error sending sms " + url + ":" + e.toString());
-            }
-        }
-        
-        //Android Market
-        else if(url.startsWith("market:")) {
-            try {
-                Intent intent = new Intent(Intent.ACTION_VIEW);
-                intent.setData(Uri.parse(url));
-                this.cordova.getActivity().startActivity(intent);
-            } catch (android.content.ActivityNotFoundException e) {
-                LOG.e(TAG, "Error loading Google Play Store: " + url, e);
-            }
-        }
-
-        // All else
-        else {
-
-            // If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
-            // Our app continues to run.  When BACK is pressed, our app is redisplayed.
-            if (url.startsWith("file://") || url.startsWith("data:")  || Config.isUrlWhiteListed(url)) {
-                return false;
-            }
-
-            // If not our application, let default viewer handle
-            else {
-                try {
-                    Intent intent = new Intent(Intent.ACTION_VIEW);
-                    intent.setData(Uri.parse(url));
-                    this.cordova.getActivity().startActivity(intent);
-                } catch (android.content.ActivityNotFoundException e) {
-                    LOG.e(TAG, "Error loading url " + url, e);
-                }
-            }
-        }
-        return true;
+        return helper.shouldOverrideUrlLoading(view, url);
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/b0b628ff/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 63cfb91..67793d7 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -35,6 +35,7 @@ import android.webkit.WebView;
 public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
 
     private static final String TAG = "IceCreamCordovaWebViewClient";
+    private CordovaUriHelper helper;
 
     public IceCreamCordovaWebViewClient(CordovaInterface cordova) {
         super(cordova);
@@ -47,8 +48,9 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
     @Override
     public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
         try {
-            // Check the against the white-list.
-            if ((url.startsWith("http:") || url.startsWith("https:")) && !Config.isUrlWhiteListed(url)) {
+            // Check the against the whitelist and lock out access to the WebView directory
+            // Changing this will cause problems for your application
+            if (isUrlHarmful(url)) {
                 LOG.w(TAG, "URL blocked by whitelist: " + url);
                 // Results in a 404.
                 return new WebResourceResponse("text/plain", "UTF-8", null);
@@ -74,6 +76,11 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
         }
     }
 
+    private boolean isUrlHarmful(String url) {
+        return ((url.startsWith("http:") || url.startsWith("https:")) && !Config.isUrlWhiteListed(url))
+            || url.contains("app_webview");
+    }
+
     private static boolean needsKitKatContentUrlFix(Uri uri) {
         return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && "content".equals(uri.getScheme());
     }