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]