Removed Android Hybrid Composition constraint to use the pull-to-refresh feature, Removed Android com.squareup.okhttp3:okhttp dependency
This commit is contained in:
parent
b82baaa061
commit
962fc35ff7
@ -1,3 +1,8 @@
|
||||
## 6.0.0-beta.16
|
||||
|
||||
- Removed Android Hybrid Composition constraint to use the pull-to-refresh feature
|
||||
- Removed Android `com.squareup.okhttp3:okhttp` dependency
|
||||
|
||||
## 6.0.0-beta.15
|
||||
|
||||
- Automatically infer `useShouldOverrideUrlLoading`, `useOnLoadResource`, `useOnDownloadStart`, `useShouldInterceptAjaxRequest`, `useShouldInterceptFetchRequest`, `useShouldInterceptRequest`, `useOnRenderProcessGone`, `useOnNavigationResponse` settings if their value is `null` and the corresponding event is implemented by the WebView (`InAppWebView` and `HeadlessInAppWebView`, not `InAppBrowser`) before it's native initialization
|
||||
@ -145,6 +150,10 @@
|
||||
- Removed `URLProtectionSpace.iosIsProxy` property
|
||||
- `historyUrl` and `baseUrl` of `InAppWebViewInitialData` can be `null`
|
||||
|
||||
## 5.7.2
|
||||
|
||||
- Removed Android Hybrid Composition constraint to use the pull-to-refresh feature
|
||||
|
||||
## 5.7.1+2
|
||||
|
||||
- Fixed Android `NullPointerException` on `InAppBrowserActivity.dispose`
|
||||
|
@ -48,7 +48,6 @@ android {
|
||||
implementation 'androidx.webkit:webkit:1.5.0'
|
||||
implementation 'androidx.browser:browser:1.4.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,10 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyStore;
|
||||
@ -47,18 +49,11 @@ import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class Util {
|
||||
|
||||
@ -171,12 +166,38 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
public static OkHttpClient getBasicOkHttpClient() {
|
||||
return new OkHttpClient.Builder()
|
||||
.connectTimeout(15, TimeUnit.SECONDS)
|
||||
.writeTimeout(15, TimeUnit.SECONDS)
|
||||
.readTimeout(15, TimeUnit.SECONDS)
|
||||
.build();
|
||||
@Nullable
|
||||
public static HttpURLConnection makeHttpRequest(String urlString, String method, @Nullable Map<String, String> headers) {
|
||||
HttpURLConnection urlConnection = null;
|
||||
try {
|
||||
URL url = new URL(urlString);
|
||||
urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setRequestMethod(method);
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
urlConnection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
}
|
||||
urlConnection.setConnectTimeout(15000); // 15 seconds
|
||||
urlConnection.setReadTimeout(15000); // 15 seconds
|
||||
urlConnection.setDoInput(true);
|
||||
urlConnection.setInstanceFollowRedirects(true);
|
||||
if ("GET".equalsIgnoreCase(method)) {
|
||||
urlConnection.setDoOutput(false);
|
||||
}
|
||||
urlConnection.connect();
|
||||
return urlConnection;
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (!(e instanceof SSLHandshakeException)) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
}
|
||||
if (urlConnection != null) {
|
||||
urlConnection.disconnect();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,32 +2,34 @@ package com.pichillilorenzo.flutter_inappwebview.content_blocker;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.webkit.WebResourceResponse;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview.InAppWebView;
|
||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt;
|
||||
import com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview.InAppWebView;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class ContentBlockerHandler {
|
||||
protected static final String LOG_TAG = "ContentBlockerHandler";
|
||||
|
||||
@ -48,10 +50,14 @@ public class ContentBlockerHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, String url, ContentBlockerTriggerResourceType responseResourceType) throws URISyntaxException, InterruptedException, MalformedURLException {
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, WebResourceRequestExt request,
|
||||
ContentBlockerTriggerResourceType responseResourceType)
|
||||
throws URISyntaxException, InterruptedException, MalformedURLException {
|
||||
if (webView.customSettings.contentBlockers == null)
|
||||
return null;
|
||||
|
||||
String url = request.getUrl();
|
||||
|
||||
URI u;
|
||||
try {
|
||||
u = new URI(url);
|
||||
@ -182,36 +188,85 @@ public class ContentBlockerHandler {
|
||||
if (scheme.equals("http") && (port == -1 || port == 80)) {
|
||||
String urlHttps = url.replace("http://", "https://");
|
||||
|
||||
Request mRequest = new Request.Builder().url(urlHttps).build();
|
||||
Response response = null;
|
||||
HttpURLConnection urlConnection = Util.makeHttpRequest(urlHttps, request.getMethod(), request.getHeaders());
|
||||
if (urlConnection != null) {
|
||||
try {
|
||||
byte[] dataBytes = Util.readAllBytes(urlConnection.getInputStream());
|
||||
if (dataBytes == null) {
|
||||
return null;
|
||||
}
|
||||
InputStream dataStream = new ByteArrayInputStream(dataBytes);
|
||||
|
||||
try {
|
||||
response = Util.getBasicOkHttpClient().newCall(mRequest).execute();
|
||||
byte[] dataBytes = response.body().bytes();
|
||||
InputStream dataStream = new ByteArrayInputStream(dataBytes);
|
||||
String encoding = urlConnection.getContentEncoding();
|
||||
String contentType = urlConnection.getContentType();
|
||||
if (contentType == null) {
|
||||
contentType = "text/plain";
|
||||
} else {
|
||||
String[] contentTypeSplitted = contentType.split(";");
|
||||
contentType = contentTypeSplitted[0].trim();
|
||||
if (encoding == null) {
|
||||
encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
}
|
||||
}
|
||||
|
||||
String[] contentTypeSplitted = response.header("content-type", "text/plain").split(";");
|
||||
|
||||
String contentType = contentTypeSplitted[0].trim();
|
||||
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
|
||||
response.body().close();
|
||||
response.close();
|
||||
|
||||
return new WebResourceResponse(contentType, encoding, dataStream);
|
||||
|
||||
} catch (Exception e) {
|
||||
if (response != null) {
|
||||
response.body().close();
|
||||
response.close();
|
||||
}
|
||||
if (!(e instanceof SSLHandshakeException)) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
String reasonPhrase = urlConnection.getResponseMessage();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && reasonPhrase != null) {
|
||||
Map<String, String> responseHeaders = new HashMap<>();
|
||||
for (Map.Entry<String, List<String>> responseHeader : urlConnection.getHeaderFields().entrySet()) {
|
||||
responseHeaders.put(responseHeader.getKey(), TextUtils.join(",", responseHeader.getValue()));
|
||||
}
|
||||
return new WebResourceResponse(contentType,
|
||||
encoding,
|
||||
urlConnection.getResponseCode(),
|
||||
reasonPhrase,
|
||||
responseHeaders,
|
||||
dataStream);
|
||||
} else {
|
||||
return new WebResourceResponse(contentType,
|
||||
encoding,
|
||||
dataStream);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (!(e instanceof SSLHandshakeException)) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
urlConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// Request mRequest = new Request.Builder().url(urlHttps).build();
|
||||
// Response response = null;
|
||||
//
|
||||
// try {
|
||||
// response = Util.getBasicOkHttpClient().newCall(mRequest).execute();
|
||||
// byte[] dataBytes = response.body().bytes();
|
||||
// InputStream dataStream = new ByteArrayInputStream(dataBytes);
|
||||
//
|
||||
// String[] contentTypeSplitted = response.header("content-type", "text/plain").split(";");
|
||||
//
|
||||
// String contentType = contentTypeSplitted[0].trim();
|
||||
// String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
// ? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
// : "utf-8";
|
||||
//
|
||||
// response.body().close();
|
||||
// response.close();
|
||||
//
|
||||
// return new WebResourceResponse(contentType, encoding, dataStream);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// if (response != null) {
|
||||
// response.body().close();
|
||||
// response.close();
|
||||
// }
|
||||
// if (!(e instanceof SSLHandshakeException)) {
|
||||
// e.printStackTrace();
|
||||
// Log.e(LOG_TAG, e.getMessage());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -221,48 +276,36 @@ public class ContentBlockerHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, String url) throws URISyntaxException, InterruptedException, MalformedURLException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(url);
|
||||
return checkUrl(webView, url, responseResourceType);
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, WebResourceRequestExt request) throws URISyntaxException, InterruptedException, MalformedURLException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(request);
|
||||
return checkUrl(webView, request, responseResourceType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, String url, String contentType) throws URISyntaxException, InterruptedException, MalformedURLException {
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, WebResourceRequestExt request, String contentType) throws URISyntaxException, InterruptedException, MalformedURLException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
return checkUrl(webView, url, responseResourceType);
|
||||
return checkUrl(webView, request, responseResourceType);
|
||||
}
|
||||
|
||||
public ContentBlockerTriggerResourceType getResourceTypeFromUrl(String url) {
|
||||
public ContentBlockerTriggerResourceType getResourceTypeFromUrl(WebResourceRequestExt request) {
|
||||
ContentBlockerTriggerResourceType responseResourceType = ContentBlockerTriggerResourceType.RAW;
|
||||
String url = request.getUrl();
|
||||
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
// make an HTTP "HEAD" request to the server for that URL. This will not return the full content of the URL.
|
||||
Request mRequest = new Request.Builder().url(url).head().build();
|
||||
Response response = null;
|
||||
try {
|
||||
response = Util.getBasicOkHttpClient().newCall(mRequest).execute();
|
||||
|
||||
if (response.header("content-type") != null) {
|
||||
String[] contentTypeSplitted = response.header("content-type").split(";");
|
||||
|
||||
String contentType = contentTypeSplitted[0].trim();
|
||||
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
|
||||
response.body().close();
|
||||
response.close();
|
||||
responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (response != null) {
|
||||
response.body().close();
|
||||
response.close();
|
||||
}
|
||||
if (!(e instanceof SSLHandshakeException)) {
|
||||
HttpURLConnection urlConnection = Util.makeHttpRequest(url, "HEAD", request.getHeaders());
|
||||
if (urlConnection != null) {
|
||||
try {
|
||||
String contentType = urlConnection.getContentType();
|
||||
if (contentType != null) {
|
||||
String[] contentTypeSplitted = contentType.split(";");
|
||||
contentType = contentTypeSplitted[0].trim();
|
||||
responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
} finally {
|
||||
urlConnection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,15 +68,13 @@ public class FlutterWebView implements PlatformWebView {
|
||||
customSettings.useHybridComposition ? null : plugin.flutterView, userScripts);
|
||||
displayListenerProxy.onPostWebViewInitialization(displayManager);
|
||||
|
||||
if (customSettings.useHybridComposition) {
|
||||
// set MATCH_PARENT layout params to the WebView, otherwise it won't take all the available space!
|
||||
webView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
PullToRefreshSettings pullToRefreshSettings = new PullToRefreshSettings();
|
||||
pullToRefreshSettings.parse(pullToRefreshInitialSettings);
|
||||
pullToRefreshLayout = new PullToRefreshLayout(context, plugin, id, pullToRefreshSettings);
|
||||
pullToRefreshLayout.addView(webView);
|
||||
pullToRefreshLayout.prepare();
|
||||
}
|
||||
// set MATCH_PARENT layout params to the WebView, otherwise it won't take all the available space!
|
||||
webView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
PullToRefreshSettings pullToRefreshSettings = new PullToRefreshSettings();
|
||||
pullToRefreshSettings.parse(pullToRefreshInitialSettings);
|
||||
pullToRefreshLayout = new PullToRefreshLayout(context, plugin, id, pullToRefreshSettings);
|
||||
pullToRefreshLayout.addView(webView);
|
||||
pullToRefreshLayout.prepare();
|
||||
|
||||
FindInteractionController findInteractionController = new FindInteractionController(webView, plugin, id, null);
|
||||
webView.findInteractionController = findInteractionController;
|
||||
|
@ -690,7 +690,7 @@ public class InAppWebViewClient extends WebViewClient {
|
||||
if (customSchemeResponse != null) {
|
||||
WebResourceResponse response = null;
|
||||
try {
|
||||
response = webView.contentBlockerHandler.checkUrl(webView, url, customSchemeResponse.getContentType());
|
||||
response = webView.contentBlockerHandler.checkUrl(webView, request, customSchemeResponse.getContentType());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -705,7 +705,7 @@ public class InAppWebViewClient extends WebViewClient {
|
||||
WebResourceResponse response = null;
|
||||
if (webView.contentBlockerHandler.getRuleList().size() > 0) {
|
||||
try {
|
||||
response = webView.contentBlockerHandler.checkUrl(webView, url);
|
||||
response = webView.contentBlockerHandler.checkUrl(webView, request);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -3,11 +3,11 @@
|
||||
export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/3.3.6"
|
||||
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
|
||||
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||
export "FLUTTER_TARGET=integration_test/webview_flutter_test.dart"
|
||||
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
|
||||
export "FLUTTER_BUILD_DIR=build"
|
||||
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||
export "FLUTTER_BUILD_NUMBER=1"
|
||||
export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
|
||||
export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
|
||||
export "DART_OBFUSCATION=false"
|
||||
export "TRACK_WIDGET_CREATION=true"
|
||||
export "TREE_SHAKE_ICONS=false"
|
||||
|
@ -668,11 +668,6 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||
widget.initialOptions?.android.useHybridComposition) ??
|
||||
true;
|
||||
|
||||
if (!useHybridComposition && widget.pullToRefreshController != null) {
|
||||
throw new Exception(
|
||||
"To use the pull-to-refresh feature, InAppWebViewSettings.useHybridComposition setting MUST be true!");
|
||||
}
|
||||
|
||||
return PlatformViewLink(
|
||||
viewType: 'com.pichillilorenzo/flutter_inappwebview',
|
||||
surfaceFactory: (
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: flutter_inappwebview
|
||||
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
|
||||
version: 6.0.0-beta.15
|
||||
version: 6.0.0-beta.16
|
||||
homepage: https://inappwebview.dev/
|
||||
repository: https://github.com/pichillilorenzo/flutter_inappwebview
|
||||
issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues
|
||||
|
Loading…
x
Reference in New Issue
Block a user