This is an automated email from the ASF dual-hosted git repository.

niklasmerz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-android.git


The following commit(s) were added to refs/heads/master by this push:
     new 5e7be8e  breaking: implement WebViewAssetLoader (#1137)
5e7be8e is described below

commit 5e7be8e1d6f9863f78a3bd481a3d366cc4d0a804
Author: Niklas Merz <[email protected]>
AuthorDate: Thu Apr 22 14:32:14 2021 +0200

    breaking: implement WebViewAssetLoader (#1137)
    
    Implement AndroidX WebViewAssetLoader with hook for plugins
    
    
    Co-authored-by: エリス <[email protected]>
---
 .gitignore                                         |  3 --
 framework/build.gradle                             |  4 ++
 .../src/org/apache/cordova/ConfigXmlParser.java    |  7 ++-
 .../src/org/apache/cordova/CordovaPlugin.java      |  8 +++
 .../apache/cordova/CordovaPluginPathHandler.java   | 38 ++++++++++++++
 .../src/org/apache/cordova/CordovaWebViewImpl.java |  1 -
 .../src/org/apache/cordova/PluginManager.java      | 16 ++++++
 .../apache/cordova/engine/SystemWebViewClient.java | 60 +++++++++++++++++++++-
 .../apache/cordova/engine/SystemWebViewEngine.java | 12 -----
 9 files changed, 129 insertions(+), 20 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8bfdf85..e374ee7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,9 +27,6 @@ example
 /framework/javadoc-private
 /test/.externalNativeBuild
 
-/test/android/gradle
-/test/android/gradlew
-/test/android/gradlew.bat
 /test/androidx/gradle
 /test/androidx/gradlew
 /test/androidx/gradlew.bat
diff --git a/framework/build.gradle b/framework/build.gradle
index 2bb483b..ecc0bf3 100644
--- a/framework/build.gradle
+++ b/framework/build.gradle
@@ -159,3 +159,7 @@ bintray {
         }
     }
 }
+
+dependencies {
+    implementation 'androidx.webkit:webkit:1.3.0'
+}
diff --git a/framework/src/org/apache/cordova/ConfigXmlParser.java 
b/framework/src/org/apache/cordova/ConfigXmlParser.java
index 01a97f2..ae9b57f 100644
--- a/framework/src/org/apache/cordova/ConfigXmlParser.java
+++ b/framework/src/org/apache/cordova/ConfigXmlParser.java
@@ -33,7 +33,7 @@ import android.content.Context;
 public class ConfigXmlParser {
     private static String TAG = "ConfigXmlParser";
 
-    private String launchUrl = "file:///android_asset/www/index.html";
+    private String launchUrl = null;
     private CordovaPreferences prefs = new CordovaPreferences();
     private ArrayList<PluginEntry> pluginEntries = new 
ArrayList<PluginEntry>(20);
 
@@ -46,6 +46,9 @@ public class ConfigXmlParser {
     }
 
     public String getLaunchUrl() {
+        if (launchUrl == null) { 
+            launchUrl = "https://"; +  this.prefs.getString("hostname", 
"localhost");
+        }
         return launchUrl;
     }
 
@@ -139,7 +142,7 @@ public class ConfigXmlParser {
             if (src.charAt(0) == '/') {
                 src = src.substring(1);
             }
-            launchUrl = "file:///android_asset/www/" + src;
+            launchUrl = "https://"; +  this.prefs.getString("hostname", 
"localhost") + "/" + src;
         }
     }
 }
diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java 
b/framework/src/org/apache/cordova/CordovaPlugin.java
index 46fd2fa..38e2e4a 100644
--- a/framework/src/org/apache/cordova/CordovaPlugin.java
+++ b/framework/src/org/apache/cordova/CordovaPlugin.java
@@ -434,4 +434,12 @@ public class CordovaPlugin {
                                           int[] grantResults) throws 
JSONException {
 
     }
