From 2ea3bee498479fec3312669987a77b9dfe0c97b4 Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Sun, 12 Nov 2023 19:51:33 +0100 Subject: [PATCH] Added getPackageName static method on ChromeSafariBrowser for Android, updated iOS and macOS WebViewChannelDelegate channel self reference --- CHANGELOG.md | 1 + .../ChromeSafariBrowserManager.java | 10 +++ .../chrome_safari_browser/custom_tabs.dart | 14 ++-- .../chrome_safari_browser_example.screen.dart | 18 +----- .../InAppWebView/WebViewChannelDelegate.swift | 64 ++++++++++++------- .../chrome_safari_browser.dart | 23 +++++++ .../InAppWebView/WebViewChannelDelegate.swift | 64 ++++++++++++------- 7 files changed, 124 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc6727a4..31439049 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Added `requestPostMessageChannel`, `postMessage`, `isEngagementSignalsApiAvailable` methods on `ChromeSafariBrowser` for Android - Added `onMessageChannelReady`, `onPostMessage`, `onVerticalScrollEvent`, `onGreatestScrollPercentageIncreased`, `onSessionEnded` events on `ChromeSafariBrowser` for Android +- Added `getPackageName` static method on `ChromeSafariBrowser` for Android ## 6.0.0-beta.26 diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java index 1df565fb..768d1b51 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.os.Bundle; import androidx.annotation.Nullable; +import androidx.browser.customtabs.CustomTabsClient; import androidx.browser.customtabs.CustomTabsIntent; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; @@ -70,6 +71,15 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl { case "getMaxToolbarItems": result.success(CustomTabsIntent.getMaxToolbarItems()); break; + case "getPackageName": + if (plugin != null && plugin.activity != null) { + ArrayList packages = (ArrayList) call.argument("packages"); + Boolean ignoreDefault = (Boolean) call.argument("ignoreDefault"); + result.success(CustomTabsClient.getPackageName(plugin.activity, packages, ignoreDefault)); + } else { + result.success(null); + } + break; default: result.notImplemented(); } diff --git a/example/integration_test/chrome_safari_browser/custom_tabs.dart b/example/integration_test/chrome_safari_browser/custom_tabs.dart index 7982a181..d62bdd88 100644 --- a/example/integration_test/chrome_safari_browser/custom_tabs.dart +++ b/example/integration_test/chrome_safari_browser/custom_tabs.dart @@ -166,11 +166,6 @@ void customTabs() { expect(chromeSafariBrowser.isOpened(), false); }); - skippableTest('getMaxToolbarItems', () async { - expect(await ChromeSafariBrowser.getMaxToolbarItems(), - greaterThanOrEqualTo(0)); - }); - skippableTest('request and send post messages', () async { var chromeSafariBrowser = MyChromeSafariBrowser(); expect(chromeSafariBrowser.isOpened(), false); @@ -217,5 +212,14 @@ void customTabs() { await expectLater(chromeSafariBrowser.closed.future, completes); expect(chromeSafariBrowser.isOpened(), false); }); + + skippableTest('getMaxToolbarItems', () async { + expect(await ChromeSafariBrowser.getMaxToolbarItems(), + greaterThanOrEqualTo(0)); + }); + + skippableTest('getPackageName', () async { + expect(await ChromeSafariBrowser.getPackageName(), isNotNull); + }); }, skip: shouldSkip); } diff --git a/example/lib/chrome_safari_browser_example.screen.dart b/example/lib/chrome_safari_browser_example.screen.dart index 5360667c..829c12ca 100755 --- a/example/lib/chrome_safari_browser_example.screen.dart +++ b/example/lib/chrome_safari_browser_example.screen.dart @@ -19,21 +19,6 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser { void onClosed() { print("ChromeSafari browser closed"); } - - @override - void onVerticalScrollEvent(bool isDirectionUp) { - print("onVerticalScrollEvent $isDirectionUp"); - } - - @override - void onGreatestScrollPercentageIncreased(int scrollPercentage) { - print("onGreatestScrollPercentageIncreased $scrollPercentage"); - } - - @override - void onSessionEnded(bool didUserInteract) { - print("onSessionEnded $didUserInteract"); - } } class ChromeSafariBrowserExampleScreen extends StatefulWidget { @@ -118,8 +103,7 @@ class _ChromeSafariBrowserExampleScreenState dismissButtonStyle: DismissButtonStyle.CLOSE, presentationStyle: ModalPresentationStyle.OVER_FULL_SCREEN)); - await Future.delayed(Duration(seconds: 5)); - widget.browser.close(); + print(await ChromeSafariBrowser.getPackageName()); }, child: Text("Open Chrome Safari Browser")), )); diff --git a/ios/Classes/InAppWebView/WebViewChannelDelegate.swift b/ios/Classes/InAppWebView/WebViewChannelDelegate.swift index 4a4f2b61..2ca6b080 100644 --- a/ios/Classes/InAppWebView/WebViewChannelDelegate.swift +++ b/ios/Classes/InAppWebView/WebViewChannelDelegate.swift @@ -882,11 +882,11 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onPermissionRequest(request: PermissionRequest, callback: PermissionRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } - channel.invokeMethod("onPermissionRequest", arguments: request.toMap(), callback: callback) + channel?.invokeMethod("onPermissionRequest", arguments: request.toMap(), callback: callback) } public class ShouldOverrideUrlLoadingCallback : BaseCallbackResult { @@ -906,11 +906,11 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func shouldOverrideUrlLoading(navigationAction: WKNavigationAction, callback: ShouldOverrideUrlLoadingCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } - channel.invokeMethod("shouldOverrideUrlLoading", arguments: navigationAction.toMap(), callback: callback) + channel?.invokeMethod("shouldOverrideUrlLoading", arguments: navigationAction.toMap(), callback: callback) } public func onLoadStart(url: String?) { @@ -961,7 +961,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge, callback: ReceivedHttpAuthRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -969,8 +969,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, callback: callback) } } } @@ -989,7 +993,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge, callback: ReceivedServerTrustAuthRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -997,8 +1001,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, callback: callback) } } } @@ -1017,7 +1025,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onReceivedClientCertRequest(challenge: ClientCertChallenge, callback: ReceivedClientCertRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1025,8 +1033,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("onReceivedClientCertRequest", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("onReceivedClientCertRequest", arguments: arguments, callback: callback) } } } @@ -1056,12 +1068,12 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onLoadResourceWithCustomScheme(request: WebResourceRequest, callback: LoadResourceWithCustomSchemeCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } let arguments: [String: Any?] = ["request": request.toMap()] - channel.invokeMethod("onLoadResourceWithCustomScheme", arguments: arguments, callback: callback) + channel?.invokeMethod("onLoadResourceWithCustomScheme", arguments: arguments, callback: callback) } public class CallJsHandlerCallback : BaseCallbackResult { @@ -1074,7 +1086,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onCallJsHandler(handlerName: String, args: String, callback: CallJsHandlerCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1082,7 +1094,7 @@ public class WebViewChannelDelegate : ChannelDelegate { "handlerName": handlerName, "args": args ] - channel.invokeMethod("onCallJsHandler", arguments: arguments, callback: callback) + channel?.invokeMethod("onCallJsHandler", arguments: arguments, callback: callback) } public class NavigationResponseCallback : BaseCallbackResult { @@ -1102,11 +1114,11 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onNavigationResponse(navigationResponse: WKNavigationResponse, callback: NavigationResponseCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } - channel.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), callback: callback) + channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), callback: callback) } public class ShouldAllowDeprecatedTLSCallback : BaseCallbackResult { @@ -1126,7 +1138,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func shouldAllowDeprecatedTLS(challenge: URLAuthenticationChallenge, callback: ShouldAllowDeprecatedTLSCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1134,8 +1146,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("shouldAllowDeprecatedTLS", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("shouldAllowDeprecatedTLS", arguments: arguments, callback: callback) } } } @@ -1178,7 +1194,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onPrintRequest(url: URL?, printJobId: String?, callback: PrintRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1186,7 +1202,7 @@ public class WebViewChannelDelegate : ChannelDelegate { "url": url?.absoluteString, "printJobId": printJobId, ] - channel.invokeMethod("onPrintRequest", arguments: arguments, callback: callback) + channel?.invokeMethod("onPrintRequest", arguments: arguments, callback: callback) } public override func dispose() { diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser.dart b/lib/src/chrome_safari_browser/chrome_safari_browser.dart index 0067875f..3090d895 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser.dart @@ -488,6 +488,29 @@ class ChromeSafariBrowser extends ChannelController { 0; } + ///Returns the preferred package to use for Custom Tabs. + ///The preferred package name is the default VIEW intent handler as long as it supports Custom Tabs. + ///To modify this preferred behavior, set [ignoreDefault] to `true` and give a + ///non empty list of package names in packages. + ///This method queries the `PackageManager` to determine which packages support the Custom Tabs API. + ///On apps that target Android 11 and above, this requires adding the following + ///package visibility elements to your manifest. + /// + ///[packages] – Ordered list of packages to test for Custom Tabs support, in decreasing order of priority. + /// + ///[ignoreDefault] – If set, the default VIEW handler won't get priority over other browsers. + /// + ///Returns the preferred package name for handling Custom Tabs, or null. + /// + ///**Supported Platforms/Implementations**: + ///- Android ([Official API - CustomTabsClient.getPackageName](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsClient#getPackageName(android.content.Context,java.util.List%3Cjava.lang.String%3E,boolean)))) + static Future getPackageName({List? packages, bool ignoreDefault = false}) async { + Map args = {}; + args.putIfAbsent("packages", () => packages); + args.putIfAbsent("ignoreDefault", () => ignoreDefault); + return await _sharedChannel.invokeMethod("getPackageName", args); + } + ///Clear associated website data accrued from browsing activity within your app. ///This includes all local storage, cached resources, and cookies. /// diff --git a/macos/Classes/InAppWebView/WebViewChannelDelegate.swift b/macos/Classes/InAppWebView/WebViewChannelDelegate.swift index b2079b8d..f41511ba 100644 --- a/macos/Classes/InAppWebView/WebViewChannelDelegate.swift +++ b/macos/Classes/InAppWebView/WebViewChannelDelegate.swift @@ -845,11 +845,11 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onPermissionRequest(request: PermissionRequest, callback: PermissionRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } - channel.invokeMethod("onPermissionRequest", arguments: request.toMap(), callback: callback) + channel?.invokeMethod("onPermissionRequest", arguments: request.toMap(), callback: callback) } public class ShouldOverrideUrlLoadingCallback : BaseCallbackResult { @@ -869,11 +869,11 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func shouldOverrideUrlLoading(navigationAction: WKNavigationAction, callback: ShouldOverrideUrlLoadingCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } - channel.invokeMethod("shouldOverrideUrlLoading", arguments: navigationAction.toMap(), callback: callback) + channel?.invokeMethod("shouldOverrideUrlLoading", arguments: navigationAction.toMap(), callback: callback) } public func onLoadStart(url: String?) { @@ -924,7 +924,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge, callback: ReceivedHttpAuthRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -932,8 +932,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, callback: callback) } } } @@ -952,7 +956,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge, callback: ReceivedServerTrustAuthRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -960,8 +964,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, callback: callback) } } } @@ -980,7 +988,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onReceivedClientCertRequest(challenge: ClientCertChallenge, callback: ReceivedClientCertRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -988,8 +996,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("onReceivedClientCertRequest", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("onReceivedClientCertRequest", arguments: arguments, callback: callback) } } } @@ -1019,12 +1031,12 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onLoadResourceWithCustomScheme(request: WebResourceRequest, callback: LoadResourceWithCustomSchemeCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } let arguments: [String: Any?] = ["request": request.toMap()] - channel.invokeMethod("onLoadResourceWithCustomScheme", arguments: arguments, callback: callback) + channel?.invokeMethod("onLoadResourceWithCustomScheme", arguments: arguments, callback: callback) } public class CallJsHandlerCallback : BaseCallbackResult { @@ -1037,7 +1049,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onCallJsHandler(handlerName: String, args: String, callback: CallJsHandlerCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1045,7 +1057,7 @@ public class WebViewChannelDelegate : ChannelDelegate { "handlerName": handlerName, "args": args ] - channel.invokeMethod("onCallJsHandler", arguments: arguments, callback: callback) + channel?.invokeMethod("onCallJsHandler", arguments: arguments, callback: callback) } public class NavigationResponseCallback : BaseCallbackResult { @@ -1065,11 +1077,11 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onNavigationResponse(navigationResponse: WKNavigationResponse, callback: NavigationResponseCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } - channel.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), callback: callback) + channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), callback: callback) } public class ShouldAllowDeprecatedTLSCallback : BaseCallbackResult { @@ -1089,7 +1101,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func shouldAllowDeprecatedTLS(challenge: URLAuthenticationChallenge, callback: ShouldAllowDeprecatedTLSCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1097,8 +1109,12 @@ public class WebViewChannelDelegate : ChannelDelegate { // https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678 DispatchQueue.global(qos: .background).async { let arguments = challenge.toMap() - DispatchQueue.main.async { - channel.invokeMethod("shouldAllowDeprecatedTLS", arguments: arguments, callback: callback) + DispatchQueue.main.async { [weak self] in + if self?.channel == nil { + callback.defaultBehaviour(nil) + return + } + self?.channel?.invokeMethod("shouldAllowDeprecatedTLS", arguments: arguments, callback: callback) } } } @@ -1141,7 +1157,7 @@ public class WebViewChannelDelegate : ChannelDelegate { } public func onPrintRequest(url: URL?, printJobId: String?, callback: PrintRequestCallback) { - guard let channel = channel else { + if channel == nil { callback.defaultBehaviour(nil) return } @@ -1149,7 +1165,7 @@ public class WebViewChannelDelegate : ChannelDelegate { "url": url?.absoluteString, "printJobId": printJobId, ] - channel.invokeMethod("onPrintRequest", arguments: arguments, callback: callback) + channel?.invokeMethod("onPrintRequest", arguments: arguments, callback: callback) } public override func dispose() {