forked from github/cordova-android
breaking: implement WebViewAssetLoader (#1137)
Implement AndroidX WebViewAssetLoader with hook for plugins Co-authored-by: エリス <erisu@users.noreply.github.com>
This commit is contained in:
parent
b2d9d639b4
commit
5e7be8e1d6
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||
|
@ -159,3 +159,7 @@ bintray {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.webkit:webkit:1.3.0'
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -117,7 +117,6 @@ public class CordovaWebViewImpl implements CordovaWebView {
|
||||
|
||||
pluginManager.addService(CoreAndroid.PLUGIN_NAME, "org.apache.cordova.CoreAndroid");
|
||||
pluginManager.init();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user