+
+    /**
+     * Allow plugins to supply a PathHandler for the WebViewAssetHandler
+     * @return a CordovaPluginPathHandler which listen for paths and returns a 
response
+     */
+    public CordovaPluginPathHandler getPathHandler() {
+        return null;
+    }
 }
diff --git a/framework/src/org/apache/cordova/CordovaPluginPathHandler.java 
b/framework/src/org/apache/cordova/CordovaPluginPathHandler.java
new file mode 100644
index 0000000..0acaacb
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaPluginPathHandler.java
@@ -0,0 +1,38 @@
+/*
+       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 androidx.webkit.WebViewAssetLoader;
+
+/**
+ * Wrapper class for path and handler
+ */
+public class CordovaPluginPathHandler {
+
+    private final WebViewAssetLoader.PathHandler handler;
+
+    public  CordovaPluginPathHandler(WebViewAssetLoader.PathHandler handler) {
+        this.handler = handler;
+    }
+
+    public WebViewAssetLoader.PathHandler getPathHandler() {
+        return handler;
+    }
+}
diff --git a/framework/src/org/apache/cordova/CordovaWebViewImpl.java 
b/framework/src/org/apache/cordova/CordovaWebViewImpl.java
index b0ddcf4..55b8d3b 100644
--- a/framework/src/org/apache/cordova/CordovaWebViewImpl.java
+++ b/framework/src/org/apache/cordova/CordovaWebViewImpl.java
@@ -117,7 +117,6 @@ public class CordovaWebViewImpl implements CordovaWebView {
 
         pluginManager.addService(CoreAndroid.PLUGIN_NAME, 
"org.apache.cordova.CoreAndroid");
         pluginManager.init();
-
     }
 
     @Override
diff --git a/framework/src/org/apache/cordova/PluginManager.java 
b/framework/src/org/apache/cordova/PluginManager.java
index 21aec73..3728879 100755
--- a/framework/src/org/apache/cordova/PluginManager.java
+++ b/framework/src/org/apache/cordova/PluginManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cordova;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -577,4 +578,19 @@ public class PluginManager {
         }
         return state;
     }
+
+    /**
+     * Collect all plugins PathHandlers
+     *
+     * @return list of PathHandlers in no particular order
+     */
+    public ArrayList<CordovaPluginPathHandler> getPluginPathHandlers() {
+        ArrayList<CordovaPluginPathHandler> handlers = new 
ArrayList<CordovaPluginPathHandler>();
+        for (CordovaPlugin plugin : this.pluginMap.values()) {
+            if (plugin != null && plugin.getPathHandler() != null) {
+                handlers.add(plugin.getPathHandler());
+            }
+        }
+        return handlers;
+    }
 }
diff --git a/framework/src/org/apache/cordova/engine/SystemWebViewClient.java 
b/framework/src/org/apache/cordova/engine/SystemWebViewClient.java
index af9e51f..2af0668 100755
--- a/framework/src/org/apache/cordova/engine/SystemWebViewClient.java
+++ b/framework/src/org/apache/cordova/engine/SystemWebViewClient.java
@@ -18,17 +18,18 @@
 */
 package org.apache.cordova.engine;
 
-import android.annotation.TargetApi;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.net.http.SslError;
-import android.os.Build;
 import android.webkit.ClientCertRequest;
 import android.webkit.HttpAuthHandler;
+import android.webkit.MimeTypeMap;
 import android.webkit.SslErrorHandler;
+import android.webkit.WebResourceRequest;
 import android.webkit.WebResourceResponse;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
@@ -36,14 +37,17 @@ import android.webkit.WebViewClient;
 import org.apache.cordova.AuthenticationToken;
 import org.apache.cordova.CordovaClientCertRequest;
 import org.apache.cordova.CordovaHttpAuthHandler;
+import org.apache.cordova.CordovaPluginPathHandler;
 import org.apache.cordova.CordovaResourceApi;
 import org.apache.cordova.LOG;
 import org.apache.cordova.PluginManager;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Hashtable;
 
