From 49ce7d85ddf2a963337668129badf58ee4d4acc0 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 14 Jun 2022 11:27:18 -0400 Subject: [PATCH 1/4] [url_launcher] Switch to new launchUrl interface Switches the new `launchUrl*` API methods to use the new corresponding platform interface method instead of the legacy version. The legacy `launch` API still uses the old interface to ensure that its behavior doesn't change. --- .../url_launcher/url_launcher/CHANGELOG.md | 3 +- .../url_launcher/lib/src/type_conversion.dart | 32 +++++++++++++++++ .../lib/src/url_launcher_string.dart | 26 +++++--------- .../lib/src/url_launcher_uri.dart | 20 +++++------ .../url_launcher/url_launcher/pubspec.yaml | 4 +-- .../mocks/mock_url_launcher_platform.dart | 19 ++++++++-- .../test/src/url_launcher_string_test.dart | 36 +++++++------------ .../test/src/url_launcher_uri_test.dart | 33 ++++++----------- 8 files changed, 95 insertions(+), 78 deletions(-) create mode 100644 packages/url_launcher/url_launcher/lib/src/type_conversion.dart diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 182119345ccc..e5e98f658617 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 6.1.4 +* Adopts new platform interface method for launching URLs. * Ignores unnecessary import warnings in preparation for [upcoming Flutter changes](https://github.com/flutter/flutter/pull/105648). ## 6.1.3 diff --git a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart new file mode 100644 index 000000000000..970f04dced57 --- /dev/null +++ b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; + +import 'types.dart'; + +/// Converts an (app-facing) [WebViewConfiguration] to a (platform interface) +/// [InAppWebViewConfiguration]. +InAppWebViewConfiguration convertConfiguration(WebViewConfiguration config) { + return InAppWebViewConfiguration( + enableJavaScript: config.enableJavaScript, + enableDomStorage: config.enableDomStorage, + headers: config.headers, + ); +} + +/// Converts an (app-facing) [LaunchMode] to a (platform interface) +/// [PreferredLaunchMode]. +PreferredLaunchMode convertLaunchMode(LaunchMode mode) { + switch (mode) { + case LaunchMode.platformDefault: + return PreferredLaunchMode.platformDefault; + case LaunchMode.inAppWebView: + return PreferredLaunchMode.inAppWebView; + case LaunchMode.externalApplication: + return PreferredLaunchMode.externalApplication; + case LaunchMode.externalNonBrowserApplication: + return PreferredLaunchMode.externalNonBrowserApplication; + } +} diff --git a/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart b/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart index bee2a80a59c0..732f6d9209b1 100644 --- a/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart +++ b/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:url_launcher/src/type_conversion.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; import 'types.dart'; @@ -24,27 +25,18 @@ Future launchUrlString( WebViewConfiguration webViewConfiguration = const WebViewConfiguration(), String? webOnlyWindowName, }) async { - final bool isWebURL = - urlString.startsWith('http:') || urlString.startsWith('https:'); - if (mode == LaunchMode.inAppWebView && !isWebURL) { + if (mode == LaunchMode.inAppWebView && + !(urlString.startsWith('https:') || urlString.startsWith('http:'))) { throw ArgumentError.value(urlString, 'urlString', 'To use an in-app web view, you must provide an http(s) URL.'); } - final bool useWebView = mode == LaunchMode.inAppWebView || - (isWebURL && mode == LaunchMode.platformDefault); - - // TODO(stuartmorgan): Create a replacement platform interface method that - // uses something more like the new argument structure, and switch to using - // that, to support launch mode on more platforms. - return await UrlLauncherPlatform.instance.launch( + return await UrlLauncherPlatform.instance.launchUrl( urlString, - useSafariVC: useWebView, - useWebView: useWebView, - enableJavaScript: webViewConfiguration.enableJavaScript, - enableDomStorage: webViewConfiguration.enableDomStorage, - universalLinksOnly: mode == LaunchMode.externalNonBrowserApplication, - headers: webViewConfiguration.headers, - webOnlyWindowName: webOnlyWindowName, + LaunchOptions( + mode: convertLaunchMode(mode), + webViewConfiguration: convertConfiguration(webViewConfiguration), + webOnlyWindowName: webOnlyWindowName, + ), ); } diff --git a/packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart b/packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart index fc33f05e5afb..9061b517e0d5 100644 --- a/packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart +++ b/packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart @@ -7,6 +7,8 @@ import 'dart:async'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; +import 'type_conversion.dart'; + /// Passes [url] to the underlying platform for handling. /// /// [mode] support varies significantly by platform: @@ -43,20 +45,18 @@ Future launchUrl( WebViewConfiguration webViewConfiguration = const WebViewConfiguration(), String? webOnlyWindowName, }) async { - final bool isWebURL = url.scheme == 'http' || url.scheme == 'https'; - if (mode == LaunchMode.inAppWebView && !isWebURL) { + if (mode == LaunchMode.inAppWebView && + !(url.scheme == 'https' || url.scheme == 'http')) { throw ArgumentError.value(url, 'url', 'To use an in-app web view, you must provide an http(s) URL.'); } - // TODO(stuartmorgan): Use UrlLauncherPlatform directly once a new API - // that better matches these parameters has been added. For now, delegate to - // launchUrlString so that there's only one copy of the parameter translation - // logic. - return await launchUrlString( + return await UrlLauncherPlatform.instance.launchUrl( url.toString(), - mode: mode, - webViewConfiguration: webViewConfiguration, - webOnlyWindowName: webOnlyWindowName, + LaunchOptions( + mode: convertLaunchMode(mode), + webViewConfiguration: convertConfiguration(webViewConfiguration), + webOnlyWindowName: webOnlyWindowName, + ), ); } diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 2a7ddcdb1dbe..e01cd9b7a4f7 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.1.3 +version: 6.1.4 environment: sdk: ">=2.14.0 <3.0.0" @@ -34,7 +34,7 @@ dependencies: # implementations, as both are compatible. url_launcher_linux: ">=2.0.0 <4.0.0" url_launcher_macos: ">=2.0.0 <4.0.0" - url_launcher_platform_interface: ^2.0.3 + url_launcher_platform_interface: ^2.1.0 url_launcher_web: ^2.0.0 url_launcher_windows: ">=2.0.0 <4.0.0" diff --git a/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart b/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart index 5c53257f7630..b8d15c4f2fdb 100644 --- a/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart +++ b/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart @@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher_platform_interface/link.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; @@ -11,6 +12,7 @@ class MockUrlLauncher extends Fake with MockPlatformInterfaceMixin implements UrlLauncherPlatform { String? url; + PreferredLaunchMode? launchMode; bool? useSafariVC; bool? useWebView; bool? enableJavaScript; @@ -32,8 +34,9 @@ class MockUrlLauncher extends Fake void setLaunchExpectations({ required String url, - required bool? useSafariVC, - required bool useWebView, + PreferredLaunchMode? launchMode, + bool? useSafariVC, + bool? useWebView, required bool enableJavaScript, required bool enableDomStorage, required bool universalLinksOnly, @@ -41,6 +44,7 @@ class MockUrlLauncher extends Fake required String? webOnlyWindowName, }) { this.url = url; + this.launchMode = launchMode; this.useSafariVC = useSafariVC; this.useWebView = useWebView; this.enableJavaScript = enableJavaScript; @@ -88,6 +92,17 @@ class MockUrlLauncher extends Fake return response!; } + @override + Future launchUrl(String url, LaunchOptions options) async { + expect(url, this.url); + expect(options.mode, launchMode); + expect(options.webViewConfiguration.enableJavaScript, enableJavaScript); + expect(options.webViewConfiguration.enableDomStorage, enableDomStorage); + expect(options.webViewConfiguration.headers, headers); + expect(options.webOnlyWindowName, webOnlyWindowName); + return response!; + } + @override Future closeWebView() async { closeWebViewCalled = true; diff --git a/packages/url_launcher/url_launcher/test/src/url_launcher_string_test.dart b/packages/url_launcher/url_launcher/test/src/url_launcher_string_test.dart index 95b2f5c27bf3..02c0b22903e0 100644 --- a/packages/url_launcher/url_launcher/test/src/url_launcher_string_test.dart +++ b/packages/url_launcher/url_launcher/test/src/url_launcher_string_test.dart @@ -43,8 +43,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -60,8 +59,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -77,8 +75,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -95,8 +92,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -113,8 +109,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -131,8 +126,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.externalApplication, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -151,8 +145,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.externalNonBrowserApplication, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: true, @@ -171,8 +164,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: false, enableDomStorage: true, universalLinksOnly: false, @@ -193,8 +185,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: true, enableDomStorage: false, universalLinksOnly: false, @@ -215,8 +206,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -245,8 +235,7 @@ void main() { mock ..setLaunchExpectations( url: emailLaunchUrlString, - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -264,8 +253,7 @@ void main() { mock ..setLaunchExpectations( url: urlString, - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, diff --git a/packages/url_launcher/url_launcher/test/src/url_launcher_uri_test.dart b/packages/url_launcher/url_launcher/test/src/url_launcher_uri_test.dart index 8286e0c43d20..e226e591a4ae 100644 --- a/packages/url_launcher/url_launcher/test/src/url_launcher_uri_test.dart +++ b/packages/url_launcher/url_launcher/test/src/url_launcher_uri_test.dart @@ -48,8 +48,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -65,8 +64,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -82,8 +80,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -99,8 +96,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -116,8 +112,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -133,8 +128,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.externalApplication, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -151,8 +145,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.externalNonBrowserApplication, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: true, @@ -170,8 +163,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: false, enableDomStorage: true, universalLinksOnly: false, @@ -192,8 +184,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: true, enableDomStorage: false, universalLinksOnly: false, @@ -214,8 +205,7 @@ void main() { mock ..setLaunchExpectations( url: url.toString(), - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -247,8 +237,7 @@ void main() { mock ..setLaunchExpectations( url: emailLaunchUrl.toString(), - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.platformDefault, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, From 30d497e53e5455c8b0f33d0befe244218a6ad6d0 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 22 Jun 2022 11:24:04 -0400 Subject: [PATCH 2/4] Analyzer fix --- .../url_launcher/test/mocks/mock_url_launcher_platform.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart b/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart index b8d15c4f2fdb..75a4e08555a6 100644 --- a/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart +++ b/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher_platform_interface/link.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; From 06ee6c0564f2198bdd3ddb03fc11a581ceca4a86 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 22 Jun 2022 11:30:05 -0400 Subject: [PATCH 3/4] Update Link test expectations for new API --- packages/url_launcher/url_launcher/test/link_test.dart | 8 +++----- .../test/mocks/mock_url_launcher_platform.dart | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/url_launcher/url_launcher/test/link_test.dart b/packages/url_launcher/url_launcher/test/link_test.dart index 6242397c5ed7..1c3d3e1e2d5b 100644 --- a/packages/url_launcher/url_launcher/test/link_test.dart +++ b/packages/url_launcher/url_launcher/test/link_test.dart @@ -19,7 +19,7 @@ void main() { UrlLauncherPlatform.instance = mock; }); - group('$Link', () { + group('Link', () { testWidgets('handles null uri correctly', (WidgetTester tester) async { bool isBuilt = false; FollowLink? followLink; @@ -55,8 +55,7 @@ void main() { mock ..setLaunchExpectations( url: 'http://example.com/foobar', - useSafariVC: false, - useWebView: false, + launchMode: PreferredLaunchMode.externalApplication, universalLinksOnly: false, enableJavaScript: true, enableDomStorage: true, @@ -85,8 +84,7 @@ void main() { mock ..setLaunchExpectations( url: 'http://example.com/foobar', - useSafariVC: true, - useWebView: true, + launchMode: PreferredLaunchMode.inAppWebView, universalLinksOnly: false, enableJavaScript: true, enableDomStorage: true, diff --git a/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart b/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart index 75a4e08555a6..05c8b5e4b375 100644 --- a/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart +++ b/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart @@ -99,6 +99,7 @@ class MockUrlLauncher extends Fake expect(options.webViewConfiguration.enableDomStorage, enableDomStorage); expect(options.webViewConfiguration.headers, headers); expect(options.webOnlyWindowName, webOnlyWindowName); + launchCalled = true; return response!; } From b0ab9bc37fb2b34fe7fa6983b3f19c7dce5ce8e6 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 22 Jun 2022 13:29:12 -0400 Subject: [PATCH 4/4] Fix import --- .../url_launcher/url_launcher/lib/src/url_launcher_string.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart b/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart index 732f6d9209b1..cf96ebc095da 100644 --- a/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart +++ b/packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:url_launcher/src/type_conversion.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; +import 'type_conversion.dart'; import 'types.dart'; /// String version of [launchUrl].