diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml
new file mode 100644
index 00000000..3d5970d9
--- /dev/null
+++ b/.idea/libraries/Dart_Packages.xml
@@ -0,0 +1,772 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml
index c241dc8c..31799730 100755
--- a/.idea/libraries/Flutter_Plugins.xml
+++ b/.idea/libraries/Flutter_Plugins.xml
@@ -1,9 +1,6 @@
-
-
-
-
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54c5ddc6..9a89838d 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,11 +5,11 @@
- Added `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options also for iOS (also thanks to [liranhao](https://github.com/liranhao))
- Added limited cookies support on iOS below 11.0 using JavaScript
- Added `IOSCookieManager` class and `CookieManager.instance().ios.getAllCookies` iOS-specific method
-- Added `UserScript`, `UserScriptInjectionTime`, `ContentWorld`, `AndroidWebViewFeature`, `AndroidServiceWorkerController`, `AndroidServiceWorkerClient`, `ScreenshotConfiguration`, `IOSWKPDFConfiguration` classes
+- Added `UserScript`, `UserScriptInjectionTime`, `ContentWorld`, `AndroidWebViewFeature`, `AndroidServiceWorkerController`, `AndroidServiceWorkerClient`, `ScreenshotConfiguration`, `IOSWKPDFConfiguration`, `URLRequest` classes
- Added `initialUserScripts` WebView option
-- Added `addUserScript`, `addUserScripts`, `removeUserScript`, `removeUserScripts`, `removeAllUserScripts`, `callAsyncJavaScript` WebView methods
+- Added `addUserScript`, `addUserScripts`, `removeUserScript`, `removeUserScripts`, `removeUserScriptsByGroupName`, `removeAllUserScripts`, `callAsyncJavaScript`, `isSecureContext` WebView methods
- Added `contentWorld` argument to `evaluateJavascript` WebView method
-- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains`, `useOnNavigationResponse`, `applePayAPIEnabled`, `allowingReadAccessTo` iOS-specific WebView options
+- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains`, `useOnNavigationResponse`, `applePayAPIEnabled`, `allowingReadAccessTo`, `disableLongPressContextMenuOnLinks` iOS-specific WebView options
- Added `handlesURLScheme`, `createPdf`, `createWebArchiveData` iOS-specific WebView methods
- Added `iosOnNavigationResponse` and `iosShouldAllowDeprecatedTLS` iOS-specific WebView events
- Added `iosAnimated` optional argument to `zoomBy` WebView method
@@ -18,6 +18,7 @@
- Added `cssLinkHtmlTagAttributes` optional argument to `injectCSSFileFromUrl` WebView method
- Added `iosAllowingReadAccessTo` iOS-specific optional argument to `loadUrl` WebView method
- Added new iOS-specific attributes to `ShouldOverrideUrlLoadingRequest` and `CreateWindowRequest` classes
+- Added `toolbarTopTranslucent`, `toolbarTopTintColor`, `toolbarBottomTintColor`, `toolbarTopBarTintColor` ios-specific InAppBrowser options
- Updated integration tests
- Merge "Upgraded appcompat to 1.2.0-rc-02" [#465](https://github.com/pichillilorenzo/flutter_inappwebview/pull/465) (thanks to [andreidiaconu](https://github.com/andreidiaconu))
- Merge "Added missing field 'headers' which returned by WebResourceResponse.toMap()" [#490](https://github.com/pichillilorenzo/flutter_inappwebview/pull/490) (thanks to [Doflatango](https://github.com/Doflatango))
@@ -47,14 +48,44 @@
- Minimum Flutter version required is `1.22.2` and Dart SDK `>=2.12.0-0 <3.0.0`
- iOS Xcode version `>= 12`
-- Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled
- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options
- Added `callAsyncJavaScript` name to the list of javaScriptHandlerForbiddenNames
-- Changed `zoomBy` WebView method signature
- Moved `saveWebArchive` WebView method from Android-specific to cross-platform
+- Moved `progressBar` InAppBroswer from Android-specific option to cross-platform option and renamed to `hideProgressBar`
- Renamed `HttpAuthChallenge` to `URLAuthenticationChallenge`
-- Deleted `androidOnRequestFocus` event because it is never called
- Updated `basicConstraints`, `subjectKeyIdentifier`, `authorityKeyIdentifier`, `certificatePolicies`, `cRLDistributionPoints`, `authorityInfoAccess` attributes type of `X509Certificate`
+- Updated "WebView.storyboard" for InAppBrowser iOS representation
+- Renamed `ShouldOverrideUrlLoadingAction` class to `NavigationActionPolicy`
+- Renamed `ProtectionSpace` class to `URLProtectionSpace`
+- Renamed `ProtectionSpaceHttpAuthCredentials` to `URLProtectionSpaceHttpAuthCredentials`
+- Renamed `CreateWindowRequest` class to `CreateWindowAction`
+- Renamed `initialUrl` to `initialUrlRequest` WebView attribute and made it of type `URLRequest`
+- Renamed `toolbarTop` InAppBrowser cross-platform option to `hideToolbarTop`
+- Renamed `toolbarBottom` InAppBrowser ios-specific option to `hideToolbarBottom`
+- Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled
+- Removed `androidOnRequestFocus` event because it is never called
+- Removed `initialHeaders` WebView attribute. Use `URLRequest.headers` attribute
+- Removed `headers` argument from `loadFile` WebView method
+- Removed `headers` argument from `openFile` InAppBrowser method
+- Removed `headers` argument from `loadUrl` WebView method, renamed the `url` argument to `urlRequest` and made it of type `URLRequest`
+- Removed `headers` argument from `openFile` InAppBrowser method
+- Removed `headers` argument from `openUrl` InAppBrowser method, renamed the `url` argument to `urlRequest` and made it of type `URLRequest`
+- Removed `fallback` argument from `ChromeSafariBrowser` constructor. Check for availability of `ChromeSafariBrowser` if you want show one or the other.
+- Removed `scheme` argument from `onLoadResourceCustomScheme` WebView event. Use the `Uri url` parameter now.
+- Removed `ShouldOverrideUrlLoadingRequest` class and replaced with `NavigationAction`
+- Changed `zoomBy` WebView method signature
+- Changed type of `urlFile` argument of `injectCSSFileFromUrl` WebView method to `Uri`
+- Changed type of `urlFile` argument of `injectJavascriptFileFromUrl` WebView method to `Uri`
+- Changed return type of `getOriginalUrl` Android-specific WebView method to `Uri`
+- Changed return type of `getSafeBrowsingPrivacyPolicyUrl` Android-specific WebView method to `Uri`
+- Changed type of `url` argument of `onLoadStart`, `onLoadStop`, `onLoadError`, `onLoadHttpError`, `onLoadResourceCustomScheme`, `onUpdateVisitedHistory`, `onPrint`, `onPageCommitVisible`, `androidOnSafeBrowsingHit`, `androidOnRenderProcessUnresponsive`, `androidOnRenderProcessResponsive`, `androidOnFormResubmission`, `androidOnReceivedTouchIconUrl` WebView events to `Uri`
+- Changed type of `baseUrl` and `androidHistoryUrl` arguments of `loadData` WebView method and `openData` InAppBrowser method
+- Changed `openUrl` InAppBrowser method to `openUrlRequest`
+- Changed type of `url` argument of `openWithSystemBrowser` InAppBrowser method to `Uri`
+- Changed all InAppBrowser color options type from `String` to `Color`
+- Changed all ChromeSafariBrowser color options type from `String` to `Color`
+- Updated attributes of `ShouldOverrideUrlLoadingRequest`, `ServerTrustChallenge` and `ClientCertChallenge` classes
+- Changed type of `url` attribute to `Uri` for `JsAlertRequest`, `JsAlertConfirm`, `JsPromptRequest` classes
## 4.0.0+4
diff --git a/README.md b/README.md
index 1df4dd1e..2866c9ab 100755
--- a/README.md
+++ b/README.md
@@ -29,8 +29,8 @@ Also, check the [example/integration_test/webview_flutter_test.dart](https://git
## Articles/Resources
-- [InAppWebView: The Real Power of WebViews in Flutter](https://medium.com/flutter-community/inappwebview-the-real-power-of-webviews-in-flutter-c6d52374209d?source=friends_link&sk=cb74487219bcd85e610a670ee0b447d0)
-- [Creating a Full-Featured Browser using WebViews in Flutter](https://medium.com/flutter-community/creating-a-full-featured-browser-using-webviews-in-flutter-9c8f2923c574?source=friends_link&sk=55fc8267f351082aa9e73ced546f6bcb)
+- [InAppWebView: The Real Power of WebViews in Flutter](https://medium.com/flutter-community/inappwebview-the-real-power-of-webviews-in-flutter-c6d52374209d?source=friends_link&sk=cb74487219bcd85e610a670ee0b447d0) (valid for plugin version 4.0.0)
+- [Creating a Full-Featured Browser using WebViews in Flutter](https://medium.com/flutter-community/creating-a-full-featured-browser-using-webviews-in-flutter-9c8f2923c574?source=friends_link&sk=55fc8267f351082aa9e73ced546f6bcb) (valid for plugin version 4.0.0)
- [Flutter Browser App: A Full-Featured Mobile Browser App (such as the Google Chrome mobile browser) created using Flutter and the features offered by the flutter_inappwebview plugin](https://github.com/pichillilorenzo/flutter_browser_app)
## Requirements
@@ -323,24 +323,31 @@ class _MyAppState extends State {
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
- initialUrl: "https://flutter.dev/",
- initialHeaders: {},
+ initialUrlRequest: URLRequest(
+ url: Uri.parse("https://flutter.dev/")
+ ),
initialOptions: InAppWebViewGroupOptions(
- crossPlatform: InAppWebViewOptions(
+ crossPlatform: InAppWebViewOptions(
- )
+ ),
+ ios: IOSInAppWebViewOptions(
+
+ ),
+ android: AndroidInAppWebViewOptions(
+ useHybridComposition: true
+ )
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (controller, url) {
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
onLoadStop: (controller, url) async {
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
onProgressChanged: (controller, progress) {
@@ -354,19 +361,19 @@ class _MyAppState extends State {
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
- RaisedButton(
+ ElevatedButton(
child: Icon(Icons.arrow_back),
onPressed: () {
webView?.goBack();
},
),
- RaisedButton(
+ ElevatedButton(
child: Icon(Icons.arrow_forward),
onPressed: () {
webView?.goForward();
},
),
- RaisedButton(
+ ElevatedButton(
child: Icon(Icons.refresh),
onPressed: () {
webView?.reload();
@@ -395,8 +402,8 @@ Screenshots:
##### `InAppWebViewController` Cross-platform methods
* `addJavaScriptHandler({required String handlerName, required JavaScriptHandlerCallback callback})`: Adds a JavaScript message handler callback that listen to post messages sent from JavaScript by the handler with name `handlerName`.
-* `addUserScript(UserScript userScript)`: Injects the specified `userScript` into the webpage’s content.
-* `addUserScripts(List userScripts)`: Injects the `userScripts` into the webpage’s content.
+* `addUserScript({required UserScript userScript})`: Injects the specified `userScript` into the webpage’s content.
+* `addUserScripts({required List userScripts})`: Injects the `userScripts` into the webpage’s content.
* `callAsyncJavaScript({required String functionBody, Map arguments = const {}, ContentWorld? contentWorld})`: Executes the specified string as an asynchronous JavaScript function.
* `canGoBackOrForward({required int steps})`: Returns a boolean value indicating whether the WebView can go back or forward the given number of steps. Steps is negative if backward and positive if forward.
* `canGoBack`: Returns a boolean value indicating whether the WebView can move backward.
@@ -433,26 +440,28 @@ Screenshots:
* `injectCSSFileFromAsset({required String assetFilePath})`: Injects a CSS file into the WebView from the flutter assets directory.
* `injectCSSFileFromUrl({required String urlFile, CSSLinkHtmlTagAttributes? cssLinkHtmlTagAttributes})`: Injects an external CSS file into the WebView from a defined url.
* `injectJavascriptFileFromAsset({required String assetFilePath})`: Injects a JavaScript file into the WebView from the flutter assets directory.
-* `injectJavascriptFileFromUrl({required String urlFile, ScriptHtmlTagAttributes? scriptHtmlTagAttributes})`: Injects an external JavaScript file into the WebView from a defined url.
+* `injectJavascriptFileFromUrl({required Uri urlFile, ScriptHtmlTagAttributes? scriptHtmlTagAttributes})`: Injects an external JavaScript file into the WebView from a defined url.
* `isLoading`: Check if the WebView instance is in a loading state.
-* `loadData({required String data, String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank", String androidHistoryUrl = "about:blank"})`: Loads the given data into this WebView.
-* `loadFile({required String assetFilePath, Map headers = const {}})`: Loads the given `assetFilePath` with optional headers specified as a map from name to value.
-* `loadUrl({required String url, Map headers = const {}, String? iosAllowingReadAccessTo})`: Loads the given url with optional headers specified as a map from name to value.
+* `isSecureContext`: Indicates whether the webpage context is capable of using features that require secure contexts.
+* `loadData({required String data, String mimeType = "text/html", String encoding = "utf8", Uri? baseUrl, Uri? androidHistoryUrl})`: Loads the given data into this WebView.
+* `loadFile({required String assetFilePath})`: Loads the given `assetFilePath` with optional headers specified as a map from name to value.
+* `loadUrl({required URLRequest urlRequest, Uri? iosAllowingReadAccessTo})`: Loads the given url with optional headers specified as a map from name to value.
* `pauseTimers`: On Android, it pauses all layout, parsing, and JavaScript timers for all WebViews. This is a global requests, not restricted to just this WebView. This can be useful if the application has been paused. On iOS, it is restricted to just this WebView.
-* `postUrl({required String url, required Uint8List postData})`: Loads the given url with postData using `POST` method into this WebView.
+* `postUrl({required Uri url, required Uint8List postData})`: Loads the given url with postData using `POST` method into this WebView.
* `printCurrentPage`: Prints the current page.
* `reload`: Reloads the WebView.
* `removeAllUserScripts()`: Removes all the user scripts from the webpage’s content.
* `removeJavaScriptHandler({required String handlerName})`: Removes a JavaScript message handler previously added with the `addJavaScriptHandler()` associated to `handlerName` key.
-* `removeUserScript(UserScript userScript)`: Removes the specified `userScript` from the webpage’s content.
-* `removeUserScripts(List userScripts)`: Removes the `userScripts` from the webpage’s content.
+* `removeUserScript({required UserScript userScript})`: Removes the specified `userScript` from the webpage’s content.
+* `removeUserScriptsByGroupName({required String groupName})`: Removes all the `UserScript`s with `groupName` as group name from the webpage’s content.
+* `removeUserScripts({required List userScripts})`: Removes the `userScripts` from the webpage’s content.
* `requestFocusNodeHref`: Requests the anchor or image element URL at the last tapped point.
* `requestImageRef`: Requests the URL of the image last touched by the user.
* `resumeTimers`: On Android, it resumes all layout, parsing, and JavaScript timers for all WebViews. This will resume dispatching all timers. On iOS, it resumes all layout, parsing, and JavaScript timers to just this WebView.
* `saveWebArchive({required String filePath, bool autoname = false})`: Saves the current view as a web archive.
* `scrollBy({required int x, required int y, bool animated = false})`: Moves the scrolled position of the WebView.
* `scrollTo({required int x, required int y, bool animated = false})`: Scrolls the WebView to the position.
-* `setContextMenu(ContextMenu contextMenu)`: Sets or updates the WebView context menu to be used next time it will appear.
+* `setContextMenu(ContextMenu? contextMenu)`: Sets or updates the WebView context menu to be used next time it will appear.
* `setOptions({required InAppWebViewGroupOptions options})`: Sets the WebView options with the new options and evaluates them.
* `stopLoading`: Stops the WebView from loading.
* `takeScreenshot({ScreenshotConfiguration? screenshotConfiguration})`: Takes a screenshot (in PNG format) of the WebView's visible viewport and returns a `Uint8List`. Returns `null` if it wasn't be able to take it.
@@ -611,6 +620,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
* `minimumLogicalFontSize`: Sets the minimum logical font size. The default is `8`.
* `mixedContentMode`: Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin.
* `needInitialFocus`: Tells the WebView whether it needs to set a node. The default value is `true`.
+* `networkAvailable`: Informs WebView of the network state.
* `offscreenPreRaster`: Sets whether this WebView should raster tiles when it is offscreen but attached to a window.
* `overScrollMode`: Sets the WebView's over-scroll mode. The default value is `AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS`.
* `regexToCancelSubFramesLoading`: Regular expression used by `shouldOverrideUrlLoading` event to cancel navigation for frames that are not the main frame. If the url request of a subframe matches the regular expression, then the request of that subframe is canceled.
@@ -649,6 +659,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
* `contentInsetAdjustmentBehavior`: Configures how safe area insets are added to the adjusted content inset. The default value is `IOSUIScrollViewContentInsetAdjustmentBehavior.NEVER`.
* `dataDetectorTypes`: Specifying a dataDetectoryTypes value adds interactivity to web content that matches the value.
* `decelerationRate`: A `IOSUIScrollViewDecelerationRate` value that determines the rate of deceleration after the user lifts their finger. The default value is `IOSUIScrollViewDecelerationRate.NORMAL`.
+* `disableLongPressContextMenuOnLinks`: Set to `true` to disable the context menu (copy, select, etc.) that is shown when the user emits a long press event on a HTML link.
* `disallowOverScroll`: Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`.
* `enableViewportScale`: Set to `true` to allow a viewport meta tag to either disable or restrict the range of user scaling. The default value is `false`.
* `ignoresViewportScaleLimits`: Set to `true` if you want that the WebView should always allow scaling of the webpage, regardless of the author's intent.
@@ -664,7 +675,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
* `selectionGranularity`: The level of granularity with which the user can interactively select content in the web view.
* `sharedCookiesEnabled`: Set `true` if shared cookies from `HTTPCookieStorage.shared` should used for every load request in the WebView.
* `suppressesIncrementalRendering`: Set to `true` if you want the WebView suppresses content rendering until it is fully loaded into memory. The default value is `false`.
-* `useOnNavigationResponse`: Set to `true` to be able to listen at the `iosOnNavigationResponse` event. The default value is `false`.
+* `useOnNavigationResponse`: Set to `true` to be able to listen to the `iosOnNavigationResponse` event. The default value is `false`.
#### `InAppWebView` Events
@@ -814,25 +825,32 @@ class _MyAppState extends State {
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
- initialUrl: "https://flutter.dev/",
+ initialUrlRequest: URLRequest(
+ url: Uri.parse("https://flutter.dev/")
+ ),
contextMenu: contextMenu,
- initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
- crossPlatform: InAppWebViewOptions(
+ crossPlatform: InAppWebViewOptions(
- )
+ ),
+ ios: IOSInAppWebViewOptions(
+
+ ),
+ android: AndroidInAppWebViewOptions(
+ useHybridComposition: true
+ )
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (controller, url) {
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
onLoadStop: (controller, url) async {
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
onProgressChanged: (controller, progress) {
@@ -846,19 +864,19 @@ class _MyAppState extends State {
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
- RaisedButton(
+ ElevatedButton(
child: Icon(Icons.arrow_back),
onPressed: () {
webView?.goBack();
},
),
- RaisedButton(
+ ElevatedButton(
child: Icon(Icons.arrow_forward),
onPressed: () {
webView?.goForward();
},
),
- RaisedButton(
+ ElevatedButton(
child: Icon(Icons.refresh),
onPressed: () {
webView?.reload();
@@ -922,7 +940,9 @@ class _MyAppState extends State {
super.initState();
headlessWebView = new HeadlessInAppWebView(
- initialUrl: "https://flutter.dev/",
+ initialUrlRequest: URLRequest(
+ url: Uri.parse("https://flutter.dev/")
+ ),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
@@ -937,19 +957,19 @@ class _MyAppState extends State {
onLoadStart: (controller, url) async {
print("onLoadStart $url");
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
onLoadStop: (controller, url) async {
print("onLoadStop $url");
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
onUpdateVisitedHistory: (controller, url, androidIsReload) {
print("onUpdateVisitedHistory $url");
setState(() {
- this.url = url ?? '';
+ this.url = url?.toString() ?? '';
});
},
);
@@ -976,7 +996,7 @@ class _MyAppState extends State {
"CURRENT URL\n${(url.length > 50) ? url.substring(0, 50) + "..." : url}"),
),
Center(
- child: RaisedButton(
+ child: ElevatedButton(
onPressed: () async {
await headlessWebView?.dispose();
await headlessWebView?.run();
@@ -984,7 +1004,7 @@ class _MyAppState extends State {
child: Text("Run HeadlessInAppWebView")),
),
Center(
- child: RaisedButton(
+ child: ElevatedButton(
onPressed: () async {
try {
await headlessWebView?.webViewController.evaluateJavascript(source: """console.log('Here is the message!');""");
@@ -995,7 +1015,7 @@ class _MyAppState extends State {
child: Text("Send console.log message")),
),
Center(
- child: RaisedButton(
+ child: ElevatedButton(
onPressed: () {
headlessWebView?.dispose();
},
@@ -1054,9 +1074,9 @@ class MyInAppBrowser extends InAppBrowser {
}
@override
- Future shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
- print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n");
- return ShouldOverrideUrlLoadingAction.ALLOW;
+ Future? shouldOverrideUrlLoading(NavigationAction navigationAction) async {
+ print("\n\n override ${navigationAction.request.url}\n\n");
+ return NavigationActionPolicy.ALLOW;
}
@override
@@ -1066,7 +1086,7 @@ class MyInAppBrowser extends InAppBrowser {
"ms ---> duration: " +
response.duration.toString() +
"ms " +
- (response.url ?? ''));
+ (response.url?.toString() ?? ''));
}
@override
@@ -1074,7 +1094,7 @@ class MyInAppBrowser extends InAppBrowser {
print("""
console output:
message: ${consoleMessage.message}
- messageLevel: ${consoleMessage.messageLevel?.toValue()}
+ messageLevel: ${consoleMessage.messageLevel.toValue()}
""");
}
}
@@ -1106,7 +1126,7 @@ class _MyAppState extends State {
title: const Text('InAppBrowser Example'),
),
body: Center(
- child: RaisedButton(
+ child: ElevatedButton(
onPressed: () {
widget.browser.openFile(
assetFilePath: "assets/index.html",
@@ -1136,10 +1156,10 @@ Screenshots:
#### `InAppBrowser` Methods
-* `open({String url = "about:blank", Map headers = const {}, InAppBrowserClassOptions options})`: Opens an `url` in a new `InAppBrowser` instance.
-* `openFile({required String assetFilePath, Map headers = const {}, InAppBrowserClassOptions options})`: Opens the given `assetFilePath` file in a new `InAppBrowser` instance. The other arguments are the same of `InAppBrowser.open`.
-* `openData({required String data, String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank", String historyUrl = "about:blank", InAppBrowserClassOptions options})`: Opens a new `InAppBrowser` instance with `data` as a content, using `baseUrl` as the base URL for it.
-* `openWithSystemBrowser({required String url})`: This is a static method that opens an `url` in the system browser. You wont be able to use the `InAppBrowser` methods here!
+* `openUrlRequest({required URLRequest urlRequest, InAppBrowserClassOptions? options})`: Opens an `url` in a new `InAppBrowser` instance.
+* `openFile({required String assetFilePath, InAppBrowserClassOptions? options})`: Opens the given `assetFilePath` file in a new `InAppBrowser` instance. The other arguments are the same of `InAppBrowser.open`.
+* `openData({required String data, String mimeType = "text/html", String encoding = "utf8", Uri? baseUrl, Uri? androidHistoryUrl, InAppBrowserClassOptions? options})`: Opens a new `InAppBrowser` instance with `data` as a content, using `baseUrl` as the base URL for it.
+* `openWithSystemBrowser({required Uri url})`: This is a static method that opens an `url` in the system browser. You wont be able to use the `InAppBrowser` methods here!
* `show`: Displays an `InAppBrowser` window that was opened hidden. Calling this has no effect if the `InAppBrowser` was already visible.
* `hide`: Hides the `InAppBrowser` window. Calling this has no effect if the `InAppBrowser` was already hidden.
* `close`: Closes the `InAppBrowser` window.
@@ -1157,25 +1177,28 @@ Specific options of the `InAppBrowser` class are:
* `hidden`: Set to `true` to create the browser and load the page, but not show it. Omit or set to `false` to have the browser open and load normally. The default value is `false`.
* `hideUrlBar`: Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`.
+* `hideProgressBar`: Set to `true` to hide the progress bar when the WebView is loading a page. The default value is `false`.
+* `hideToolbarTop`: Set to `true` to hide the toolbar at the top of the WebView. The default value is `false`.
* `toolbarTopBackgroundColor`: Set the custom background color of the toolbar at the top.
-* `toolbarTop`: Set to `false` to hide the toolbar at the top of the WebView. The default value is `true`.
##### `InAppBrowser` Android-specific options
* `closeOnCannotGoBack`: Set to `false` to not close the InAppBrowser when the user click on the back button and the WebView cannot go back to the history. The default value is `true`.
* `hideTitleBar`: Set to `true` if you want the title should be displayed. The default value is `false`.
-* `progressBar`: Set to `false` to hide the progress bar at the bottom of the toolbar at the top. The default value is `true`.
* `toolbarTopFixedTitle`: Set the action bar's title.
##### `InAppBrowser` iOS-specific options
* `closeButtonCaption`: Set the custom text for the close button.
* `closeButtonColor`: Set the custom color for the close button.
+* `hideToolbarBottom`: Set to `true` to hide the toolbar at the bottom of the WebView. The default value is `false`.
* `presentationStyle`: Set the custom modal presentation style when presenting the WebView. The default value is `IOSUIModalPresentationStyle.FULL_SCREEN`.
-* `spinner`: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`.
* `toolbarBottomBackgroundColor`: Set the custom background color of the toolbar at the bottom.
+* `toolbarBottomTintColor`: Set the tint color to apply to the bar button items.
* `toolbarBottomTranslucent`: Set to `true` to set the toolbar at the bottom translucent. The default value is `true`.
-* `toolbarBottom`: Set to `false` to hide the toolbar at the bottom of the WebView. The default value is `true`.
+* `toolbarTopTranslucent`: Set to `true` to set the toolbar at the top translucent. The default value is `true`.
+* `toolbarTopBarTintColor`: Set the tint color to apply to the navigation bar background.
+* `toolbarTopTintColor`: Set the tint color to apply to the navigation items and bar button items.
* `transitionStyle`: Set to the custom transition style when presenting the WebView. The default value is `IOSUIModalTransitionStyle.COVER_VERTICAL`.
#### `InAppBrowser` Events
@@ -1192,8 +1215,6 @@ Specific events of the `InAppBrowser` class are:
If you want to use the `ChromeSafariBrowser` class on Android 11+ you need to specify your app querying for `android.support.customtabs.action.CustomTabsService` in your `AndroidManifest.xml` (you can read more about it here: https://developers.google.com/web/android/custom-tabs/best-practices#applications_targeting_android_11_api_level_30_or_above).
-You can initialize the `ChromeSafariBrowser` instance with an `InAppBrowser` fallback instance.
-
Create a Class that extends the `ChromeSafariBrowser` Class in order to override the callbacks to manage the browser events. Example:
```dart
import 'dart:io';
@@ -1227,8 +1248,6 @@ class MyInAppBrowser extends InAppBrowser {
class MyChromeSafariBrowser extends ChromeSafariBrowser {
- MyChromeSafariBrowser(browserFallback) : super(bFallback: browserFallback);
-
@override
void onOpened() {
print("ChromeSafari browser opened");
@@ -1254,7 +1273,7 @@ Future main() async {
}
class MyApp extends StatefulWidget {
- final ChromeSafariBrowser browser = new MyChromeSafariBrowser(new MyInAppBrowser());
+ final ChromeSafariBrowser browser = new MyChromeSafariBrowser();
@override
_MyAppState createState() => new _MyAppState();
@@ -1285,10 +1304,10 @@ class _MyAppState extends State {
title: const Text('ChromeSafariBrowser Example'),
),
body: Center(
- child: RaisedButton(
+ child: ElevatedButton(
onPressed: () async {
await widget.browser.open(
- url: "https://flutter.dev/",
+ url: Uri.parse("https://flutter.dev/"),
options: ChromeSafariBrowserClassOptions(
android: AndroidChromeCustomTabsOptions(addDefaultShareMenuItem: false),
ios: IOSSafariOptions(barCollapsingEnabled: true)));
@@ -1316,7 +1335,7 @@ Screenshots:
* `addMenuItems`: Adds a list of `ChromeSafariBrowserMenuItem` to the menu.
* `close`: Closes the `ChromeSafariBrowser` instance.
* `isOpened`: Returns `true` if the `ChromeSafariBrowser` instance is opened, otherwise `false`.
-* `open({required String url, ChromeSafariBrowserClassOptions options, Map headersFallback = const {}, InAppBrowserClassOptions optionsFallback})`: Opens an `url` in a new `ChromeSafariBrowser` instance.
+* `open({required Uri url, ChromeSafariBrowserClassOptions? options})`: Opens an `url` in a new `ChromeSafariBrowser` instance.
* `static isAvailable`: On Android, returns `true` if Chrome Custom Tabs is available. On iOS, returns `true` if SFSafariViewController is available. Otherwise returns `false`.
#### `ChromeSafariBrowser` options
@@ -1376,30 +1395,31 @@ Future main() async {
title: const Text('InAppWebView Example'),
),
body: Container(
- child: Column(children: [
- Expanded(
- child: Container(
- child: InAppWebView(
- initialUrl: "http://localhost:8080/assets/index.html",
- initialHeaders: {},
- initialOptions: InAppWebViewGroupOptions(
- crossPlatform: InAppWebViewOptions(
+ child: Column(children: [
+ Expanded(
+ child: Container(
+ child: InAppWebView(
+ initialUrlRequest: URLRequest(
+ url: Uri.parse("http://localhost:8080/assets/index.html")
+ ),
+ initialOptions: InAppWebViewGroupOptions(
+ crossPlatform: InAppWebViewOptions(
- )
+ )
+ ),
+ onWebViewCreated: (controller) {
+
+ },
+ onLoadStart: (controller, url) {
+
+ },
+ onLoadStop: (controller, url) {
+
+ },
),
- onWebViewCreated: (controller) {
-
- },
- onLoadStart: (controller, url) {
-
- },
- onLoadStop: (controller, url) {
-
- },
),
- ),
- )]
- )
+ )]
+ )
),
),
);
@@ -1426,11 +1446,11 @@ On iOS, it is implemented using [WKHTTPCookieStore](https://developer.apple.com/
#### `CookieManager` methods
* `instance`: Gets the cookie manager shared instance.
-* `setCookie({required String url, required String name, required String value, String? domain, String path = "/", int? expiresDate, int? maxAge, bool? isSecure, bool? isHttpOnly, HTTPCookieSameSitePolicy? sameSite, InAppWebViewController? iosBelow11WebViewController})`: Sets a cookie for the given `url`. Any existing cookie with the same `host`, `path` and `name` will be replaced with the new cookie. The cookie being set will be ignored if it is expired.
-* `getCookies({required String url, InAppWebViewController? iosBelow11WebViewController})`: Gets all the cookies for the given `url`.
-* `getCookie({required String url, required String name, InAppWebViewController? iosBelow11WebViewController})`: Gets a cookie by its `name` for the given `url`.
-* `deleteCookie({required String url, required String name, String domain = "", String path = "/", InAppWebViewController? iosBelow11WebViewController})`: Removes a cookie by its `name` for the given `url`, `domain` and `path`.
-* `deleteCookies({required String url, String domain = "", String path = "/", InAppWebViewController? iosBelow11WebViewController})`: Removes all cookies for the given `url`, `domain` and `path`.
+* `setCookie({required Uri url, required String name, required String value, String? domain, String path = "/", int? expiresDate, int? maxAge, bool? isSecure, bool? isHttpOnly, HTTPCookieSameSitePolicy? sameSite, InAppWebViewController? iosBelow11WebViewController})`: Sets a cookie for the given `url`. Any existing cookie with the same `host`, `path` and `name` will be replaced with the new cookie. The cookie being set will be ignored if it is expired.
+* `getCookies({required Uri url, InAppWebViewController? iosBelow11WebViewController})`: Gets all the cookies for the given `url`.
+* `getCookie({required Uri url, required String name, InAppWebViewController? iosBelow11WebViewController})`: Gets a cookie by its `name` for the given `url`.
+* `deleteCookie({required Uri url, required String name, String domain = "", String path = "/", InAppWebViewController? iosBelow11WebViewController})`: Removes a cookie by its `name` for the given `url`, `domain` and `path`.
+* `deleteCookies({required Uri url, String domain = "", String path = "/", InAppWebViewController? iosBelow11WebViewController})`: Removes all cookies for the given `url`, `domain` and `path`.
* `deleteAllCookies()`: Removes all cookies.
#### `CookieManager` iOS-specific methods
@@ -1449,10 +1469,10 @@ On Android, this class has a custom implementation using `android.database.sqlit
* `instance`: Gets the database shared instance.
* `getAllAuthCredentials`: Gets a map list of all HTTP auth credentials saved.
-* `getHttpAuthCredentials({required ProtectionSpace protectionSpace})`: Gets all the HTTP auth credentials saved for that `protectionSpace`.
-* `setHttpAuthCredential({required ProtectionSpace protectionSpace, required HttpAuthCredential credential})`: Saves an HTTP auth `credential` for that `protectionSpace`.
-* `removeHttpAuthCredential({required ProtectionSpace protectionSpace, required HttpAuthCredential credential})`: Removes an HTTP auth `credential` for that `protectionSpace`.
-* `removeHttpAuthCredentials({required ProtectionSpace protectionSpace})`: Removes all the HTTP auth credentials saved for that `protectionSpace`.
+* `getHttpAuthCredentials({required URLProtectionSpace protectionSpace})`: Gets all the HTTP auth credentials saved for that `protectionSpace`.
+* `setHttpAuthCredential({required URLProtectionSpace protectionSpace, required URLCredential credential})`: Saves an HTTP auth `credential` for that `protectionSpace`.
+* `removeHttpAuthCredential({required URLProtectionSpace protectionSpace, required URLCredential credential})`: Removes an HTTP auth `credential` for that `protectionSpace`.
+* `removeHttpAuthCredentials({required URLProtectionSpace protectionSpace})`: Removes all the HTTP auth credentials saved for that `protectionSpace`.
* `clearAllAuthCredentials()`: Removes all the HTTP auth credentials saved in the database.
### `WebStorageManager` class
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 9aaca72f..aa9e7a21 100755
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -2,9 +2,9 @@
-
-
-
+
+
+
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeSafariBrowserManager.java
deleted file mode 100755
index 3526913c..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeSafariBrowserManager.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ChromeCustomTabsActivity;
-import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.CustomTabActivityHelper;
-import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserActivity;
-import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserOptions;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import io.flutter.plugin.common.BinaryMessenger;
-import io.flutter.plugin.common.MethodCall;
-import io.flutter.plugin.common.MethodChannel;
-
-public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandler {
-
- public MethodChannel channel;
-
- protected static final String LOG_TAG = "ChromeBrowserManager";
-
- public ChromeSafariBrowserManager(BinaryMessenger messenger) {
- channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_chromesafaribrowser");
- channel.setMethodCallHandler(this);
- }
-
- @Override
- public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
- final Activity activity = Shared.activity;
- final String uuid = (String) call.argument("uuid");
-
- switch (call.method) {
- case "open":
- {
- String url = (String) call.argument("url");
- HashMap options = (HashMap) call.argument("options");
- List> menuItemList = (List>) call.argument("menuItemList");
- String uuidFallback = (String) call.argument("uuidFallback");
- Map headersFallback = (Map) call.argument("headersFallback");
- HashMap optionsFallback = (HashMap) call.argument("optionsFallback");
- HashMap contextMenuFallback = (HashMap) call.argument("contextMenuFallback");
- Integer windowIdFallback = (Integer) call.argument("windowIdFallback");
- open(activity, uuid, url, options, menuItemList, uuidFallback, headersFallback, optionsFallback, contextMenuFallback, windowIdFallback, result);
- }
- break;
- case "isAvailable":
- result.success(CustomTabActivityHelper.isAvailable(activity));
- break;
- default:
- result.notImplemented();
- }
- }
-
- public void open(Activity activity, String uuid, String url, HashMap options, List> menuItemList, String uuidFallback,
- Map headersFallback, HashMap optionsFallback, HashMap contextMenuFallback, Integer windowIdFallback,
- MethodChannel.Result result) {
-
- Intent intent = null;
- Bundle extras = new Bundle();
- extras.putString("fromActivity", activity.getClass().getName());
- extras.putString("url", url);
- extras.putBoolean("isData", false);
- extras.putString("uuid", uuid);
- extras.putSerializable("options", options);
- extras.putSerializable("menuItemList", (Serializable) menuItemList);
-
- extras.putSerializable("headers", (Serializable) headersFallback);
- extras.putSerializable("contextMenu", (Serializable) contextMenuFallback);
-
- extras.putInt("windowId", windowIdFallback != null ? windowIdFallback : -1);
-
- if (CustomTabActivityHelper.isAvailable(activity)) {
- intent = new Intent(activity, ChromeCustomTabsActivity.class);
- }
- // check for webview fallback
- else if (uuidFallback != null) {
- Log.d(LOG_TAG, "WebView fallback declared.");
- // overwrite with extras fallback parameters
- extras.putString("uuid", uuidFallback);
- if (optionsFallback != null)
- extras.putSerializable("options", optionsFallback);
- else
- extras.putSerializable("options", (Serializable) (new InAppBrowserOptions()).toMap());
- intent = new Intent(activity, InAppBrowserActivity.class);
- }
-
- if (intent != null) {
- intent.putExtras(extras);
- activity.startActivity(intent);
- result.success(true);
- return;
- }
-
- result.error(LOG_TAG, "No WebView fallback declared.", null);
- }
-
- public void dispose() {
- channel.setMethodCallHandler(null);
- }
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlocker.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlocker.java
deleted file mode 100755
index f9082514..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlocker.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.ContentBlocker;
-
-public class ContentBlocker {
- public ContentBlockerTrigger trigger;
- public ContentBlockerAction action;
-
- public ContentBlocker (ContentBlockerTrigger trigger, ContentBlockerAction action) {
- this.trigger = trigger;
- this.action = action;
- }
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerAction.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerAction.java
deleted file mode 100755
index b6ff1193..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerAction.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.ContentBlocker;
-
-import java.util.Map;
-
-public class ContentBlockerAction {
- ContentBlockerActionType type;
- String selector;
-
- ContentBlockerAction(ContentBlockerActionType type, String selector) {
- this.type = type;
- if (this.type.equals(ContentBlockerActionType.CSS_DISPLAY_NONE)) {
- assert(selector != null);
- }
- this.selector = selector;
- }
-
- public static ContentBlockerAction fromMap(Map map) {
- ContentBlockerActionType type = ContentBlockerActionType.fromValue((String) map.get("type"));
- String selector = (String) map.get("selector");
- return new ContentBlockerAction(type, selector);
- }
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerTrigger.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerTrigger.java
deleted file mode 100755
index 79df6b0c..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerTrigger.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.ContentBlocker;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-public class ContentBlockerTrigger {
-
- public String urlFilter;
- public Pattern urlFilterPatternCompiled;
- public Boolean urlFilterIsCaseSensitive;
- public List resourceType = new ArrayList<>();
- public List ifDomain = new ArrayList<>();
- public List unlessDomain = new ArrayList<>();
- public List loadType = new ArrayList<>();
- public List ifTopUrl = new ArrayList<>();
- public List unlessTopUrl = new ArrayList<>();
-
- public ContentBlockerTrigger(String urlFilter, Boolean urlFilterIsCaseSensitive, List resourceType, List ifDomain,
- List unlessDomain, List loadType, List ifTopUrl, List unlessTopUrl) {
- this.urlFilter = urlFilter;
- this.urlFilterPatternCompiled = Pattern.compile(this.urlFilter);
-
- this.resourceType = resourceType != null ? resourceType : this.resourceType;
- this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive != null ? urlFilterIsCaseSensitive : false;
- this.ifDomain = ifDomain != null ? ifDomain : this.ifDomain;
- this.unlessDomain = unlessDomain != null ? unlessDomain : this.unlessDomain;
- if ((!(this.ifDomain.isEmpty() || this.unlessDomain.isEmpty()) != false))
- throw new AssertionError();
- this.loadType = loadType != null ? loadType : this.loadType;
- if ((this.loadType.size() > 2)) throw new AssertionError();
- this.ifTopUrl = ifTopUrl != null ? ifTopUrl : this.ifTopUrl;
- this.unlessTopUrl = unlessTopUrl != null ? unlessTopUrl : this.unlessTopUrl;
- if ((!(this.ifTopUrl.isEmpty() || this.unlessTopUrl.isEmpty()) != false))
- throw new AssertionError();
- }
-
- public static ContentBlockerTrigger fromMap(Map map) {
- String urlFilter = (String) map.get("url-filter");
- Boolean urlFilterIsCaseSensitive = (Boolean) map.get("url-filter-is-case-sensitive");
- List resourceTypeStringList = (List) map.get("resource-type");
- List resourceType = new ArrayList<>();
- if (resourceTypeStringList != null) {
- for (String type : resourceTypeStringList) {
- resourceType.add(ContentBlockerTriggerResourceType.fromValue(type));
- }
- } else {
- resourceType.addAll(Arrays.asList(ContentBlockerTriggerResourceType.values()));
- }
- List ifDomain = (List) map.get("if-domain");
- List unlessDomain = (List) map.get("unless-domain");
- List loadType = (List) map.get("load-type");
- List ifTopUrl = (List) map.get("if-top-url");
- List unlessTopUrl = (List) map.get("unless-top-url");
- return new ContentBlockerTrigger(urlFilter, urlFilterIsCaseSensitive, resourceType, ifDomain, unlessDomain, loadType, ifTopUrl, unlessTopUrl);
- }
-
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/Credential.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/Credential.java
deleted file mode 100755
index eaed8ade..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/Credential.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.CredentialDatabase;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class Credential {
- public Long id;
- public String username;
- public String password;
- public Long protectionSpaceId;
-
- public Credential (Long id, String username, String password, Long protectionSpaceId) {
- this.id = id;
- this.username = username;
- this.password = password;
- this.protectionSpaceId = protectionSpaceId;
- }
-
- public Map toMap() {
- Map credentialMap = new HashMap<>();
- credentialMap.put("username", username);
- credentialMap.put("password", password);
- return credentialMap;
- }
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDao.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDao.java
deleted file mode 100755
index 6f81b661..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDao.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.CredentialDatabase;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class CredentialDao {
-
- CredentialDatabaseHelper credentialDatabaseHelper;
- String[] projection = {
- CredentialContract.FeedEntry._ID,
- CredentialContract.FeedEntry.COLUMN_NAME_USERNAME,
- CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD,
- CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID
- };
-
- public CredentialDao(CredentialDatabaseHelper credentialDatabaseHelper) {
- this.credentialDatabaseHelper = credentialDatabaseHelper;
- }
-
- public List getAllByProtectionSpaceId(Long protectionSpaceId) {
- String selection = CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " = ?";
- String[] selectionArgs = {protectionSpaceId.toString()};
-
- Cursor cursor = credentialDatabaseHelper.getReadableDatabase().query(
- CredentialContract.FeedEntry.TABLE_NAME,
- projection,
- selection,
- selectionArgs,
- null,
- null,
- null
- );
-
- List credentials = new ArrayList<>();
- while (cursor.moveToNext()) {
- Long id = cursor.getLong(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry._ID));
- String username = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME));
- String password = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD));
- credentials.add(new Credential(id, username, password, protectionSpaceId));
- }
- cursor.close();
-
- return credentials;
- }
-
- public Credential find(String username, String password, Long protectionSpaceId) {
- String selection = CredentialContract.FeedEntry.COLUMN_NAME_USERNAME + " = ? AND " +
- CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD + " = ? AND " +
- CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " = ?";
- String[] selectionArgs = {username, password, protectionSpaceId.toString()};
-
- Cursor cursor = credentialDatabaseHelper.getReadableDatabase().query(
- CredentialContract.FeedEntry.TABLE_NAME,
- projection,
- selection,
- selectionArgs,
- null,
- null,
- null
- );
-
- Credential credential = null;
- if (cursor.moveToNext()) {
- Long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry._ID));
- String rowUsername = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME));
- String rowPassword = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD));
- credential = new Credential(rowId, rowUsername, rowPassword, protectionSpaceId);
- }
- cursor.close();
-
- return credential;
- }
-
- public long insert(Credential credential) {
- ContentValues credentialValues = new ContentValues();
- credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME, credential.username);
- credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD, credential.password);
- credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID, credential.protectionSpaceId);
-
- return credentialDatabaseHelper.getWritableDatabase().insert(CredentialContract.FeedEntry.TABLE_NAME, null, credentialValues);
- }
-
- public long update(Credential credential) {
- ContentValues credentialValues = new ContentValues();
- credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME, credential.username);
- credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD, credential.password);
-
- String whereClause = CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " = ?";
- String[] whereArgs = {credential.protectionSpaceId.toString()};
-
- return credentialDatabaseHelper.getWritableDatabase().update(CredentialContract.FeedEntry.TABLE_NAME, credentialValues, whereClause, whereArgs);
- }
-
- public long delete(Credential credential) {
- String whereClause = CredentialContract.FeedEntry._ID + " = ?";
- String[] whereArgs = {credential.id.toString()};
-
- return credentialDatabaseHelper.getWritableDatabase().delete(CredentialContract.FeedEntry.TABLE_NAME, whereClause, whereArgs);
- }
-
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDatabase.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDatabase.java
deleted file mode 100755
index 9b02fba9..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDatabase.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.CredentialDatabase;
-
-import android.content.Context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class CredentialDatabase {
-
- private static CredentialDatabase instance;
- static final String LOG_TAG = "CredentialDatabase";
-
- // If you change the database schema, you must increment the database version.
- public static final int DATABASE_VERSION = 2;
- public static final String DATABASE_NAME = "CredentialDatabase.db";
-
- public ProtectionSpaceDao protectionSpaceDao;
- public CredentialDao credentialDao;
- public CredentialDatabaseHelper db;
-
- private CredentialDatabase() {}
-
- private CredentialDatabase(CredentialDatabaseHelper db, ProtectionSpaceDao protectionSpaceDao, CredentialDao credentialDao) {
- this.db = db;
- this.protectionSpaceDao = protectionSpaceDao;
- this.credentialDao = credentialDao;
- }
-
- public static CredentialDatabase getInstance(Context context) {
- if (instance != null)
- return instance;
- CredentialDatabaseHelper db = new CredentialDatabaseHelper(context);
- instance = new CredentialDatabase(db, new ProtectionSpaceDao(db), new CredentialDao(db));
- return instance;
- }
-
- public List getHttpAuthCredentials(String host, String protocol, String realm, Integer port) {
- List credentialList = new ArrayList<>();
- ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
- if (protectionSpace != null) {
- credentialList = credentialDao.getAllByProtectionSpaceId(protectionSpace.id);
- }
- return credentialList;
- }
-
- public void clearAllAuthCredentials() {
- db.clearAllTables(db.getWritableDatabase());
- }
-
- public void removeHttpAuthCredentials(String host, String protocol, String realm, Integer port) {
- ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
- if (protectionSpace != null) {
- protectionSpaceDao.delete(protectionSpace);
- }
- }
-
- public void removeHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
- ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
- if (protectionSpace != null) {
- Credential credential = credentialDao.find(username, password, protectionSpace.id);
- credentialDao.delete(credential);
- }
- }
-
- public void setHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
- ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
- Long protectionSpaceId;
- if (protectionSpace == null) {
- protectionSpaceId = protectionSpaceDao.insert(new ProtectionSpace(null, host, protocol, realm, port));
- } else {
- protectionSpaceId = protectionSpace.id;
- }
-
- Credential credential = credentialDao.find(username, password, protectionSpaceId);
- if (credential != null) {
- boolean needUpdate = false;
- if (!credential.username.equals(username)) {
- credential.username = username;
- needUpdate = true;
- }
- if (!credential.password.equals(password)) {
- credential.password = password;
- needUpdate = true;
- }
- if (needUpdate)
- credentialDao.update(credential);
- } else {
- credential = new Credential(null, username, password, protectionSpaceId);
- credential.id = credentialDao.insert(credential);
- }
- }
-}
\ No newline at end of file
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDatabaseHelper.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDatabaseHelper.java
deleted file mode 100755
index 2cc90777..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/CredentialDatabaseHelper.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.CredentialDatabase;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-public class CredentialDatabaseHelper extends SQLiteOpenHelper {
-
- private static final String SQL_CREATE_PROTECTION_SPACE_TABLE =
- "CREATE TABLE " + ProtectionSpaceContract.FeedEntry.TABLE_NAME + " (" +
- ProtectionSpaceContract.FeedEntry._ID + " INTEGER PRIMARY KEY," +
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST + " TEXT NOT NULL," +
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL + " TEXT," +
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM + " TEXT," +
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT + " INTEGER," +
- "UNIQUE(" + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST + ", " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL + ", " +
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM + ", " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT +
- ")" +
- ");";
-
- private static final String SQL_CREATE_CREDENTIAL_TABLE =
- "CREATE TABLE " + CredentialContract.FeedEntry.TABLE_NAME + " (" +
- CredentialContract.FeedEntry._ID + " INTEGER PRIMARY KEY," +
- CredentialContract.FeedEntry.COLUMN_NAME_USERNAME + " TEXT NOT NULL," +
- CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD + " TEXT NOT NULL," +
- CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " INTEGER NOT NULL," +
- "UNIQUE(" + CredentialContract.FeedEntry.COLUMN_NAME_USERNAME + ", " + CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD + ", " +
- CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID +
- ")," +
- "FOREIGN KEY (" + CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + ") REFERENCES " +
- ProtectionSpaceContract.FeedEntry.TABLE_NAME + " (" + ProtectionSpaceContract.FeedEntry._ID + ") ON DELETE CASCADE" +
- ");";
-
- private static final String SQL_DELETE_PROTECTION_SPACE_TABLE =
- "DROP TABLE IF EXISTS " + ProtectionSpaceContract.FeedEntry.TABLE_NAME;
-
- private static final String SQL_DELETE_CREDENTIAL_TABLE =
- "DROP TABLE IF EXISTS " + CredentialContract.FeedEntry.TABLE_NAME;
-
- public CredentialDatabaseHelper(Context context) {
- super(context, CredentialDatabase.DATABASE_NAME, null, CredentialDatabase.DATABASE_VERSION);
- }
-
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(SQL_CREATE_PROTECTION_SPACE_TABLE);
- db.execSQL(SQL_CREATE_CREDENTIAL_TABLE);
- }
-
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // This database is only a cache for online data, so its upgrade policy is
- // to simply to discard the data and start over
- db.execSQL(SQL_DELETE_PROTECTION_SPACE_TABLE);
- db.execSQL(SQL_DELETE_CREDENTIAL_TABLE);
- onCreate(db);
- }
-
- public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- onUpgrade(db, oldVersion, newVersion);
- }
-
- public void clearAllTables(SQLiteDatabase db) {
- db.execSQL(SQL_DELETE_PROTECTION_SPACE_TABLE);
- db.execSQL(SQL_DELETE_CREDENTIAL_TABLE);
- onCreate(db);
- }
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/ProtectionSpace.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/ProtectionSpace.java
deleted file mode 100755
index 1e460fe1..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/ProtectionSpace.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.CredentialDatabase;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class ProtectionSpace {
- public Long id;
- public String host;
- public String procotol;
- public String realm;
- public Integer port;
-
- public ProtectionSpace (Long id, String host, String protocol, String realm, Integer port) {
- this.id = id;
- this.host = host;
- this.procotol = protocol;
- this.realm = realm;
- this.port = port;
- }
-
- public Map toMap() {
- Map protectionSpaceMap = new HashMap<>();
- protectionSpaceMap.put("host", host);
- protectionSpaceMap.put("protocol", procotol);
- protectionSpaceMap.put("realm", realm);
- protectionSpaceMap.put("port", port);
- return protectionSpaceMap;
- }
-}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/ProtectionSpaceDao.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/ProtectionSpaceDao.java
deleted file mode 100755
index 81d1cdfc..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabase/ProtectionSpaceDao.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.pichillilorenzo.flutter_inappwebview.CredentialDatabase;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ProtectionSpaceDao {
- CredentialDatabaseHelper credentialDatabaseHelper;
- String[] projection = {
- ProtectionSpaceContract.FeedEntry._ID,
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST,
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL,
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM,
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT
- };
-
- public ProtectionSpaceDao(CredentialDatabaseHelper credentialDatabaseHelper) {
- this.credentialDatabaseHelper = credentialDatabaseHelper;
- }
-
- public List getAll() {
- SQLiteDatabase readableDatabase = credentialDatabaseHelper.getReadableDatabase();
-
- Cursor cursor = readableDatabase.query(
- ProtectionSpaceContract.FeedEntry.TABLE_NAME,
- projection,
- null,
- null,
- null,
- null,
- null
- );
-
- List protectionSpaces = new ArrayList<>();
- while (cursor.moveToNext()) {
- Long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry._ID));
- String rowHost = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST));
- String rowProtocol = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL));
- String rowRealm = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM));
- Integer rowPort = cursor.getInt(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT));
- protectionSpaces.add(new ProtectionSpace(rowId, rowHost, rowProtocol, rowRealm, rowPort));
- }
- cursor.close();
-
- return protectionSpaces;
- }
-
- public ProtectionSpace find(String host, String protocol, String realm, Integer port) {
- SQLiteDatabase readableDatabase = credentialDatabaseHelper.getReadableDatabase();
-
- String selection = ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST + " = ? AND " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL + " = ? AND " +
- ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM + " = ? AND " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT + " = ?";
- String[] selectionArgs = {host, protocol, realm, port.toString()};
-
- Cursor cursor = readableDatabase.query(
- ProtectionSpaceContract.FeedEntry.TABLE_NAME,
- projection,
- selection,
- selectionArgs,
- null,
- null,
- null
- );
-
- ProtectionSpace protectionSpace = null;
- if (cursor.moveToNext()) {
- Long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry._ID));
- String rowHost = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST));
- String rowProtocol = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL));
- String rowRealm = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM));
- Integer rowPort = cursor.getInt(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT));
- protectionSpace = new ProtectionSpace(rowId, rowHost, rowProtocol, rowRealm, rowPort);
- }
- cursor.close();
-
- return protectionSpace;
- }
-
- public long insert(ProtectionSpace protectionSpace) {
- ContentValues protectionSpaceValues = new ContentValues();
- protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST, protectionSpace.host);
- protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL, protectionSpace.procotol);
- protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM, protectionSpace.realm);
- protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT, protectionSpace.port);
-
- return credentialDatabaseHelper.getWritableDatabase().insert(ProtectionSpaceContract.FeedEntry.TABLE_NAME, null, protectionSpaceValues);
- };
-
- public long delete(ProtectionSpace protectionSpace) {
- String whereClause = ProtectionSpaceContract.FeedEntry._ID + " = ?";
- String[] whereArgs = {protectionSpace.id.toString()};
-
- return credentialDatabaseHelper.getWritableDatabase().delete(ProtectionSpaceContract.FeedEntry.TABLE_NAME, whereClause, whereArgs);
- }
-}
\ No newline at end of file
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java
index 4af050b7..645d5f19 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java
@@ -4,10 +4,13 @@ import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
-import android.util.Log;
import android.webkit.ValueCallback;
-import com.pichillilorenzo.flutter_inappwebview.InAppWebView.FlutterWebViewFactory;
+import com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs.ChromeSafariBrowserManager;
+import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabaseHandler;
+import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserManager;
+import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebViewFactory;
+import com.pichillilorenzo.flutter_inappwebview.in_app_webview.HeadlessInAppWebViewManager;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
@@ -15,7 +18,6 @@ import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.platform.PlatformViewRegistry;
-import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;
public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java
index a7e40cfd..17a5aa0a 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java
@@ -8,10 +8,16 @@ import androidx.annotation.NonNull;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
-import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserOptions;
-import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView;
-import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebViewOptions;
+import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserActivity;
+import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserOptions;
+import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebView;
+import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebViewOptions;
+import com.pichillilorenzo.flutter_inappwebview.types.ContentWorld;
+import com.pichillilorenzo.flutter_inappwebview.types.SslCertificateExt;
+import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
+import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@@ -40,42 +46,55 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
result.success((webView != null) ? webView.getProgress() : null);
break;
case "loadUrl":
- if (webView != null)
- webView.loadUrl((String) call.argument("url"), (Map) call.argument("headers"), result);
- else
- result.success(false);
+ if (webView != null) {
+ Map urlRequest = (Map) call.argument("urlRequest");
+ webView.loadUrl(URLRequest.fromMap(urlRequest));
+ }
+ result.success(true);
break;
case "postUrl":
- if (webView != null)
- webView.postUrl((String) call.argument("url"), (byte[]) call.argument("postData"), result);
- else
- result.success(false);
+ if (webView != null) {
+ String url = (String) call.argument("url");
+ byte[] postData = (byte[]) call.argument("postData");
+ webView.postUrl(url, postData);
+ }
+ result.success(true);
break;
case "loadData":
- {
- String data = (String) call.argument("data");
- String mimeType = (String) call.argument("mimeType");
- String encoding = (String) call.argument("encoding");
- String baseUrl = (String) call.argument("baseUrl");
- String historyUrl = (String) call.argument("historyUrl");
-
- if (webView != null)
- webView.loadData(data, mimeType, encoding, baseUrl, historyUrl, result);
- else
- result.success(false);
- }
+ if (webView != null) {
+ String data = (String) call.argument("data");
+ String mimeType = (String) call.argument("mimeType");
+ String encoding = (String) call.argument("encoding");
+ String baseUrl = (String) call.argument("baseUrl");
+ String historyUrl = (String) call.argument("historyUrl");
+ webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
+ }
+ result.success(true);
break;
case "loadFile":
- if (webView != null)
- webView.loadFile((String) call.argument("url"), (Map) call.argument("headers"), result);
- else
- result.success(false);
+ if (webView != null) {
+ String assetFilePath = (String) call.argument("url");
+ try {
+ webView.loadFile(assetFilePath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ result.error(LOG_TAG, e.getMessage(), null);
+ return;
+ }
+ }
+ result.success(true);
break;
case "evaluateJavascript":
if (webView != null) {
String source = (String) call.argument("source");
- String contentWorldName = (String) call.argument("contentWorld");
- webView.evaluateJavascript(source, contentWorldName, result);
+ Map contentWorldMap = (Map) call.argument("contentWorld");
+ ContentWorld contentWorld = ContentWorld.fromMap(contentWorldMap);
+ webView.evaluateJavascript(source, contentWorld, new ValueCallback() {
+ @Override
+ public void onReceiveValue(String value) {
+ result.success(value);
+ }
+ });
}
else {
result.success(null);
@@ -150,11 +169,12 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
result.success(null);
break;
case "setOptions":
- if (webView != null && webView.inAppBrowserActivity != null) {
+ if (webView != null && webView.inAppBrowserDelegate != null && webView.inAppBrowserDelegate instanceof InAppBrowserActivity) {
+ InAppBrowserActivity inAppBrowserActivity = (InAppBrowserActivity) webView.inAppBrowserDelegate;
InAppBrowserOptions inAppBrowserOptions = new InAppBrowserOptions();
HashMap inAppBrowserOptionsMap = (HashMap) call.argument("options");
inAppBrowserOptions.parse(inAppBrowserOptionsMap);
- webView.inAppBrowserActivity.setOptions(inAppBrowserOptions, inAppBrowserOptionsMap);
+ inAppBrowserActivity.setOptions(inAppBrowserOptions, inAppBrowserOptionsMap);
} else if (webView != null) {
InAppWebViewOptions inAppWebViewOptions = new InAppWebViewOptions();
HashMap inAppWebViewOptionsMap = (HashMap) call.argument("options");
@@ -164,30 +184,34 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
result.success(true);
break;
case "getOptions":
- if (webView != null && webView.inAppBrowserActivity != null) {
- result.success(webView.inAppBrowserActivity.getOptions());
+ if (webView != null && webView.inAppBrowserDelegate != null && webView.inAppBrowserDelegate instanceof InAppBrowserActivity) {
+ InAppBrowserActivity inAppBrowserActivity = (InAppBrowserActivity) webView.inAppBrowserDelegate;
+ result.success(inAppBrowserActivity.getOptions());
} else {
result.success((webView != null) ? webView.getOptions() : null);
}
break;
case "close":
- if (webView != null && webView.inAppBrowserActivity != null) {
- webView.inAppBrowserActivity.close(result);
+ if (webView != null && webView.inAppBrowserDelegate != null && webView.inAppBrowserDelegate instanceof InAppBrowserActivity) {
+ InAppBrowserActivity inAppBrowserActivity = (InAppBrowserActivity) webView.inAppBrowserDelegate;
+ inAppBrowserActivity.close(result);
} else {
result.notImplemented();
}
break;
case "show":
- if (webView != null && webView.inAppBrowserActivity != null) {
- webView.inAppBrowserActivity.show();
+ if (webView != null && webView.inAppBrowserDelegate != null && webView.inAppBrowserDelegate instanceof InAppBrowserActivity) {
+ InAppBrowserActivity inAppBrowserActivity = (InAppBrowserActivity) webView.inAppBrowserDelegate;
+ inAppBrowserActivity.show();
result.success(true);
} else {
result.notImplemented();
}
break;
case "hide":
- if (webView != null && webView.inAppBrowserActivity != null) {
- webView.inAppBrowserActivity.hide();
+ if (webView != null && webView.inAppBrowserDelegate != null && webView.inAppBrowserDelegate instanceof InAppBrowserActivity) {
+ InAppBrowserActivity inAppBrowserActivity = (InAppBrowserActivity) webView.inAppBrowserDelegate;
+ inAppBrowserActivity.hide();
result.success(true);
} else {
result.notImplemented();
@@ -409,7 +433,7 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
break;
case "getCertificate":
if (webView != null) {
- result.success(webView.getCertificateMap());
+ result.success(SslCertificateExt.toMap(webView.getCertificate()));
} else {
result.success(null);
}
@@ -421,24 +445,34 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
result.success(true);
break;
case "addUserScript":
- if (webView != null) {
- Map userScript = (Map) call.argument("userScript");
- result.success(webView.addUserScript(userScript));
+ if (webView != null && webView.userContentController != null) {
+ Map userScriptMap = (Map) call.argument("userScript");
+ UserScript userScript = UserScript.fromMap(userScriptMap);
+ result.success(webView.userContentController.addUserOnlyScript(userScript));
} else {
result.success(false);
}
break;
case "removeUserScript":
- if (webView != null) {
+ if (webView != null && webView.userContentController != null) {
Integer index = (Integer) call.argument("index");
- result.success(webView.removeUserScript(index));
+ Map userScriptMap = (Map) call.argument("userScript");
+ UserScript userScript = UserScript.fromMap(userScriptMap);
+ result.success(webView.userContentController.removePluginScriptAt(index, userScript.getInjectionTime()));
} else {
result.success(false);
}
break;
+ case "removeUserScriptsByGroupName":
+ if (webView != null && webView.userContentController != null) {
+ String groupName = (String) call.argument("groupName");
+ webView.userContentController.removeUserOnlyScriptsByGroupName(groupName);
+ }
+ result.success(true);
+ break;
case "removeAllUserScripts":
- if (webView != null) {
- webView.removeAllUserScripts();
+ if (webView != null && webView.userContentController != null) {
+ webView.userContentController.removeAllUserOnlyScripts();
}
result.success(true);
break;
@@ -446,13 +480,31 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
String functionBody = (String) call.argument("functionBody");
Map functionArguments = (Map) call.argument("arguments");
- String contentWorldName = (String) call.argument("contentWorld");
- webView.callAsyncJavaScript(functionBody, functionArguments, contentWorldName, result);
+ Map contentWorldMap = (Map) call.argument("contentWorld");
+ ContentWorld contentWorld = ContentWorld.fromMap(contentWorldMap);
+ webView.callAsyncJavaScript(functionBody, functionArguments, contentWorld, new ValueCallback() {
+ @Override
+ public void onReceiveValue(String value) {
+ result.success(value);
+ }
+ });
}
else {
result.success(null);
}
break;
+ case "isSecureContext":
+ if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ webView.isSecureContext(new ValueCallback() {
+ @Override
+ public void onReceiveValue(Boolean value) {
+ result.success(value);
+ }
+ });
+ } else {
+ result.success(false);
+ }
+ break;
default:
result.notImplemented();
}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java
index 56d1b481..45e3a233 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java
@@ -7,9 +7,8 @@ import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
-import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserActivity;
-import com.pichillilorenzo.flutter_inappwebview.InAppWebView.FlutterWebView;
-import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView;
+import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebView;
+import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
import org.json.JSONArray;
import org.json.JSONException;
@@ -22,58 +21,27 @@ import io.flutter.plugin.common.MethodChannel;
public class JavaScriptBridgeInterface {
private static final String LOG_TAG = "JSBridgeInterface";
- public static final String name = "flutter_inappwebview";
- private FlutterWebView flutterWebView;
- private InAppBrowserActivity inAppBrowserActivity;
- public MethodChannel channel;
+ private InAppWebView inAppWebView;
+ private final MethodChannel channel;
- // https://github.com/tildeio/rsvp.js
- public static final String promisePolyfillJS = "if (window.Promise == null) {" +
- " !function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?e(exports):\"function\"==typeof define&&define.amd?define([\"exports\"],e):e(t.RSVP={})}(this,function(t){\"use strict\";function e(t){var e=t._promiseCallbacks;return e||(e=t._promiseCallbacks={}),e}var r={mixin:function(t){return t.on=this.on,t.off=this.off,t.trigger=this.trigger,t._promiseCallbacks=void 0,t},on:function(t,r){if(\"function\"!=typeof r)throw new TypeError(\"Callback must be a function\");var n=e(this),o=n[t];o||(o=n[t]=[]),-1===o.indexOf(r)&&o.push(r)},off:function(t,r){var n=e(this);if(r){var o=n[t],i=o.indexOf(r);-1!==i&&o.splice(i,1)}else n[t]=[]},trigger:function(t,r,n){var o=e(this)[t];if(o)for(var i=0;i2&&void 0!==arguments[2])||arguments[2],o=arguments[3];return function(t,e){if(!t)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return!e||\"object\"!=typeof e&&\"function\"!=typeof e?t:e}(this,t.call(this,e,r,n,o))}return function(t,e){if(\"function\"!=typeof e&&null!==e)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),e.prototype._init=function(t,e){this._result={},this._enumerate(e)},e.prototype._enumerate=function(t){var e=Object.keys(t),r=e.length,n=this.promise;this._remaining=r;for(var o=void 0,i=void 0,s=0;n._state===a&&s obj = new HashMap<>();
obj.put("handlerName", handlerName);
obj.put("args", args);
@@ -97,19 +63,36 @@ public class JavaScriptBridgeInterface {
handler.post(new Runnable() {
@Override
public void run() {
+ if (inAppWebView == null) {
+ // The webview has already been disposed, ignore.
+ return;
+ }
if (handlerName.equals("onPrint") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- webView.printCurrentPage();
+ inAppWebView.printCurrentPage();
} else if (handlerName.equals("callAsyncJavaScript")) {
try {
JSONArray arguments = new JSONArray(args);
JSONObject jsonObject = arguments.getJSONObject(0);
String resultUuid = jsonObject.getString("resultUuid");
- if (webView.callAsyncJavaScriptResults.containsKey(resultUuid)) {
- MethodChannel.Result callAsyncJavaScriptResult = webView.callAsyncJavaScriptResults.get(resultUuid);
- callAsyncJavaScriptResult.success(jsonObject.toString());
-
- webView.callAsyncJavaScriptResults.remove(resultUuid);
+ ValueCallback callAsyncJavaScriptCallback = inAppWebView.callAsyncJavaScriptCallbacks.get(resultUuid);
+ if (callAsyncJavaScriptCallback != null) {
+ callAsyncJavaScriptCallback.onReceiveValue(jsonObject.toString());
+ inAppWebView.callAsyncJavaScriptCallbacks.remove(resultUuid);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return;
+ } else if (handlerName.equals("evaluateJavaScriptWithContentWorld")) {
+ try {
+ JSONArray arguments = new JSONArray(args);
+ JSONObject jsonObject = arguments.getJSONObject(0);
+ String resultUuid = jsonObject.getString("resultUuid");
+ ValueCallback evaluateJavaScriptCallback = inAppWebView.evaluateJavaScriptContentWorldCallbacks.get(resultUuid);
+ if (evaluateJavaScriptCallback != null) {
+ evaluateJavaScriptCallback.onReceiveValue(jsonObject.has("value") ? jsonObject.get("value").toString() : "null");
+ inAppWebView.evaluateJavaScriptContentWorldCallbacks.remove(resultUuid);
}
} catch (JSONException e) {
e.printStackTrace();
@@ -117,18 +100,19 @@ public class JavaScriptBridgeInterface {
return;
}
+ // invoke flutter javascript handler and send back flutter data as a JSON Object to javascript
channel.invokeMethod("onCallJsHandler", obj, new MethodChannel.Result() {
@Override
public void success(Object json) {
- if (webView == null) {
+ if (inAppWebView == null) {
// The webview has already been disposed, ignore.
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- webView.evaluateJavascript("if(window." + name + "[" + _callHandlerID + "] != null) {window." + name + "[" + _callHandlerID + "](" + json + "); delete window." + name + "[" + _callHandlerID + "];}", (ValueCallback) null);
+ inAppWebView.evaluateJavascript("if(window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "] != null) {window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "](" + json + "); delete window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "];}", (ValueCallback) null);
}
else {
- webView.loadUrl("javascript:if(window." + name + "[" + _callHandlerID + "] != null) {window." + name + "[" + _callHandlerID + "](" + json + "); delete window." + name + "[" + _callHandlerID + "];}");
+ inAppWebView.loadUrl("javascript:if(window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "] != null) {window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "](" + json + "); delete window." + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "[" + _callHandlerID + "];}");
}
}
@@ -147,12 +131,6 @@ public class JavaScriptBridgeInterface {
}
public void dispose() {
- channel.setMethodCallHandler(null);
- if (inAppBrowserActivity != null) {
- inAppBrowserActivity = null;
- }
- if (flutterWebView != null) {
- flutterWebView = null;
- }
+ inAppWebView = null;
}
}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java
index 7a3a88b1..4a0b45b1 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java
@@ -8,8 +8,10 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Parcelable;
+import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import org.json.JSONArray;
@@ -27,12 +29,15 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
@@ -244,7 +249,7 @@ public class Util {
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
- public static String JSONStringify(Object value) {
+ public static String JSONStringify(@Nullable Object value) {
if (value == null) {
return "null";
}
@@ -258,4 +263,15 @@ public class Util {
return JSONObject.wrap(value).toString();
}
}
+
+ public static boolean objEquals(@Nullable Object a, @Nullable Object b) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ return Objects.equals(a, b);
+ }
+ return (a == b) || (a != null && a.equals(b));
+ }
+
+ public static String replaceAll(String s, String oldString, String newString) {
+ return TextUtils.join(newString, s.split(Pattern.quote(oldString)));
+ }
}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ActionBroadcastReceiver.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java
similarity index 93%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ActionBroadcastReceiver.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java
index f2a439f6..04557756 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ActionBroadcastReceiver.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java
@@ -1,10 +1,9 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.util.Log;
import com.pichillilorenzo.flutter_inappwebview.Shared;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ChromeCustomTabsActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java
similarity index 97%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ChromeCustomTabsActivity.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java
index 85d9fdae..0de7ce9b 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ChromeCustomTabsActivity.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.app.Activity;
import android.app.PendingIntent;
@@ -6,7 +6,6 @@ import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
import androidx.browser.customtabs.CustomTabsCallback;
import androidx.browser.customtabs.CustomTabsIntent;
@@ -16,7 +15,6 @@ import androidx.browser.customtabs.CustomTabsSession;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
-import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -145,7 +143,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
if (options.addDefaultShareMenuItem)
builder.addDefaultShareMenuItem();
- if (!options.toolbarBackgroundColor.isEmpty())
+ if (options.toolbarBackgroundColor != null && !options.toolbarBackgroundColor.isEmpty())
builder.setToolbarColor(Color.parseColor(options.toolbarBackgroundColor));
builder.setShowTitle(options.showTitle);
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ChromeCustomTabsOptions.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsOptions.java
similarity index 94%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ChromeCustomTabsOptions.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsOptions.java
index 005e9fa7..7e04628b 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ChromeCustomTabsOptions.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsOptions.java
@@ -1,7 +1,9 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.content.Intent;
+import androidx.annotation.Nullable;
+
import com.pichillilorenzo.flutter_inappwebview.Options;
import java.util.HashMap;
@@ -13,7 +15,8 @@ public class ChromeCustomTabsOptions implements Options options = (HashMap) call.argument("options");
+ List> menuItemList = (List>) call.argument("menuItemList");
+ open(activity, uuid, url, options, menuItemList, result);
+ }
+ break;
+ case "isAvailable":
+ result.success(CustomTabActivityHelper.isAvailable(activity));
+ break;
+ default:
+ result.notImplemented();
+ }
+ }
+
+ public void open(Activity activity, String uuid, String url, HashMap options,
+ List> menuItemList, MethodChannel.Result result) {
+
+ Intent intent = null;
+ Bundle extras = new Bundle();
+ extras.putString("fromActivity", activity.getClass().getName());
+ extras.putString("url", url);
+ extras.putBoolean("isData", false);
+ extras.putString("uuid", uuid);
+ extras.putSerializable("options", options);
+ extras.putSerializable("menuItemList", (Serializable) menuItemList);
+
+ if (CustomTabActivityHelper.isAvailable(activity)) {
+ intent = new Intent(activity, ChromeCustomTabsActivity.class);
+ intent.putExtras(extras);
+ activity.startActivity(intent);
+ result.success(true);
+ return;
+ }
+
+ result.error(LOG_TAG, "ChromeCustomTabs is not available!", null);
+ }
+
+ public void dispose() {
+ channel.setMethodCallHandler(null);
+ }
+}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/CustomTabActivityHelper.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/CustomTabActivityHelper.java
similarity index 98%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/CustomTabActivityHelper.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/CustomTabActivityHelper.java
index 95bc7fea..31c348c3 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/CustomTabActivityHelper.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/CustomTabActivityHelper.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.app.Activity;
import android.net.Uri;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/CustomTabsHelper.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/CustomTabsHelper.java
similarity index 98%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/CustomTabsHelper.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/CustomTabsHelper.java
index a807e5f2..c3f0198d 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/CustomTabsHelper.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/CustomTabsHelper.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.content.Context;
import android.content.Intent;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/KeepAliveService.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/KeepAliveService.java
similarity index 85%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/KeepAliveService.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/KeepAliveService.java
index 5b936b1c..b1302f99 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/KeepAliveService.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/KeepAliveService.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.app.Service;
import android.content.Intent;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ServiceConnection.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ServiceConnection.java
similarity index 94%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ServiceConnection.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ServiceConnection.java
index 0cbea7cf..33c3058f 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ServiceConnection.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ServiceConnection.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import android.content.ComponentName;
import androidx.browser.customtabs.CustomTabsClient;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ServiceConnectionCallback.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ServiceConnectionCallback.java
similarity index 86%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ServiceConnectionCallback.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ServiceConnectionCallback.java
index fdf94209..6f792300 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ChromeCustomTabs/ServiceConnectionCallback.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ServiceConnectionCallback.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs;
+package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
import androidx.browser.customtabs.CustomTabsClient;
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlocker.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlocker.java
new file mode 100755
index 00000000..21c4af73
--- /dev/null
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlocker.java
@@ -0,0 +1,59 @@
+package com.pichillilorenzo.flutter_inappwebview.content_blocker;
+
+import androidx.annotation.NonNull;
+
+public class ContentBlocker {
+ @NonNull
+ private ContentBlockerTrigger trigger;
+ @NonNull
+ private ContentBlockerAction action;
+
+ public ContentBlocker (@NonNull ContentBlockerTrigger trigger, @NonNull ContentBlockerAction action) {
+ this.trigger = trigger;
+ this.action = action;
+ }
+
+ @NonNull
+ public ContentBlockerTrigger getTrigger() {
+ return trigger;
+ }
+
+ public void setTrigger(@NonNull ContentBlockerTrigger trigger) {
+ this.trigger = trigger;
+ }
+
+ @NonNull
+ public ContentBlockerAction getAction() {
+ return action;
+ }
+
+ public void setAction(@NonNull ContentBlockerAction action) {
+ this.action = action;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ContentBlocker that = (ContentBlocker) o;
+
+ if (!trigger.equals(that.trigger)) return false;
+ return action.equals(that.action);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = trigger.hashCode();
+ result = 31 * result + action.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ContentBlocker{" +
+ "trigger=" + trigger +
+ ", action=" + action +
+ '}';
+ }
+}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerAction.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerAction.java
new file mode 100755
index 00000000..072413c0
--- /dev/null
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerAction.java
@@ -0,0 +1,71 @@
+package com.pichillilorenzo.flutter_inappwebview.content_blocker;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Map;
+
+public class ContentBlockerAction {
+ @NonNull
+ private ContentBlockerActionType type;
+
+ @Nullable
+ private String selector;
+
+ ContentBlockerAction(@NonNull ContentBlockerActionType type, @Nullable String selector) {
+ this.type = type;
+ if (this.type.equals(ContentBlockerActionType.CSS_DISPLAY_NONE)) {
+ assert(selector != null);
+ }
+ this.selector = selector;
+ }
+
+ public static ContentBlockerAction fromMap(Map map) {
+ ContentBlockerActionType type = ContentBlockerActionType.fromValue((String) map.get("type"));
+ String selector = (String) map.get("selector");
+ return new ContentBlockerAction(type, selector);
+ }
+
+ @NonNull
+ public ContentBlockerActionType getType() {
+ return type;
+ }
+
+ public void setType(@NonNull ContentBlockerActionType type) {
+ this.type = type;
+ }
+
+ public String getSelector() {
+ return selector;
+ }
+
+ public void setSelector(String selector) {
+ this.selector = selector;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ContentBlockerAction that = (ContentBlockerAction) o;
+
+ if (type != that.type) return false;
+ return selector != null ? selector.equals(that.selector) : that.selector == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = type.hashCode();
+ result = 31 * result + (selector != null ? selector.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ContentBlockerAction{" +
+ "type=" + type +
+ ", selector='" + selector + '\'' +
+ '}';
+ }
+}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerActionType.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerActionType.java
similarity index 90%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerActionType.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerActionType.java
index 8a8601ad..8ed16c8f 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerActionType.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerActionType.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ContentBlocker;
+package com.pichillilorenzo.flutter_inappwebview.content_blocker;
public enum ContentBlockerActionType {
BLOCK ("block"),
@@ -23,6 +23,7 @@ public enum ContentBlockerActionType {
throw new IllegalArgumentException("No enum constant: " + value);
}
+ @Override
public String toString() {
return this.value;
}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java
similarity index 88%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerHandler.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java
index 546dcd45..aac86a7e 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerHandler.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ContentBlocker;
+package com.pichillilorenzo.flutter_inappwebview.content_blocker;
import android.os.Build;
import android.os.Handler;
@@ -6,7 +6,7 @@ import android.os.Looper;
import android.util.Log;
import android.webkit.WebResourceResponse;
-import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView;
+import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebView;
import com.pichillilorenzo.flutter_inappwebview.Util;
import java.io.ByteArrayInputStream;
@@ -21,7 +21,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
-import io.flutter.plugin.common.MethodChannel;
import okhttp3.Request;
import okhttp3.Response;
@@ -64,23 +63,23 @@ public class ContentBlockerHandler {
List ruleListCopy = new CopyOnWriteArrayList(ruleList);
for (ContentBlocker contentBlocker : ruleListCopy) {
- ContentBlockerTrigger trigger = contentBlocker.trigger;
- List resourceTypes = trigger.resourceType;
+ ContentBlockerTrigger trigger = contentBlocker.getTrigger();
+ List resourceTypes = trigger.getResourceType();
if (resourceTypes.contains(ContentBlockerTriggerResourceType.IMAGE) && !resourceTypes.contains(ContentBlockerTriggerResourceType.SVG_DOCUMENT)) {
resourceTypes.add(ContentBlockerTriggerResourceType.SVG_DOCUMENT);
}
- ContentBlockerAction action = contentBlocker.action;
+ ContentBlockerAction action = contentBlocker.getAction();
- Matcher m = trigger.urlFilterPatternCompiled.matcher(url);
+ Matcher m = trigger.getUrlFilterPatternCompiled().matcher(url);
if (m.matches()) {
if (!resourceTypes.isEmpty() && !resourceTypes.contains(responseResourceType)) {
return null;
}
- if (!trigger.ifDomain.isEmpty()) {
+ if (!trigger.getIfDomain().isEmpty()) {
boolean matchFound = false;
- for (String domain : trigger.ifDomain) {
+ for (String domain : trigger.getIfDomain()) {
if ((domain.startsWith("*") && host.endsWith(domain.replace("*", ""))) || domain.equals(host)) {
matchFound = true;
break;
@@ -89,14 +88,14 @@ public class ContentBlockerHandler {
if (!matchFound)
return null;
}
- if (!trigger.unlessDomain.isEmpty()) {
- for (String domain : trigger.unlessDomain)
+ if (!trigger.getUnlessDomain().isEmpty()) {
+ for (String domain : trigger.getUnlessDomain())
if ((domain.startsWith("*") && host.endsWith(domain.replace("*", ""))) || domain.equals(host))
return null;
}
final String[] webViewUrl = new String[1];
- if (!trigger.loadType.isEmpty() || !trigger.ifTopUrl.isEmpty() || !trigger.unlessTopUrl.isEmpty()) {
+ if (!trigger.getLoadType().isEmpty() || !trigger.getIfTopUrl().isEmpty() || !trigger.getUnlessTopUrl().isEmpty()) {
final CountDownLatch latch = new CountDownLatch(1);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@@ -110,19 +109,19 @@ public class ContentBlockerHandler {
}
if (webViewUrl[0] != null) {
- if (!trigger.loadType.isEmpty()) {
+ if (!trigger.getLoadType().isEmpty()) {
URI cUrl = new URI(webViewUrl[0]);
String cHost = cUrl.getHost();
int cPort = cUrl.getPort();
String cScheme = cUrl.getScheme();
- if ( (trigger.loadType.contains("first-party") && cHost != null && !(cScheme.equals(scheme) && cHost.equals(host) && cPort == port)) ||
- (trigger.loadType.contains("third-party") && cHost != null && cHost.equals(host)) )
+ if ( (trigger.getLoadType().contains("first-party") && cHost != null && !(cScheme.equals(scheme) && cHost.equals(host) && cPort == port)) ||
+ (trigger.getLoadType().contains("third-party") && cHost != null && cHost.equals(host)) )
return null;
}
- if (!trigger.ifTopUrl.isEmpty()) {
+ if (!trigger.getIfTopUrl().isEmpty()) {
boolean matchFound = false;
- for (String topUrl : trigger.ifTopUrl) {
+ for (String topUrl : trigger.getIfTopUrl()) {
if (webViewUrl[0].startsWith(topUrl)) {
matchFound = true;
break;
@@ -131,20 +130,20 @@ public class ContentBlockerHandler {
if (!matchFound)
return null;
}
- if (!trigger.unlessTopUrl.isEmpty()) {
- for (String topUrl : trigger.unlessTopUrl)
+ if (!trigger.getUnlessTopUrl().isEmpty()) {
+ for (String topUrl : trigger.getUnlessTopUrl())
if (webViewUrl[0].startsWith(topUrl))
return null;
}
}
- switch (action.type) {
+ switch (action.getType()) {
case BLOCK:
return new WebResourceResponse("", "", null);
case CSS_DISPLAY_NONE:
- final String cssSelector = action.selector;
+ final String cssSelector = action.getSelector();
final String jsScript = "(function(d) { " +
" function hide () { " +
" if (!d.getElementById('css-display-none-style')) { " +
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java
new file mode 100755
index 00000000..8310ede1
--- /dev/null
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java
@@ -0,0 +1,184 @@
+package com.pichillilorenzo.flutter_inappwebview.content_blocker;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class ContentBlockerTrigger {
+
+ @NonNull
+ private String urlFilter;
+ private Pattern urlFilterPatternCompiled;
+ private Boolean urlFilterIsCaseSensitive;
+ private List resourceType = new ArrayList<>();
+ private List ifDomain = new ArrayList<>();
+ private List unlessDomain = new ArrayList<>();
+ private List loadType = new ArrayList<>();
+ private List ifTopUrl = new ArrayList<>();
+ private List unlessTopUrl = new ArrayList<>();
+
+ public ContentBlockerTrigger(@NonNull String urlFilter, @Nullable Boolean urlFilterIsCaseSensitive, @Nullable List resourceType,
+ @Nullable List ifDomain, @Nullable List unlessDomain, @Nullable List loadType,
+ @Nullable List ifTopUrl, @Nullable List unlessTopUrl) {
+ this.urlFilter = urlFilter;
+ this.urlFilterPatternCompiled = Pattern.compile(this.urlFilter);
+
+ this.resourceType = resourceType != null ? resourceType : this.resourceType;
+ this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive != null ? urlFilterIsCaseSensitive : false;
+ this.ifDomain = ifDomain != null ? ifDomain : this.ifDomain;
+ this.unlessDomain = unlessDomain != null ? unlessDomain : this.unlessDomain;
+ if ((!(this.ifDomain.isEmpty() || this.unlessDomain.isEmpty()) != false))
+ throw new AssertionError();
+ this.loadType = loadType != null ? loadType : this.loadType;
+ if ((this.loadType.size() > 2)) throw new AssertionError();
+ this.ifTopUrl = ifTopUrl != null ? ifTopUrl : this.ifTopUrl;
+ this.unlessTopUrl = unlessTopUrl != null ? unlessTopUrl : this.unlessTopUrl;
+ if ((!(this.ifTopUrl.isEmpty() || this.unlessTopUrl.isEmpty()) != false))
+ throw new AssertionError();
+ }
+
+ public static ContentBlockerTrigger fromMap(Map map) {
+ String urlFilter = (String) map.get("url-filter");
+ Boolean urlFilterIsCaseSensitive = (Boolean) map.get("url-filter-is-case-sensitive");
+ List resourceTypeStringList = (List) map.get("resource-type");
+ List resourceType = new ArrayList<>();
+ if (resourceTypeStringList != null) {
+ for (String type : resourceTypeStringList) {
+ resourceType.add(ContentBlockerTriggerResourceType.fromValue(type));
+ }
+ } else {
+ resourceType.addAll(Arrays.asList(ContentBlockerTriggerResourceType.values()));
+ }
+ List ifDomain = (List) map.get("if-domain");
+ List unlessDomain = (List) map.get("unless-domain");
+ List loadType = (List) map.get("load-type");
+ List ifTopUrl = (List) map.get("if-top-url");
+ List unlessTopUrl = (List) map.get("unless-top-url");
+ return new ContentBlockerTrigger(urlFilter, urlFilterIsCaseSensitive, resourceType, ifDomain, unlessDomain, loadType, ifTopUrl, unlessTopUrl);
+ }
+
+ @NonNull
+ public String getUrlFilter() {
+ return urlFilter;
+ }
+
+ public void setUrlFilter(@NonNull String urlFilter) {
+ this.urlFilter = urlFilter;
+ }
+
+ public Pattern getUrlFilterPatternCompiled() {
+ return urlFilterPatternCompiled;
+ }
+
+ public void setUrlFilterPatternCompiled(Pattern urlFilterPatternCompiled) {
+ this.urlFilterPatternCompiled = urlFilterPatternCompiled;
+ }
+
+ public Boolean getUrlFilterIsCaseSensitive() {
+ return urlFilterIsCaseSensitive;
+ }
+
+ public void setUrlFilterIsCaseSensitive(Boolean urlFilterIsCaseSensitive) {
+ this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive;
+ }
+
+ public List getResourceType() {
+ return resourceType;
+ }
+
+ public void setResourceType(List resourceType) {
+ this.resourceType = resourceType;
+ }
+
+ public List getIfDomain() {
+ return ifDomain;
+ }
+
+ public void setIfDomain(List ifDomain) {
+ this.ifDomain = ifDomain;
+ }
+
+ public List getUnlessDomain() {
+ return unlessDomain;
+ }
+
+ public void setUnlessDomain(List unlessDomain) {
+ this.unlessDomain = unlessDomain;
+ }
+
+ public List getLoadType() {
+ return loadType;
+ }
+
+ public void setLoadType(List loadType) {
+ this.loadType = loadType;
+ }
+
+ public List getIfTopUrl() {
+ return ifTopUrl;
+ }
+
+ public void setIfTopUrl(List ifTopUrl) {
+ this.ifTopUrl = ifTopUrl;
+ }
+
+ public List getUnlessTopUrl() {
+ return unlessTopUrl;
+ }
+
+ public void setUnlessTopUrl(List unlessTopUrl) {
+ this.unlessTopUrl = unlessTopUrl;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ContentBlockerTrigger that = (ContentBlockerTrigger) o;
+
+ if (!urlFilter.equals(that.urlFilter)) return false;
+ if (!urlFilterPatternCompiled.equals(that.urlFilterPatternCompiled)) return false;
+ if (!urlFilterIsCaseSensitive.equals(that.urlFilterIsCaseSensitive)) return false;
+ if (!resourceType.equals(that.resourceType)) return false;
+ if (!ifDomain.equals(that.ifDomain)) return false;
+ if (!unlessDomain.equals(that.unlessDomain)) return false;
+ if (!loadType.equals(that.loadType)) return false;
+ if (!ifTopUrl.equals(that.ifTopUrl)) return false;
+ return unlessTopUrl.equals(that.unlessTopUrl);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = urlFilter.hashCode();
+ result = 31 * result + urlFilterPatternCompiled.hashCode();
+ result = 31 * result + urlFilterIsCaseSensitive.hashCode();
+ result = 31 * result + resourceType.hashCode();
+ result = 31 * result + ifDomain.hashCode();
+ result = 31 * result + unlessDomain.hashCode();
+ result = 31 * result + loadType.hashCode();
+ result = 31 * result + ifTopUrl.hashCode();
+ result = 31 * result + unlessTopUrl.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ContentBlockerTrigger{" +
+ "urlFilter='" + urlFilter + '\'' +
+ ", urlFilterPatternCompiled=" + urlFilterPatternCompiled +
+ ", urlFilterIsCaseSensitive=" + urlFilterIsCaseSensitive +
+ ", resourceType=" + resourceType +
+ ", ifDomain=" + ifDomain +
+ ", unlessDomain=" + unlessDomain +
+ ", loadType=" + loadType +
+ ", ifTopUrl=" + ifTopUrl +
+ ", unlessTopUrl=" + unlessTopUrl +
+ '}';
+ }
+}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerTriggerResourceType.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTriggerResourceType.java
similarity index 91%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerTriggerResourceType.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTriggerResourceType.java
index fc78ead5..0f63196d 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ContentBlocker/ContentBlockerTriggerResourceType.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTriggerResourceType.java
@@ -1,4 +1,4 @@
-package com.pichillilorenzo.flutter_inappwebview.ContentBlocker;
+package com.pichillilorenzo.flutter_inappwebview.content_blocker;
public enum ContentBlockerTriggerResourceType {
DOCUMENT ("document"),
@@ -29,6 +29,7 @@ public enum ContentBlockerTriggerResourceType {
throw new IllegalArgumentException("No enum constant: " + value);
}
+ @Override
public String toString() {
return this.value;
}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabase.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabase.java
new file mode 100755
index 00000000..c85a4d60
--- /dev/null
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabase.java
@@ -0,0 +1,95 @@
+package com.pichillilorenzo.flutter_inappwebview.credential_database;
+
+import android.content.Context;
+
+import com.pichillilorenzo.flutter_inappwebview.types.URLCredential;
+import com.pichillilorenzo.flutter_inappwebview.types.URLProtectionSpace;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CredentialDatabase {
+
+ private static CredentialDatabase instance;
+ static final String LOG_TAG = "CredentialDatabase";
+
+ // If you change the database schema, you must increment the database version.
+ public static final int DATABASE_VERSION = 2;
+ public static final String DATABASE_NAME = "CredentialDatabase.db";
+
+ public URLProtectionSpaceDao protectionSpaceDao;
+ public URLCredentialDao credentialDao;
+ public CredentialDatabaseHelper db;
+
+ private CredentialDatabase() {}
+
+ private CredentialDatabase(CredentialDatabaseHelper db, URLProtectionSpaceDao protectionSpaceDao, URLCredentialDao credentialDao) {
+ this.db = db;
+ this.protectionSpaceDao = protectionSpaceDao;
+ this.credentialDao = credentialDao;
+ }
+
+ public static CredentialDatabase getInstance(Context context) {
+ if (instance != null)
+ return instance;
+ CredentialDatabaseHelper db = new CredentialDatabaseHelper(context);
+ instance = new CredentialDatabase(db, new URLProtectionSpaceDao(db), new URLCredentialDao(db));
+ return instance;
+ }
+
+ public List getHttpAuthCredentials(String host, String protocol, String realm, Integer port) {
+ List credentials = new ArrayList<>();
+ URLProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
+ if (protectionSpace != null) {
+ credentials = credentialDao.getAllByProtectionSpaceId(protectionSpace.getId());
+ }
+ return credentials;
+ }
+
+ public void clearAllAuthCredentials() {
+ db.clearAllTables(db.getWritableDatabase());
+ }
+
+ public void removeHttpAuthCredentials(String host, String protocol, String realm, Integer port) {
+ URLProtectionSpace URLProtectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
+ if (URLProtectionSpace != null) {
+ protectionSpaceDao.delete(URLProtectionSpace);
+ }
+ }
+
+ public void removeHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
+ URLProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
+ if (protectionSpace != null) {
+ URLCredential credential = credentialDao.find(username, password, protectionSpace.getId());
+ credentialDao.delete(credential);
+ }
+ }
+
+ public void setHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
+ URLProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
+ Long protectionSpaceId;
+ if (protectionSpace == null) {
+ protectionSpaceId = protectionSpaceDao.insert(new URLProtectionSpace(null, host, protocol, realm, port));
+ } else {
+ protectionSpaceId = protectionSpace.getId();
+ }
+
+ URLCredential credential = credentialDao.find(username, password, protectionSpaceId);
+ if (credential != null) {
+ boolean needUpdate = false;
+ if (!credential.getUsername().equals(username)) {
+ credential.setUsername(username);
+ needUpdate = true;
+ }
+ if (!credential.getPassword().equals(password)) {
+ credential.setPassword(password);
+ needUpdate = true;
+ }
+ if (needUpdate)
+ credentialDao.update(credential);
+ } else {
+ credential = new URLCredential(null, username, password, protectionSpaceId);
+ credential.setId(credentialDao.insert(credential));
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabaseHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java
similarity index 82%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabaseHandler.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java
index 54ef1e5e..794968ec 100755
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/CredentialDatabaseHandler.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java
@@ -1,13 +1,14 @@
-package com.pichillilorenzo.flutter_inappwebview;
+package com.pichillilorenzo.flutter_inappwebview.credential_database;
import android.os.Build;
import android.webkit.WebViewDatabase;
+import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
-import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.Credential;
-import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.CredentialDatabase;
-import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.ProtectionSpace;
+import com.pichillilorenzo.flutter_inappwebview.Shared;
+import com.pichillilorenzo.flutter_inappwebview.types.URLCredential;
+import com.pichillilorenzo.flutter_inappwebview.types.URLProtectionSpace;
import java.util.ArrayList;
import java.util.HashMap;
@@ -17,7 +18,6 @@ import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
-import io.flutter.plugin.common.PluginRegistry;
@RequiresApi(api = Build.VERSION_CODES.O)
public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandler {
@@ -34,15 +34,15 @@ public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandle
}
@Override
- public void onMethodCall(MethodCall call, MethodChannel.Result result) {
+ public void onMethodCall(MethodCall call, @NonNull MethodChannel.Result result) {
switch (call.method) {
case "getAllAuthCredentials":
{
List