+import androidx.webkit.WebViewAssetLoader;
 
 /**
  * This class is the WebViewClient that implements callbacks for our web view.
@@ -56,6 +60,7 @@ public class SystemWebViewClient extends WebViewClient {
 
     private static final String TAG = "SystemWebViewClient";
     protected final SystemWebViewEngine parentEngine;
+    private final WebViewAssetLoader assetLoader;
     private boolean doClearHistory = false;
     boolean isCurrentlyLoading;
 
@@ -64,6 +69,52 @@ public class SystemWebViewClient extends WebViewClient {
 
     public SystemWebViewClient(SystemWebViewEngine parentEngine) {
         this.parentEngine = parentEngine;
+
+        WebViewAssetLoader.Builder assetLoaderBuilder = new 
WebViewAssetLoader.Builder()
+                .setDomain(parentEngine.preferences.getString("hostname", 
"localhost"))
+                .setHttpAllowed(true);
+
+        assetLoaderBuilder.addPathHandler("/", path -> {
+            try {
+                // Check if there a plugins with pathHandlers
+                PluginManager pluginManager = this.parentEngine.pluginManager;
+                if (pluginManager != null) {
+                    for (CordovaPluginPathHandler handler : 
pluginManager.getPluginPathHandlers()) {
+                        if (handler.getPathHandler() != null) {
+                            WebResourceResponse response = 
handler.getPathHandler().handle(path);
+                            if (response != null) {
+                                return response;
+                            }
+                        };
+                    }
+                }
+
+                if (path.isEmpty()) {
+                    path = "index.html";
+                }
+                InputStream is = 
parentEngine.webView.getContext().getAssets().open("www/" + path, 
AssetManager.ACCESS_STREAMING);
+                String mimeType = "text/html";
+                String extension = MimeTypeMap.getFileExtensionFromUrl(path);
+                if (extension != null) {
+                    if (path.endsWith(".js") || path.endsWith(".mjs")) {
+                        // Make sure JS files get the proper mimetype to 
support ES modules
+                        mimeType = "application/javascript";
+                    } else if (path.endsWith(".wasm")) {
+                        mimeType = "application/wasm";
+                    } else {
+                        mimeType = 
MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
+                    }
+                }
+
+                return new WebResourceResponse(mimeType, null, is);
+            } catch (Exception e) {
+                e.printStackTrace();
+                LOG.e(TAG, e.getMessage());
+            }
+            return null;
+        });
+
+        this.assetLoader = assetLoaderBuilder.build();
     }
 
     /**
@@ -366,4 +417,9 @@ public class SystemWebViewClient extends WebViewClient {
 
         return false;
     }
+
+    @Override
+    public WebResourceResponse shouldInterceptRequest(WebView view, 
WebResourceRequest request) {
+        return this.assetLoader.shouldInterceptRequest(request.getUrl());
+    }
 }
diff --git a/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java 
b/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java
index 26e56ba..2921d3d 100755
--- a/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java
+++ b/framework/src/org/apache/cordova/engine/SystemWebViewEngine.java
@@ -152,15 +152,6 @@ public class SystemWebViewEngine implements 
CordovaWebViewEngine {
         settings.setJavaScriptCanOpenWindowsAutomatically(true);
         settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
 
-        /**
-         * 
https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess(boolean)
-         * 
-         * SDK >= 30 has recently set this value to false by default.
-         * It is recommended to turn off this settings To prevent possible 
security issues targeting Build.VERSION_CODES.Q and earlier.
-         * For existing functionality, this setting is set to true. In a 
future release, this should be defaulted to false.
-         */
-        settings.setAllowFileAccess(true);
-
         String manufacturer = android.os.Build.MANUFACTURER;
         LOG.d(TAG, "CordovaWebView is running on device made by: " + 
manufacturer);
 
@@ -168,9 +159,6 @@ public class SystemWebViewEngine implements 
CordovaWebViewEngine {
         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
-        settings.setAllowUniversalAccessFromFileURLs(true);
         settings.setMediaPlaybackRequiresUserGesture(false);
 
         // Enable database

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to