From e41ea0ebb74d862e686b44a4a351d456bcc01515 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 11:50:43 +0500 Subject: [PATCH 01/28] add android show title customization functionality --- .../urllauncher/CustomTabsIntentFactory.java | 12 ++++ .../CustomTabsIntentFactoryImpl.java | 18 +++++ .../flutter/plugins/urllauncher/Messages.java | 72 ++++++++++++++----- .../plugins/urllauncher/UrlLauncher.java | 11 ++- .../integration_test/url_launcher_test.dart | 17 +++-- .../url_launcher_android/pubspec.yaml | 2 +- 6 files changed, 103 insertions(+), 29 deletions(-) create mode 100644 packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java create mode 100644 packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java new file mode 100644 index 00000000000..ef142e21806 --- /dev/null +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java @@ -0,0 +1,12 @@ +// 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. + +package io.flutter.plugins.urllauncher; + +import androidx.browser.customtabs.CustomTabsIntent; +import io.flutter.plugins.urllauncher.Messages.WebViewOptions; + +public interface CustomTabsIntentFactory { + CustomTabsIntent getCustomTabsIntent(WebViewOptions options); +} \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java new file mode 100644 index 00000000000..57b994e4925 --- /dev/null +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java @@ -0,0 +1,18 @@ +// 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. + +package io.flutter.plugins.urllauncher; + +import androidx.browser.customtabs.CustomTabsIntent; + +import io.flutter.plugins.urllauncher.Messages.WebViewOptions; + +public class CustomTabsIntentFactoryImpl implements CustomTabsIntentFactory { + @Override + public CustomTabsIntent getCustomTabsIntent(WebViewOptions options) { + return new CustomTabsIntent.Builder() + .setShowTitle(options.getShowTitle()) + .build(); + } +} \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java index eab0d87f5b3..e083d0bf59c 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v10.0.0), do not edit directly. +// Autogenerated from Pigeon (v10.1.6), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.urllauncher; @@ -16,6 +16,10 @@ import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; import java.util.Map; /** Generated class from Pigeon. */ @@ -31,7 +35,8 @@ public static class FlutterError extends RuntimeException { /** The error details. Must be a datatype supported by the api codec. */ public final Object details; - public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) { + public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) + { super(message); this.code = code; this.details = details; @@ -50,7 +55,7 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { errorList.add(exception.toString()); errorList.add(exception.getClass().getSimpleName()); errorList.add( - "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); } return errorList; } @@ -58,7 +63,7 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { /** * Configuration options for an in-app WebView. * - *

Generated class from Pigeon that represents data sent in messages. + * Generated class from Pigeon that represents data sent in messages. */ public static final class WebViewOptions { private @NonNull Boolean enableJavaScript; @@ -100,6 +105,19 @@ public void setHeaders(@NonNull Map setterArg) { this.headers = setterArg; } + private @NonNull Boolean showTitle; + + public @NonNull Boolean getShowTitle() { + return showTitle; + } + + public void setShowTitle(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"showTitle\" is null."); + } + this.showTitle = setterArg; + } + /** Constructor is non-public to enforce null safety; use Builder. */ WebViewOptions() {} @@ -126,21 +144,30 @@ public static final class Builder { return this; } + private @Nullable Boolean showTitle; + + public @NonNull Builder setShowTitle(@NonNull Boolean setterArg) { + this.showTitle = setterArg; + return this; + } + public @NonNull WebViewOptions build() { WebViewOptions pigeonReturn = new WebViewOptions(); pigeonReturn.setEnableJavaScript(enableJavaScript); pigeonReturn.setEnableDomStorage(enableDomStorage); pigeonReturn.setHeaders(headers); + pigeonReturn.setShowTitle(showTitle); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(3); + ArrayList toListResult = new ArrayList(4); toListResult.add(enableJavaScript); toListResult.add(enableDomStorage); toListResult.add(headers); + toListResult.add(showTitle); return toListResult; } @@ -152,6 +179,8 @@ ArrayList toList() { pigeonResult.setEnableDomStorage((Boolean) enableDomStorage); Object headers = list.get(2); pigeonResult.setHeaders((Map) headers); + Object showTitle = list.get(3); + pigeonResult.setShowTitle((Boolean) showTitle); return pigeonResult; } } @@ -185,13 +214,16 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface UrlLauncherApi { /** Returns true if the URL can definitely be launched. */ - @NonNull + @NonNull Boolean canLaunchUrl(@NonNull String url); /** Opens the URL externally, returning true if successful. */ - @NonNull + @NonNull Boolean launchUrl(@NonNull String url, @NonNull Map headers); - /** Opens the URL in an in-app WebView, returning true if it opens successfully. */ - @NonNull + /** + * Opens the URL in an in-app WebView, returning true if it opens + * successfully. + */ + @NonNull Boolean openUrlInWebView(@NonNull String url, @NonNull WebViewOptions options); /** Closes the view opened by [openUrlInSafariViewController]. */ void closeWebView(); @@ -200,12 +232,12 @@ public interface UrlLauncherApi { static @NonNull MessageCodec getCodec() { return UrlLauncherApiCodec.INSTANCE; } - /** Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ + /**Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLauncherApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.UrlLauncherApi.canLaunchUrl", getCodec()); + binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl", getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -215,7 +247,8 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.canLaunchUrl(urlArg); wrapped.add(0, output); - } catch (Throwable exception) { + } + catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -228,7 +261,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.UrlLauncherApi.launchUrl", getCodec()); + binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl", getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -239,7 +272,8 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.launchUrl(urlArg, headersArg); wrapped.add(0, output); - } catch (Throwable exception) { + } + catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -252,7 +286,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.UrlLauncherApi.openUrlInWebView", getCodec()); + binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView", getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -263,7 +297,8 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.openUrlInWebView(urlArg, optionsArg); wrapped.add(0, output); - } catch (Throwable exception) { + } + catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -276,7 +311,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.UrlLauncherApi.closeWebView", getCodec()); + binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView", getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -284,7 +319,8 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { api.closeWebView(); wrapped.add(0, null); - } catch (Throwable exception) { + } + catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index 8ee9bffbb58..16589733371 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -31,6 +31,8 @@ interface IntentResolver { private static final String TAG = "UrlLauncher"; + private static final CustomTabsIntentFactory customTabsIntentFactory = new CustomTabsIntentFactoryImpl(); + private final @NonNull Context applicationContext; private final @NonNull IntentResolver intentResolver; @@ -104,7 +106,7 @@ void setActivity(@Nullable Activity activity) { // Try to launch using Custom Tabs if they have the necessary functionality. if (!containsRestrictedHeader(options.getHeaders())) { Uri uri = Uri.parse(url); - if (openCustomTab(activity, uri, headersBundle)) { + if (openCustomTab(activity, uri, headersBundle, options)) { return true; } } @@ -132,9 +134,10 @@ public void closeWebView() { } private static boolean openCustomTab( - @NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle) { - CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build(); + @NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle, @NonNull WebViewOptions options) { + CustomTabsIntent customTabsIntent = customTabsIntentFactory.getCustomTabsIntent(options); customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, headersBundle); + try { customTabsIntent.launchUrl(context, uri); } catch (ActivityNotFoundException ex) { @@ -176,3 +179,5 @@ private void ensureActivity() { } } } + + diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index 7aa221b3e1a..91409894c08 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -43,13 +43,16 @@ void main() { // Launch a url then close. expect( - await launcher.launch(primaryUrl, - useSafariVC: true, - useWebView: true, - enableJavaScript: false, - enableDomStorage: false, - universalLinksOnly: false, - headers: {}), + await launcher.launch( + primaryUrl, + useSafariVC: true, + useWebView: true, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + showTitle: false, + ), true); await launcher.closeWebView(); // Delay required to catch android side crashes in onDestroy. diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index f5db21c93b4..6a3c361c245 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher_android description: Android implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.1.0 +version: 6.2.0 environment: sdk: ">=2.19.0 <4.0.0" flutter: ">=3.7.0" From fb67692dc9301765d3248fd891ce2148b7a34387 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 12:44:31 +0500 Subject: [PATCH 02/28] Pass the parameter --- .../url_launcher/example/lib/main.dart | 17 ++++++++ .../url_launcher/lib/src/type_conversion.dart | 1 + .../url_launcher/lib/src/types.dart | 6 +++ .../integration_test/url_launcher_test.dart | 1 - .../lib/src/messages.g.dart | 26 +++++++----- .../lib/url_launcher_android.dart | 40 +++++++++++++++---- .../pigeons/messages.dart | 12 ++++-- .../test/url_launcher_android_test.dart | 6 ++- .../lib/src/types.dart | 6 +++ 9 files changed, 91 insertions(+), 24 deletions(-) diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index 57a0ce9ef47..2bf45d19a7f 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -68,6 +68,16 @@ class _MyHomePageState extends State { } } + Future _launchInAppWithShowTitle(Uri url) async { + if (!await launchUrl( + url, + mode: LaunchMode.inAppWebView, + webViewConfiguration: const WebViewConfiguration(showTitle: true), + )) { + throw Exception('Could not launch $url'); + } + } + Future _launchAsInAppWebViewWithCustomHeaders(Uri url) async { if (!await launchUrl( url, @@ -214,6 +224,13 @@ class _MyHomePageState extends State { child: const Text('Launch in app + close after 5 seconds'), ), const Padding(padding: EdgeInsets.all(16.0)), + ElevatedButton( + onPressed: () => setState(() { + _launched = _launchInAppWithShowTitle(toLaunch); + }), + child: const Text('Launch in app with showTitle'), + ), + const Padding(padding: EdgeInsets.all(16.0)), Link( uri: Uri.parse( 'https://pub.dev/documentation/url_launcher/latest/link/link-library.html'), diff --git a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart index 970f04dced5..d2f04a4c518 100644 --- a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart +++ b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart @@ -13,6 +13,7 @@ InAppWebViewConfiguration convertConfiguration(WebViewConfiguration config) { enableJavaScript: config.enableJavaScript, enableDomStorage: config.enableDomStorage, headers: config.headers, + showTitle: config.showTitle, ); } diff --git a/packages/url_launcher/url_launcher/lib/src/types.dart b/packages/url_launcher/url_launcher/lib/src/types.dart index 359e293ef82..943cc987b3e 100644 --- a/packages/url_launcher/url_launcher/lib/src/types.dart +++ b/packages/url_launcher/url_launcher/lib/src/types.dart @@ -32,6 +32,7 @@ class WebViewConfiguration { this.enableJavaScript = true, this.enableDomStorage = true, this.headers = const {}, + this.showTitle = false, }); /// Whether or not JavaScript is enabled for the web content. @@ -51,4 +52,9 @@ class WebViewConfiguration { /// [Browser.EXTRA_HEADERS](https://developer.android.com/reference/android/provider/Browser#EXTRA_HEADERS) /// Not all browsers support this, so it is not guaranteed to be honored. final Map headers; + + /// Whether or not to show the webpage title when using Chrome Custom Tabs. + /// + /// Only works on Android. + final bool showTitle; } diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index 91409894c08..9a00699d220 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -51,7 +51,6 @@ void main() { enableDomStorage: false, universalLinksOnly: false, headers: {}, - showTitle: false, ), true); await launcher.closeWebView(); diff --git a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart index 9aed8f7f60f..7c8873845a4 100644 --- a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart +++ b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v10.0.0), do not edit directly. +// Autogenerated from Pigeon (v10.1.6), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import @@ -17,6 +17,7 @@ class WebViewOptions { required this.enableJavaScript, required this.enableDomStorage, required this.headers, + required this.showTitle, }); bool enableJavaScript; @@ -25,11 +26,14 @@ class WebViewOptions { Map headers; + bool showTitle; + Object encode() { return [ enableJavaScript, enableDomStorage, headers, + showTitle, ]; } @@ -39,6 +43,7 @@ class WebViewOptions { enableJavaScript: result[0]! as bool, enableDomStorage: result[1]! as bool, headers: (result[2] as Map?)!.cast(), + showTitle: result[3]! as bool, ); } } @@ -58,7 +63,7 @@ class _UrlLauncherApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 128: return WebViewOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -79,7 +84,7 @@ class UrlLauncherApi { /// Returns true if the URL can definitely be launched. Future canLaunchUrl(String arg_url) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.UrlLauncherApi.canLaunchUrl', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url]) as List?; @@ -105,10 +110,9 @@ class UrlLauncherApi { } /// Opens the URL externally, returning true if successful. - Future launchUrl( - String arg_url, Map arg_headers) async { + Future launchUrl(String arg_url, Map arg_headers) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.UrlLauncherApi.launchUrl', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url, arg_headers]) as List?; @@ -135,10 +139,9 @@ class UrlLauncherApi { /// Opens the URL in an in-app WebView, returning true if it opens /// successfully. - Future openUrlInWebView( - String arg_url, WebViewOptions arg_options) async { + Future openUrlInWebView(String arg_url, WebViewOptions arg_options) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.UrlLauncherApi.openUrlInWebView', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView', codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url, arg_options]) as List?; @@ -166,9 +169,10 @@ class UrlLauncherApi { /// Closes the view opened by [openUrlInSafariViewController]. Future closeWebView() async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.UrlLauncherApi.closeWebView', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', codec, binaryMessenger: _binaryMessenger); - final List? replyList = await channel.send(null) as List?; + final List? replyList = + await channel.send(null) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', diff --git a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart index 7b53b85f793..c47d5a6e455 100644 --- a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart +++ b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart @@ -62,17 +62,42 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { required Map headers, String? webOnlyWindowName, }) async { - final bool succeeded; + return launchUrl( + url, + LaunchOptions( + webViewConfiguration: InAppWebViewConfiguration( + enableJavaScript: enableJavaScript, + enableDomStorage: enableDomStorage, + headers: headers, + ), + webOnlyWindowName: webOnlyWindowName, + ), + ); + } + + @override + Future launchUrl(String url, LaunchOptions options) async { + final bool isWebURL = url.startsWith('http:') || url.startsWith('https:'); + final bool useWebView = options.mode == PreferredLaunchMode.inAppWebView || + (isWebURL && options.mode == PreferredLaunchMode.platformDefault); + + bool succeeded; + if (useWebView) { succeeded = await _hostApi.openUrlInWebView( - url, - WebViewOptions( - enableJavaScript: enableJavaScript, - enableDomStorage: enableDomStorage, - headers: headers)); + url, + WebViewOptions( + enableJavaScript: options.webViewConfiguration.enableJavaScript, + enableDomStorage: options.webViewConfiguration.enableDomStorage, + headers: options.webViewConfiguration.headers, + showTitle: options.webViewConfiguration.showTitle, + ), + ); } else { - succeeded = await _hostApi.launchUrl(url, headers); + succeeded = + await _hostApi.launchUrl(url, options.webViewConfiguration.headers); } + // TODO(stuartmorgan): Remove this special handling as part of a // breaking change to rework failure handling across all platform. The // current behavior is backwards compatible with the previous Java error. @@ -81,6 +106,7 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { code: 'ACTIVITY_NOT_FOUND', message: 'No Activity found to handle intent { $url }'); } + return succeeded; } diff --git a/packages/url_launcher/url_launcher_android/pigeons/messages.dart b/packages/url_launcher/url_launcher_android/pigeons/messages.dart index 84e507d7024..43e6cf6de4d 100644 --- a/packages/url_launcher/url_launcher_android/pigeons/messages.dart +++ b/packages/url_launcher/url_launcher_android/pigeons/messages.dart @@ -13,16 +13,20 @@ import 'package:pigeon/pigeon.dart'; /// Configuration options for an in-app WebView. class WebViewOptions { - const WebViewOptions( - {required this.enableJavaScript, - required this.enableDomStorage, - this.headers = const {}}); + const WebViewOptions({ + required this.enableJavaScript, + required this.enableDomStorage, + this.headers = const {}, + required this.showTitle, + }); + final bool enableJavaScript; final bool enableDomStorage; // TODO(stuartmorgan): Declare these as non-nullable generics once // https://github.com/flutter/flutter/issues/97848 is fixed. In practice, // the values will never be null, and the native implementation assumes that. final Map headers; + final bool showTitle; } @HostApi() diff --git a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart index 3b3d012a168..be2dd4e7e3f 100644 --- a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart +++ b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart @@ -226,7 +226,11 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { @override Future launchUrl(String url, Map headers) async { passedWebViewOptions = WebViewOptions( - enableJavaScript: false, enableDomStorage: false, headers: headers); + enableJavaScript: false, + enableDomStorage: false, + headers: headers, + showTitle: false, + ); usedWebView = false; return _launch(url); } diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart index ca9d8e1c917..c6dc839a4c9 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart @@ -34,6 +34,7 @@ class InAppWebViewConfiguration { this.enableJavaScript = true, this.enableDomStorage = true, this.headers = const {}, + this.showTitle = false, }); /// Whether or not JavaScript is enabled for the web content. @@ -44,6 +45,11 @@ class InAppWebViewConfiguration { /// Additional headers to pass in the load request. final Map headers; + + /// Whether or not to show the webpage title when using Chrome Custom Tabs. + /// + /// Only works on Android. + final bool showTitle; } /// Options for [launchUrl]. From 21cd06f5b2da3b571f54b2466bff4bd91db60a16 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 12:44:34 +0500 Subject: [PATCH 03/28] Dependency overrides --- packages/go_router/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_android/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_android/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_ios/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_ios/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_linux/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_linux/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_macos/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_macos/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_web/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_web/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_windows/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_windows/pubspec.yaml | 5 +++++ 15 files changed, 75 insertions(+) diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml index 3ff5906016d..c2082b162bf 100644 --- a/packages/go_router/example/pubspec.yaml +++ b/packages/go_router/example/pubspec.yaml @@ -26,3 +26,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher: {path: ../../url_launcher/url_launcher}} diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index e09df486b41..3b0785df6ee 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -29,3 +29,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher: {path: ../../../url_launcher/url_launcher}, url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 9feae723f2f..59b339f9ce7 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -50,3 +50,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_android: {path: ../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/example/pubspec.yaml b/packages/url_launcher/url_launcher_android/example/pubspec.yaml index e8aee1779b0..38bc570eca5 100644 --- a/packages/url_launcher/url_launcher_android/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/example/pubspec.yaml @@ -28,3 +28,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index 6a3c361c245..0984a1ab56f 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -34,3 +34,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml index d755c553f6a..793cde0144d 100644 --- a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml @@ -27,3 +27,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_ios/pubspec.yaml b/packages/url_launcher/url_launcher_ios/pubspec.yaml index 8b45ed75054..43d58cb6f3c 100644 --- a/packages/url_launcher/url_launcher_ios/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/pubspec.yaml @@ -33,3 +33,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index 0dd4a4cf8a3..ff6a34aabdf 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -26,3 +26,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index 2649beeecb9..65e615ed205 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -31,3 +31,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 0ad23902782..bbe82f8c505 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -26,3 +26,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index 23d5f6a2f47..45e09ee396d 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -33,3 +33,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index 9915164471a..adc6f4da5f3 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -19,3 +19,8 @@ dev_dependencies: url_launcher_platform_interface: ^2.0.3 url_launcher_web: path: ../ + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index fce7da421b1..8c6f3e65b61 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -32,3 +32,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index 77106bc48a7..b9e23486d63 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -26,3 +26,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index 6b17b9d7c55..ddc595ca907 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -32,3 +32,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} From 276c08bd39dabe9ca8b3c9c7863584c28cc3074e Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 16:42:33 +0500 Subject: [PATCH 04/28] Add tests for native side --- .../urllauncher/CustomTabsIntentFactory.java | 12 ------ .../CustomTabsIntentFactoryImpl.java | 18 --------- .../plugins/urllauncher/UrlLauncher.java | 13 ++++--- .../plugins/urllauncher/UrlLauncherTest.java | 39 +++++++++++++++++++ 4 files changed, 47 insertions(+), 35 deletions(-) delete mode 100644 packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java delete mode 100644 packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java deleted file mode 100644 index ef142e21806..00000000000 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactory.java +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -package io.flutter.plugins.urllauncher; - -import androidx.browser.customtabs.CustomTabsIntent; -import io.flutter.plugins.urllauncher.Messages.WebViewOptions; - -public interface CustomTabsIntentFactory { - CustomTabsIntent getCustomTabsIntent(WebViewOptions options); -} \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java deleted file mode 100644 index 57b994e4925..00000000000 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/CustomTabsIntentFactoryImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -package io.flutter.plugins.urllauncher; - -import androidx.browser.customtabs.CustomTabsIntent; - -import io.flutter.plugins.urllauncher.Messages.WebViewOptions; - -public class CustomTabsIntentFactoryImpl implements CustomTabsIntentFactory { - @Override - public CustomTabsIntent getCustomTabsIntent(WebViewOptions options) { - return new CustomTabsIntent.Builder() - .setShowTitle(options.getShowTitle()) - .build(); - } -} \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index 16589733371..cc497191e9e 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -31,8 +31,6 @@ interface IntentResolver { private static final String TAG = "UrlLauncher"; - private static final CustomTabsIntentFactory customTabsIntentFactory = new CustomTabsIntentFactoryImpl(); - private final @NonNull Context applicationContext; private final @NonNull IntentResolver intentResolver; @@ -133,9 +131,13 @@ public void closeWebView() { applicationContext.sendBroadcast(new Intent(WebViewActivity.ACTION_CLOSE)); } - private static boolean openCustomTab( + @VisibleForTesting + public static boolean openCustomTab( @NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle, @NonNull WebViewOptions options) { - CustomTabsIntent customTabsIntent = customTabsIntentFactory.getCustomTabsIntent(options); + CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder() + .setShowTitle(options.getShowTitle()) + .build(); + customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, headersBundle); try { @@ -163,7 +165,8 @@ private static boolean containsRestrictedHeader(Map headersMap) return false; } - private static @NonNull Bundle extractBundle(Map headersMap) { + @VisibleForTesting + public static @NonNull Bundle extractBundle(Map headersMap) { final Bundle headersBundle = new Bundle(); for (String key : headersMap.keySet()) { final String value = headersMap.get(key); diff --git a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java index b8bb3b4f21e..064d796e808 100644 --- a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java +++ b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java @@ -23,6 +23,8 @@ import android.net.Uri; import android.os.Bundle; import android.provider.Browser; + +import androidx.browser.customtabs.CustomTabsIntent; import androidx.test.core.app.ApplicationProvider; import java.util.HashMap; import org.junit.Test; @@ -129,6 +131,7 @@ public void launch_returnsTrue() { assertTrue(result); } + @Test public void openWebView_opensUrl_inWebView() { Activity activity = mock(Activity.class); @@ -139,6 +142,7 @@ public void openWebView_opensUrl_inWebView() { boolean enableDomStorage = false; HashMap headers = new HashMap<>(); headers.put("key", "value"); + boolean showTitle = false; boolean result = api.openUrlInWebView( @@ -147,6 +151,7 @@ public void openWebView_opensUrl_inWebView() { .setEnableJavaScript(enableJavaScript) .setEnableDomStorage(enableDomStorage) .setHeaders(headers) + .setShowTitle(showTitle) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -175,6 +180,7 @@ public void openWebView_opensUrl_inCustomTabs() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) + .setShowTitle(true) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -182,6 +188,7 @@ public void openWebView_opensUrl_inCustomTabs() { assertTrue(result); assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); assertNull(intentCaptor.getValue().getComponent()); + assertEquals(intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), CustomTabsIntent.SHOW_PAGE_TITLE); } @Test @@ -201,6 +208,7 @@ public void openWebView_opensUrl_inCustomTabs_withCORSAllowedHeader() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(headers) + .setShowTitle(false) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -230,6 +238,7 @@ public void openWebView_fallsbackTo_inWebView() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) + .setShowTitle(false) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -257,6 +266,7 @@ public void openWebView_handlesEnableJavaScript() { .setEnableJavaScript(enableJavaScript) .setEnableDomStorage(false) .setHeaders(headers) + .setShowTitle(false) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -283,6 +293,7 @@ public void openWebView_handlesHeaders() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(headers) + .setShowTitle(false) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -309,6 +320,7 @@ public void openWebView_handlesEnableDomStorage() { .setEnableJavaScript(false) .setEnableDomStorage(enableDomStorage) .setHeaders(headers) + .setShowTitle(false) .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -318,6 +330,31 @@ public void openWebView_handlesEnableDomStorage() { intentCaptor.getValue().getExtras().getBoolean(WebViewActivity.ENABLE_DOM_EXTRA)); } + @Test + public void openWebView_handlesEnableShowTitle() { + Activity activity = mock(Activity.class); + UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext()); + api.setActivity(activity); + boolean enableDomStorage = true; + HashMap headers = new HashMap<>(); + boolean showTitle = true; + + api.openUrlInWebView( + "https://flutter.dev", + new Messages.WebViewOptions.Builder() + .setEnableJavaScript(false) + .setEnableDomStorage(enableDomStorage) + .setHeaders(headers) + .setShowTitle(showTitle) + .build() + ); + + final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(activity).startActivity(intentCaptor.capture(), isNull()); + + assertEquals(intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), CustomTabsIntent.SHOW_PAGE_TITLE); + } + @Test public void openWebView_throwsForNoCurrentActivity() { UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext()); @@ -333,6 +370,7 @@ public void openWebView_throwsForNoCurrentActivity() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) + .setShowTitle(false) .build())); assertEquals("NO_ACTIVITY", exception.code); } @@ -356,6 +394,7 @@ public void openWebView_returnsFalse() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) + .setShowTitle(false) .build()); assertFalse(result); From 1897451e3ed631c9956d65b288913a5d1d9bd2c6 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 16:56:35 +0500 Subject: [PATCH 05/28] Cover dart side with tests --- .../url_launcher/test/link_test.dart | 2 ++ .../mocks/mock_url_launcher_platform.dart | 5 +++ .../test/src/legacy_api_test.dart | 12 +++++++ .../test/src/url_launcher_string_test.dart | 12 +++++++ .../test/src/url_launcher_uri_test.dart | 33 +++++++++++++++++++ .../test/url_launcher_android_test.dart | 14 ++++++++ 6 files changed, 78 insertions(+) diff --git a/packages/url_launcher/url_launcher/test/link_test.dart b/packages/url_launcher/url_launcher/test/link_test.dart index 1585420d9b2..d737a18a446 100644 --- a/packages/url_launcher/url_launcher/test/link_test.dart +++ b/packages/url_launcher/url_launcher/test/link_test.dart @@ -61,6 +61,7 @@ void main() { enableDomStorage: true, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); await followLink!(); @@ -92,6 +93,7 @@ void main() { enableDomStorage: true, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); await followLink!(); 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 05c8b5e4b37..5a0c503241b 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 @@ -17,6 +17,7 @@ class MockUrlLauncher extends Fake bool? enableJavaScript; bool? enableDomStorage; bool? universalLinksOnly; + bool? showTitle; Map? headers; String? webOnlyWindowName; @@ -41,6 +42,7 @@ class MockUrlLauncher extends Fake required bool universalLinksOnly, required Map headers, required String? webOnlyWindowName, + required bool showTitle, }) { this.url = url; this.launchMode = launchMode; @@ -51,6 +53,7 @@ class MockUrlLauncher extends Fake this.universalLinksOnly = universalLinksOnly; this.headers = headers; this.webOnlyWindowName = webOnlyWindowName; + this.showTitle = showTitle; } // ignore: use_setters_to_change_properties @@ -87,6 +90,7 @@ class MockUrlLauncher extends Fake expect(universalLinksOnly, this.universalLinksOnly); expect(headers, this.headers); expect(webOnlyWindowName, this.webOnlyWindowName); + expect(webOnlyWindowName, this.webOnlyWindowName); launchCalled = true; return response!; } @@ -98,6 +102,7 @@ class MockUrlLauncher extends Fake expect(options.webViewConfiguration.enableJavaScript, enableJavaScript); expect(options.webViewConfiguration.enableDomStorage, enableDomStorage); expect(options.webViewConfiguration.headers, headers); + expect(options.webViewConfiguration.showTitle, showTitle); expect(options.webOnlyWindowName, webOnlyWindowName); launchCalled = true; return response!; diff --git a/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart b/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart index 14f0b57828e..9b98bb7a694 100644 --- a/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart +++ b/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart @@ -53,6 +53,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/'), isTrue); @@ -69,6 +70,7 @@ void main() { universalLinksOnly: false, headers: {'key': 'value'}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -90,6 +92,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/', forceSafariVC: true), isTrue); @@ -106,6 +109,7 @@ void main() { universalLinksOnly: true, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -125,6 +129,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/', forceWebView: true), isTrue); @@ -141,6 +146,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -160,6 +166,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -179,6 +186,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/', forceSafariVC: false), isTrue); @@ -200,6 +208,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launch('mailto:gmail-noreply@google.com?subject=Hello'), @@ -231,6 +240,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); @@ -263,6 +273,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); @@ -296,6 +307,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( 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 64065ff99f9..a5021694cc6 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 @@ -49,6 +49,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -65,6 +66,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -81,6 +83,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -97,6 +100,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -113,6 +117,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString, mode: LaunchMode.inAppWebView), @@ -130,6 +135,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -149,6 +155,7 @@ void main() { universalLinksOnly: true, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -168,6 +175,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -189,6 +197,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -210,6 +219,7 @@ void main() { universalLinksOnly: false, headers: {'key': 'value'}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -239,6 +249,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(emailLaunchUrlString), isTrue); @@ -257,6 +268,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); 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 d71d07fc8fc..1e924c0ab5c 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 @@ -54,6 +54,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -70,6 +71,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -86,6 +88,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -102,6 +105,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -118,6 +122,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrl(url, mode: LaunchMode.inAppWebView), isTrue); @@ -134,6 +139,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -151,6 +157,7 @@ void main() { universalLinksOnly: true, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -169,6 +176,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -179,6 +187,28 @@ void main() { isTrue); }); + test('in-app webview with show title', () async { + final Uri url = Uri.parse('https://flutter.dev'); + mock + ..setLaunchExpectations( + url: url.toString(), + launchMode: PreferredLaunchMode.inAppWebView, + enableJavaScript: true, + enableDomStorage: true, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + showTitle: true, + ) + ..setResponse(true); + expect( + await launchUrl(url, + mode: LaunchMode.inAppWebView, + webViewConfiguration: + const WebViewConfiguration(showTitle: true)), + isTrue); + }); + test('in-app webview without DOM storage', () async { final Uri url = Uri.parse('https://flutter.dev'); mock @@ -190,6 +220,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -211,6 +242,7 @@ void main() { universalLinksOnly: false, headers: {'key': 'value'}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect( @@ -243,6 +275,7 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, + showTitle: false, ) ..setResponse(true); expect(await launchUrl(emailLaunchUrl), isTrue); diff --git a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart index be2dd4e7e3f..2f2561db492 100644 --- a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart +++ b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart @@ -165,6 +165,20 @@ void main() { expect(api.passedWebViewOptions?.enableDomStorage, true); }); + test('passes showTitle to webview', () async { + final UrlLauncherAndroid launcher = UrlLauncherAndroid(api: api); + await launcher.launchUrl( + 'http://example.com/', + const LaunchOptions( + webViewConfiguration: InAppWebViewConfiguration( + showTitle: true, + ), + ), + ); + + expect(api.passedWebViewOptions?.showTitle, true); + }); + test('passes through no-activity exception', () async { final UrlLauncherAndroid launcher = UrlLauncherAndroid(api: api); await expectLater( From 5cd1709a3bc9179a958dacc97b28b852957b49b7 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 17:03:36 +0500 Subject: [PATCH 06/28] Format --- .../flutter/plugins/urllauncher/Messages.java | 52 +++++++++---------- .../plugins/urllauncher/UrlLauncher.java | 12 ++--- .../plugins/urllauncher/UrlLauncherTest.java | 25 ++++----- .../lib/src/messages.g.dart | 23 ++++---- 4 files changed, 57 insertions(+), 55 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java index e083d0bf59c..f1299cec746 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java @@ -16,10 +16,6 @@ import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; import java.util.Map; /** Generated class from Pigeon. */ @@ -35,8 +31,7 @@ public static class FlutterError extends RuntimeException { /** The error details. Must be a datatype supported by the api codec. */ public final Object details; - public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) - { + public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) { super(message); this.code = code; this.details = details; @@ -55,7 +50,7 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { errorList.add(exception.toString()); errorList.add(exception.getClass().getSimpleName()); errorList.add( - "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); } return errorList; } @@ -63,7 +58,7 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { /** * Configuration options for an in-app WebView. * - * Generated class from Pigeon that represents data sent in messages. + *

Generated class from Pigeon that represents data sent in messages. */ public static final class WebViewOptions { private @NonNull Boolean enableJavaScript; @@ -214,16 +209,13 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface UrlLauncherApi { /** Returns true if the URL can definitely be launched. */ - @NonNull + @NonNull Boolean canLaunchUrl(@NonNull String url); /** Opens the URL externally, returning true if successful. */ - @NonNull + @NonNull Boolean launchUrl(@NonNull String url, @NonNull Map headers); - /** - * Opens the URL in an in-app WebView, returning true if it opens - * successfully. - */ - @NonNull + /** Opens the URL in an in-app WebView, returning true if it opens successfully. */ + @NonNull Boolean openUrlInWebView(@NonNull String url, @NonNull WebViewOptions options); /** Closes the view opened by [openUrlInSafariViewController]. */ void closeWebView(); @@ -232,12 +224,14 @@ public interface UrlLauncherApi { static @NonNull MessageCodec getCodec() { return UrlLauncherApiCodec.INSTANCE; } - /**Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ + /** Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLauncherApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -247,8 +241,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.canLaunchUrl(urlArg); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -261,7 +254,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -272,8 +267,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.launchUrl(urlArg, headersArg); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -286,7 +280,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -297,8 +293,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.openUrlInWebView(urlArg, optionsArg); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -311,7 +306,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -319,8 +316,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { api.closeWebView(); wrapped.add(0, null); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index cc497191e9e..63ad66cbeb1 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -133,10 +133,12 @@ public void closeWebView() { @VisibleForTesting public static boolean openCustomTab( - @NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle, @NonNull WebViewOptions options) { - CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder() - .setShowTitle(options.getShowTitle()) - .build(); + @NonNull Context context, + @NonNull Uri uri, + @NonNull Bundle headersBundle, + @NonNull WebViewOptions options) { + CustomTabsIntent customTabsIntent = + new CustomTabsIntent.Builder().setShowTitle(options.getShowTitle()).build(); customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, headersBundle); @@ -182,5 +184,3 @@ private void ensureActivity() { } } } - - diff --git a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java index 064d796e808..2ea64340aa6 100644 --- a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java +++ b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java @@ -23,7 +23,6 @@ import android.net.Uri; import android.os.Bundle; import android.provider.Browser; - import androidx.browser.customtabs.CustomTabsIntent; import androidx.test.core.app.ApplicationProvider; import java.util.HashMap; @@ -131,7 +130,6 @@ public void launch_returnsTrue() { assertTrue(result); } - @Test public void openWebView_opensUrl_inWebView() { Activity activity = mock(Activity.class); @@ -188,7 +186,9 @@ public void openWebView_opensUrl_inCustomTabs() { assertTrue(result); assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); assertNull(intentCaptor.getValue().getComponent()); - assertEquals(intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), CustomTabsIntent.SHOW_PAGE_TITLE); + assertEquals( + intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), + CustomTabsIntent.SHOW_PAGE_TITLE); } @Test @@ -340,19 +340,20 @@ public void openWebView_handlesEnableShowTitle() { boolean showTitle = true; api.openUrlInWebView( - "https://flutter.dev", - new Messages.WebViewOptions.Builder() - .setEnableJavaScript(false) - .setEnableDomStorage(enableDomStorage) - .setHeaders(headers) - .setShowTitle(showTitle) - .build() - ); + "https://flutter.dev", + new Messages.WebViewOptions.Builder() + .setEnableJavaScript(false) + .setEnableDomStorage(enableDomStorage) + .setHeaders(headers) + .setShowTitle(showTitle) + .build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture(), isNull()); - assertEquals(intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), CustomTabsIntent.SHOW_PAGE_TITLE); + assertEquals( + intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), + CustomTabsIntent.SHOW_PAGE_TITLE); } @Test diff --git a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart index 7c8873845a4..dcf95de4f3e 100644 --- a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart +++ b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart @@ -63,7 +63,7 @@ class _UrlLauncherApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 128: return WebViewOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -84,7 +84,8 @@ class UrlLauncherApi { /// Returns true if the URL can definitely be launched. Future canLaunchUrl(String arg_url) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url]) as List?; @@ -110,9 +111,11 @@ class UrlLauncherApi { } /// Opens the URL externally, returning true if successful. - Future launchUrl(String arg_url, Map arg_headers) async { + Future launchUrl( + String arg_url, Map arg_headers) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url, arg_headers]) as List?; @@ -139,9 +142,11 @@ class UrlLauncherApi { /// Opens the URL in an in-app WebView, returning true if it opens /// successfully. - Future openUrlInWebView(String arg_url, WebViewOptions arg_options) async { + Future openUrlInWebView( + String arg_url, WebViewOptions arg_options) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url, arg_options]) as List?; @@ -169,10 +174,10 @@ class UrlLauncherApi { /// Closes the view opened by [openUrlInSafariViewController]. Future closeWebView() async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send(null) as List?; + final List? replyList = await channel.send(null) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', From bc943c538b95b909b71dd7a1790b84050efc2958 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 17 Oct 2023 22:18:55 +0500 Subject: [PATCH 07/28] Reduce code repetition --- .../lib/url_launcher_android.dart | 48 +++++++++---------- .../test/url_launcher_android_test.dart | 3 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart index c47d5a6e455..444de28833a 100644 --- a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart +++ b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart @@ -49,8 +49,8 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { return _hostApi.closeWebView(); } - // TODO(stuartmorgan): Implement launchUrl, and make this a passthrough - // to launchUrl. See also https://github.com/flutter/flutter/issues/66721 + // TODO(Alex-Usmanov): make this a passthrough via launchUrl after issue + // https://github.com/flutter/flutter/issues/66721 is resolved. @override Future launch( String url, { @@ -62,17 +62,14 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { required Map headers, String? webOnlyWindowName, }) async { - return launchUrl( - url, - LaunchOptions( - webViewConfiguration: InAppWebViewConfiguration( - enableJavaScript: enableJavaScript, - enableDomStorage: enableDomStorage, - headers: headers, - ), - webOnlyWindowName: webOnlyWindowName, - ), + final WebViewOptions webViewOptions = WebViewOptions( + enableJavaScript: enableJavaScript, + enableDomStorage: enableDomStorage, + headers: headers, + showTitle: false, ); + + return _openInWebviewOrLaunch(url, webViewOptions, useWebView); } @override @@ -81,21 +78,24 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { final bool useWebView = options.mode == PreferredLaunchMode.inAppWebView || (isWebURL && options.mode == PreferredLaunchMode.platformDefault); - bool succeeded; + final WebViewOptions webViewOptions = WebViewOptions( + enableJavaScript: options.webViewConfiguration.enableJavaScript, + enableDomStorage: options.webViewConfiguration.enableDomStorage, + headers: options.webViewConfiguration.headers, + showTitle: options.webViewConfiguration.showTitle, + ); + + return _openInWebviewOrLaunch(url, webViewOptions, useWebView); + } + + Future _openInWebviewOrLaunch( + String url, WebViewOptions options, bool useWebView) async { + final bool succeeded; if (useWebView) { - succeeded = await _hostApi.openUrlInWebView( - url, - WebViewOptions( - enableJavaScript: options.webViewConfiguration.enableJavaScript, - enableDomStorage: options.webViewConfiguration.enableDomStorage, - headers: options.webViewConfiguration.headers, - showTitle: options.webViewConfiguration.showTitle, - ), - ); + succeeded = await _hostApi.openUrlInWebView(url, options); } else { - succeeded = - await _hostApi.launchUrl(url, options.webViewConfiguration.headers); + succeeded = await _hostApi.launchUrl(url, options.headers); } // TODO(stuartmorgan): Remove this special handling as part of a diff --git a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart index 2f2561db492..02e287b747c 100644 --- a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart +++ b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart @@ -64,6 +64,7 @@ void main() { universalLinksOnly: false, headers: const {}, ); + expect(launched, true); expect(api.usedWebView, false); expect(api.passedWebViewOptions?.headers, isEmpty); @@ -243,7 +244,7 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { enableJavaScript: false, enableDomStorage: false, headers: headers, - showTitle: false, + showTitle: true, ); usedWebView = false; return _launch(url); From d6306ba59fe88eba1319a180e2e595257ae4ad3d Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Wed, 18 Oct 2023 09:30:38 +0500 Subject: [PATCH 08/28] Revert todo change --- .../url_launcher_android/lib/url_launcher_android.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart index 444de28833a..eb5790ac0de 100644 --- a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart +++ b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart @@ -49,8 +49,8 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { return _hostApi.closeWebView(); } - // TODO(Alex-Usmanov): make this a passthrough via launchUrl after issue - // https://github.com/flutter/flutter/issues/66721 is resolved. + // TODO(stuartmorgan): Implement launchUrl, and make this a passthrough + // to launchUrl. See also https://github.com/flutter/flutter/issues/66721 @override Future launch( String url, { From f59475bd58fce64086d3d5b631dc318d5e9e1db6 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 20 Oct 2023 13:38:45 +0500 Subject: [PATCH 09/28] Wrap browser customization values in another configuration object --- .../url_launcher/example/lib/main.dart | 2 +- .../url_launcher/lib/src/type_conversion.dart | 11 ++- .../url_launcher/lib/src/types.dart | 9 +- .../lib/src/url_launcher_string.dart | 2 +- .../lib/src/url_launcher_uri.dart | 4 +- .../mocks/mock_url_launcher_platform.dart | 2 +- .../test/src/url_launcher_uri_test.dart | 9 +- .../flutter/plugins/urllauncher/Messages.java | 91 +++++++++++++------ .../plugins/urllauncher/UrlLauncher.java | 18 ++-- .../plugins/urllauncher/UrlLauncherTest.java | 40 ++++---- .../lib/src/messages.g.dart | 42 +++++++-- .../lib/url_launcher_android.dart | 31 +++++-- .../pigeons/messages.dart | 9 +- .../test/url_launcher_android_test.dart | 18 +++- .../lib/src/types.dart | 14 ++- 15 files changed, 214 insertions(+), 88 deletions(-) diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index 2bf45d19a7f..acb564b12fd 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -72,7 +72,7 @@ class _MyHomePageState extends State { if (!await launchUrl( url, mode: LaunchMode.inAppWebView, - webViewConfiguration: const WebViewConfiguration(showTitle: true), + browserConfiguration: const BrowserConfiguration(showTitle: true), )) { throw Exception('Could not launch $url'); } diff --git a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart index d2f04a4c518..8e4aa7991d1 100644 --- a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart +++ b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart @@ -8,11 +8,20 @@ import 'types.dart'; /// Converts an (app-facing) [WebViewConfiguration] to a (platform interface) /// [InAppWebViewConfiguration]. -InAppWebViewConfiguration convertConfiguration(WebViewConfiguration config) { +InAppWebViewConfiguration convertWebViewConfiguration( + WebViewConfiguration config) { return InAppWebViewConfiguration( enableJavaScript: config.enableJavaScript, enableDomStorage: config.enableDomStorage, headers: config.headers, + ); +} + +/// Converts an (app-facing) [BrowserConfiguration] to a (platform interface) +/// [InApp]. +InAppBrowserConfiguration convertBrowserConfiguration( + BrowserConfiguration config) { + return InAppBrowserConfiguration( showTitle: config.showTitle, ); } diff --git a/packages/url_launcher/url_launcher/lib/src/types.dart b/packages/url_launcher/url_launcher/lib/src/types.dart index 943cc987b3e..345534d3541 100644 --- a/packages/url_launcher/url_launcher/lib/src/types.dart +++ b/packages/url_launcher/url_launcher/lib/src/types.dart @@ -32,7 +32,6 @@ class WebViewConfiguration { this.enableJavaScript = true, this.enableDomStorage = true, this.headers = const {}, - this.showTitle = false, }); /// Whether or not JavaScript is enabled for the web content. @@ -52,6 +51,14 @@ class WebViewConfiguration { /// [Browser.EXTRA_HEADERS](https://developer.android.com/reference/android/provider/Browser#EXTRA_HEADERS) /// Not all browsers support this, so it is not guaranteed to be honored. final Map headers; +} + +/// Additional configuration options for [LaunchMode.inAppWebView] +// TODO(alex): replace this when the pr lands +@immutable +class BrowserConfiguration { + /// Creates a new InAppBrowserConfiguration with given settings. + const BrowserConfiguration({this.showTitle = false}); /// Whether or not to show the webpage title when using Chrome Custom Tabs. /// 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 45193ff17cb..3ff68d05c16 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 @@ -34,7 +34,7 @@ Future launchUrlString( urlString, LaunchOptions( mode: convertLaunchMode(mode), - webViewConfiguration: convertConfiguration(webViewConfiguration), + webViewConfiguration: convertWebViewConfiguration(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 b3ce6c279f3..374ddeaa36c 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 @@ -43,6 +43,7 @@ Future launchUrl( Uri url, { LaunchMode mode = LaunchMode.platformDefault, WebViewConfiguration webViewConfiguration = const WebViewConfiguration(), + BrowserConfiguration browserConfiguration = const BrowserConfiguration(), String? webOnlyWindowName, }) async { if (mode == LaunchMode.inAppWebView && @@ -54,7 +55,8 @@ Future launchUrl( url.toString(), LaunchOptions( mode: convertLaunchMode(mode), - webViewConfiguration: convertConfiguration(webViewConfiguration), + webViewConfiguration: convertWebViewConfiguration(webViewConfiguration), + browserConfiguration: convertBrowserConfiguration(browserConfiguration), webOnlyWindowName: webOnlyWindowName, ), ); 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 5a0c503241b..45d2c003817 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 @@ -102,7 +102,7 @@ class MockUrlLauncher extends Fake expect(options.webViewConfiguration.enableJavaScript, enableJavaScript); expect(options.webViewConfiguration.enableDomStorage, enableDomStorage); expect(options.webViewConfiguration.headers, headers); - expect(options.webViewConfiguration.showTitle, showTitle); + expect(options.browserConfiguration.showTitle, showTitle); expect(options.webOnlyWindowName, webOnlyWindowName); launchCalled = true; return response!; 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 1e924c0ab5c..c01bc5258c2 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 @@ -202,10 +202,11 @@ void main() { ) ..setResponse(true); expect( - await launchUrl(url, - mode: LaunchMode.inAppWebView, - webViewConfiguration: - const WebViewConfiguration(showTitle: true)), + await launchUrl( + url, + mode: LaunchMode.inAppWebView, + browserConfiguration: const BrowserConfiguration(showTitle: true), + ), isTrue); }); diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java index f1299cec746..cffdd0202ba 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java @@ -100,19 +100,6 @@ public void setHeaders(@NonNull Map setterArg) { this.headers = setterArg; } - private @NonNull Boolean showTitle; - - public @NonNull Boolean getShowTitle() { - return showTitle; - } - - public void setShowTitle(@NonNull Boolean setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"showTitle\" is null."); - } - this.showTitle = setterArg; - } - /** Constructor is non-public to enforce null safety; use Builder. */ WebViewOptions() {} @@ -139,30 +126,21 @@ public static final class Builder { return this; } - private @Nullable Boolean showTitle; - - public @NonNull Builder setShowTitle(@NonNull Boolean setterArg) { - this.showTitle = setterArg; - return this; - } - public @NonNull WebViewOptions build() { WebViewOptions pigeonReturn = new WebViewOptions(); pigeonReturn.setEnableJavaScript(enableJavaScript); pigeonReturn.setEnableDomStorage(enableDomStorage); pigeonReturn.setHeaders(headers); - pigeonReturn.setShowTitle(showTitle); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(4); + ArrayList toListResult = new ArrayList(3); toListResult.add(enableJavaScript); toListResult.add(enableDomStorage); toListResult.add(headers); - toListResult.add(showTitle); return toListResult; } @@ -174,7 +152,54 @@ ArrayList toList() { pigeonResult.setEnableDomStorage((Boolean) enableDomStorage); Object headers = list.get(2); pigeonResult.setHeaders((Map) headers); - Object showTitle = list.get(3); + return pigeonResult; + } + } + + /** Generated class from Pigeon that represents data sent in messages. */ + public static final class BrowserOptions { + private @NonNull Boolean showTitle; + + public @NonNull Boolean getShowTitle() { + return showTitle; + } + + public void setShowTitle(@NonNull Boolean setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"showTitle\" is null."); + } + this.showTitle = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + BrowserOptions() {} + + public static final class Builder { + + private @Nullable Boolean showTitle; + + public @NonNull Builder setShowTitle(@NonNull Boolean setterArg) { + this.showTitle = setterArg; + return this; + } + + public @NonNull BrowserOptions build() { + BrowserOptions pigeonReturn = new BrowserOptions(); + pigeonReturn.setShowTitle(showTitle); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(1); + toListResult.add(showTitle); + return toListResult; + } + + static @NonNull BrowserOptions fromList(@NonNull ArrayList list) { + BrowserOptions pigeonResult = new BrowserOptions(); + Object showTitle = list.get(0); pigeonResult.setShowTitle((Boolean) showTitle); return pigeonResult; } @@ -189,6 +214,8 @@ private UrlLauncherApiCodec() {} protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { case (byte) 128: + return BrowserOptions.fromList((ArrayList) readValue(buffer)); + case (byte) 129: return WebViewOptions.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); @@ -197,8 +224,11 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof WebViewOptions) { + if (value instanceof BrowserOptions) { stream.write(128); + writeValue(stream, ((BrowserOptions) value).toList()); + } else if (value instanceof WebViewOptions) { + stream.write(129); writeValue(stream, ((WebViewOptions) value).toList()); } else { super.writeValue(stream, value); @@ -216,7 +246,10 @@ public interface UrlLauncherApi { Boolean launchUrl(@NonNull String url, @NonNull Map headers); /** Opens the URL in an in-app WebView, returning true if it opens successfully. */ @NonNull - Boolean openUrlInWebView(@NonNull String url, @NonNull WebViewOptions options); + Boolean openUrlInWebView( + @NonNull String url, + @NonNull WebViewOptions webViewOptions, + @NonNull BrowserOptions browserOptions); /** Closes the view opened by [openUrlInSafariViewController]. */ void closeWebView(); @@ -289,9 +322,11 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche ArrayList wrapped = new ArrayList(); ArrayList args = (ArrayList) message; String urlArg = (String) args.get(0); - WebViewOptions optionsArg = (WebViewOptions) args.get(1); + WebViewOptions webViewOptionsArg = (WebViewOptions) args.get(1); + BrowserOptions browserOptionsArg = (BrowserOptions) args.get(2); try { - Boolean output = api.openUrlInWebView(urlArg, optionsArg); + Boolean output = + api.openUrlInWebView(urlArg, webViewOptionsArg, browserOptionsArg); wrapped.add(0, output); } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index 63ad66cbeb1..503f3d0cb6e 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -19,6 +19,7 @@ import androidx.browser.customtabs.CustomTabsIntent; import io.flutter.plugins.urllauncher.Messages.UrlLauncherApi; import io.flutter.plugins.urllauncher.Messages.WebViewOptions; +import io.flutter.plugins.urllauncher.Messages.BrowserOptions; import java.util.Locale; import java.util.Map; @@ -95,16 +96,19 @@ void setActivity(@Nullable Activity activity) { } @Override - public @NonNull Boolean openUrlInWebView(@NonNull String url, @NonNull WebViewOptions options) { + public @NonNull Boolean openUrlInWebView( + @NonNull String url, + @NonNull WebViewOptions webViewOptions, + @NonNull BrowserOptions browserOptions) { ensureActivity(); assert activity != null; - Bundle headersBundle = extractBundle(options.getHeaders()); + Bundle headersBundle = extractBundle(webViewOptions.getHeaders()); // Try to launch using Custom Tabs if they have the necessary functionality. - if (!containsRestrictedHeader(options.getHeaders())) { + if (!containsRestrictedHeader(webViewOptions.getHeaders())) { Uri uri = Uri.parse(url); - if (openCustomTab(activity, uri, headersBundle, options)) { + if (openCustomTab(activity, uri, headersBundle, browserOptions)) { return true; } } @@ -114,8 +118,8 @@ void setActivity(@Nullable Activity activity) { WebViewActivity.createIntent( activity, url, - options.getEnableJavaScript(), - options.getEnableDomStorage(), + webViewOptions.getEnableJavaScript(), + webViewOptions.getEnableDomStorage(), headersBundle); try { activity.startActivity(launchIntent); @@ -136,7 +140,7 @@ public static boolean openCustomTab( @NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle, - @NonNull WebViewOptions options) { + @NonNull BrowserOptions options) { CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().setShowTitle(options.getShowTitle()).build(); diff --git a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java index 2ea64340aa6..30cfafcbc2d 100644 --- a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java +++ b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java @@ -149,8 +149,8 @@ public void openWebView_opensUrl_inWebView() { .setEnableJavaScript(enableJavaScript) .setEnableDomStorage(enableDomStorage) .setHeaders(headers) - .setShowTitle(showTitle) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(showTitle).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -178,8 +178,8 @@ public void openWebView_opensUrl_inCustomTabs() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) - .setShowTitle(true) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(true).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture(), isNull()); @@ -208,8 +208,8 @@ public void openWebView_opensUrl_inCustomTabs_withCORSAllowedHeader() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(headers) - .setShowTitle(false) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture(), isNull()); @@ -238,8 +238,8 @@ public void openWebView_fallsbackTo_inWebView() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) - .setShowTitle(false) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -266,8 +266,8 @@ public void openWebView_handlesEnableJavaScript() { .setEnableJavaScript(enableJavaScript) .setEnableDomStorage(false) .setHeaders(headers) - .setShowTitle(false) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -293,8 +293,8 @@ public void openWebView_handlesHeaders() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(headers) - .setShowTitle(false) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -320,8 +320,8 @@ public void openWebView_handlesEnableDomStorage() { .setEnableJavaScript(false) .setEnableDomStorage(enableDomStorage) .setHeaders(headers) - .setShowTitle(false) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -345,8 +345,8 @@ public void openWebView_handlesEnableShowTitle() { .setEnableJavaScript(false) .setEnableDomStorage(enableDomStorage) .setHeaders(headers) - .setShowTitle(showTitle) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(showTitle).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture(), isNull()); @@ -371,8 +371,8 @@ public void openWebView_throwsForNoCurrentActivity() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) - .setShowTitle(false) - .build())); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build())); assertEquals("NO_ACTIVITY", exception.code); } @@ -395,8 +395,8 @@ public void openWebView_returnsFalse() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) - .setShowTitle(false) - .build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); assertFalse(result); } diff --git a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart index dcf95de4f3e..029564c6459 100644 --- a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart +++ b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart @@ -17,7 +17,6 @@ class WebViewOptions { required this.enableJavaScript, required this.enableDomStorage, required this.headers, - required this.showTitle, }); bool enableJavaScript; @@ -26,14 +25,11 @@ class WebViewOptions { Map headers; - bool showTitle; - Object encode() { return [ enableJavaScript, enableDomStorage, headers, - showTitle, ]; } @@ -43,7 +39,27 @@ class WebViewOptions { enableJavaScript: result[0]! as bool, enableDomStorage: result[1]! as bool, headers: (result[2] as Map?)!.cast(), - showTitle: result[3]! as bool, + ); + } +} + +class BrowserOptions { + BrowserOptions({ + required this.showTitle, + }); + + bool showTitle; + + Object encode() { + return [ + showTitle, + ]; + } + + static BrowserOptions decode(Object result) { + result as List; + return BrowserOptions( + showTitle: result[0]! as bool, ); } } @@ -52,9 +68,12 @@ class _UrlLauncherApiCodec extends StandardMessageCodec { const _UrlLauncherApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is WebViewOptions) { + if (value is BrowserOptions) { buffer.putUint8(128); writeValue(buffer, value.encode()); + } else if (value is WebViewOptions) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -64,6 +83,8 @@ class _UrlLauncherApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: + return BrowserOptions.decode(readValue(buffer)!); + case 129: return WebViewOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -143,13 +164,16 @@ class UrlLauncherApi { /// Opens the URL in an in-app WebView, returning true if it opens /// successfully. Future openUrlInWebView( - String arg_url, WebViewOptions arg_options) async { + String arg_url, + WebViewOptions arg_webViewOptions, + BrowserOptions arg_browserOptions) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView', codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_url, arg_options]) as List?; + final List? replyList = await channel + .send([arg_url, arg_webViewOptions, arg_browserOptions]) + as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', diff --git a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart index eb5790ac0de..2f20ab22115 100644 --- a/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart +++ b/packages/url_launcher/url_launcher_android/lib/url_launcher_android.dart @@ -66,10 +66,14 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { enableJavaScript: enableJavaScript, enableDomStorage: enableDomStorage, headers: headers, - showTitle: false, ); - return _openInWebviewOrLaunch(url, webViewOptions, useWebView); + return _openInWebviewOrLaunch( + url, + webViewOptions, + useWebView, + BrowserOptions(showTitle: false), + ); } @override @@ -82,20 +86,33 @@ class UrlLauncherAndroid extends UrlLauncherPlatform { enableJavaScript: options.webViewConfiguration.enableJavaScript, enableDomStorage: options.webViewConfiguration.enableDomStorage, headers: options.webViewConfiguration.headers, - showTitle: options.webViewConfiguration.showTitle, ); - return _openInWebviewOrLaunch(url, webViewOptions, useWebView); + final BrowserOptions browserOptions = BrowserOptions( + showTitle: options.browserConfiguration.showTitle, + ); + + return _openInWebviewOrLaunch( + url, + webViewOptions, + useWebView, + browserOptions, + ); } Future _openInWebviewOrLaunch( - String url, WebViewOptions options, bool useWebView) async { + String url, + WebViewOptions webViewOptions, + bool useWebView, + BrowserOptions browserOptions, + ) async { final bool succeeded; if (useWebView) { - succeeded = await _hostApi.openUrlInWebView(url, options); + succeeded = + await _hostApi.openUrlInWebView(url, webViewOptions, browserOptions); } else { - succeeded = await _hostApi.launchUrl(url, options.headers); + succeeded = await _hostApi.launchUrl(url, webViewOptions.headers); } // TODO(stuartmorgan): Remove this special handling as part of a diff --git a/packages/url_launcher/url_launcher_android/pigeons/messages.dart b/packages/url_launcher/url_launcher_android/pigeons/messages.dart index 43e6cf6de4d..81d679bf74d 100644 --- a/packages/url_launcher/url_launcher_android/pigeons/messages.dart +++ b/packages/url_launcher/url_launcher_android/pigeons/messages.dart @@ -17,7 +17,6 @@ class WebViewOptions { required this.enableJavaScript, required this.enableDomStorage, this.headers = const {}, - required this.showTitle, }); final bool enableJavaScript; @@ -26,6 +25,11 @@ class WebViewOptions { // https://github.com/flutter/flutter/issues/97848 is fixed. In practice, // the values will never be null, and the native implementation assumes that. final Map headers; +} + +class BrowserOptions { + BrowserOptions({required this.showTitle}); + final bool showTitle; } @@ -39,7 +43,8 @@ abstract class UrlLauncherApi { /// Opens the URL in an in-app WebView, returning true if it opens /// successfully. - bool openUrlInWebView(String url, WebViewOptions options); + bool openUrlInWebView( + String url, WebViewOptions webViewOptions, BrowserOptions browserOptions); /// Closes the view opened by [openUrlInSafariViewController]. void closeWebView(); diff --git a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart index 02e287b747c..9e94e27368c 100644 --- a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart +++ b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart @@ -171,13 +171,13 @@ void main() { await launcher.launchUrl( 'http://example.com/', const LaunchOptions( - webViewConfiguration: InAppWebViewConfiguration( + browserConfiguration: InAppBrowserConfiguration( showTitle: true, ), ), ); - expect(api.passedWebViewOptions?.showTitle, true); + expect(api.passedBrowserOptions?.showTitle, true); }); test('passes through no-activity exception', () async { @@ -227,6 +227,7 @@ void main() { /// See _launch for the behaviors. class _FakeUrlLauncherApi implements UrlLauncherApi { WebViewOptions? passedWebViewOptions; + BrowserOptions? passedBrowserOptions; bool? usedWebView; bool? closed; @@ -244,8 +245,12 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { enableJavaScript: false, enableDomStorage: false, headers: headers, + ); + + passedBrowserOptions = BrowserOptions( showTitle: true, ); + usedWebView = false; return _launch(url); } @@ -256,8 +261,13 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { } @override - Future openUrlInWebView(String url, WebViewOptions options) async { - passedWebViewOptions = options; + Future openUrlInWebView( + String url, + WebViewOptions webViewOptions, + BrowserOptions browserOptions, + ) async { + passedWebViewOptions = webViewOptions; + passedBrowserOptions = browserOptions; usedWebView = true; return _launch(url); } diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart index c6dc839a4c9..a8ee35c1d2c 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart @@ -34,7 +34,6 @@ class InAppWebViewConfiguration { this.enableJavaScript = true, this.enableDomStorage = true, this.headers = const {}, - this.showTitle = false, }); /// Whether or not JavaScript is enabled for the web content. @@ -45,6 +44,14 @@ class InAppWebViewConfiguration { /// Additional headers to pass in the load request. final Map headers; +} + +/// Additional configuration options for [PreferredLaunchMode.inAppWebView] +// TODO(alex): replace this when the pr lands +@immutable +class InAppBrowserConfiguration { + /// Creates a new InAppBrowserConfiguration with given settings. + const InAppBrowserConfiguration({this.showTitle = false}); /// Whether or not to show the webpage title when using Chrome Custom Tabs. /// @@ -59,6 +66,7 @@ class LaunchOptions { const LaunchOptions({ this.mode = PreferredLaunchMode.platformDefault, this.webViewConfiguration = const InAppWebViewConfiguration(), + this.browserConfiguration = const InAppBrowserConfiguration(), this.webOnlyWindowName, }); @@ -68,6 +76,10 @@ class LaunchOptions { /// Configuration for the web view in [PreferredLaunchMode.inAppWebView] mode. final InAppWebViewConfiguration webViewConfiguration; + /// Configuration for the browser view in [PreferredLaunchMode.inAppWebView] mode. +// TODO(alex): replace this when the pr lands + final InAppBrowserConfiguration browserConfiguration; + /// A web-platform-specific option to set the link target. /// /// Default behaviour when unset should be to open the url in a new tab. From 157343ba4a96ab02929d29986a4f468d12a5f178 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 20 Oct 2023 13:58:30 +0500 Subject: [PATCH 10/28] Remove deps overrides --- packages/go_router/example/pubspec.yaml | 4 ---- packages/url_launcher/url_launcher_ios/pubspec.yaml | 5 ----- packages/url_launcher/url_launcher_linux/pubspec.yaml | 5 ----- packages/url_launcher/url_launcher_macos/pubspec.yaml | 5 ----- packages/url_launcher/url_launcher_web/pubspec.yaml | 5 ----- packages/url_launcher/url_launcher_windows/pubspec.yaml | 4 ---- 6 files changed, 28 deletions(-) diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml index c2082b162bf..c5597e1993e 100644 --- a/packages/go_router/example/pubspec.yaml +++ b/packages/go_router/example/pubspec.yaml @@ -27,7 +27,3 @@ dev_dependencies: flutter: uses-material-design: true -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher: {path: ../../url_launcher/url_launcher}} diff --git a/packages/url_launcher/url_launcher_ios/pubspec.yaml b/packages/url_launcher/url_launcher_ios/pubspec.yaml index 43d58cb6f3c..8b45ed75054 100644 --- a/packages/url_launcher/url_launcher_ios/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/pubspec.yaml @@ -33,8 +33,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index 65e615ed205..2649beeecb9 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -31,8 +31,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index 45e09ee396d..23d5f6a2f47 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -33,8 +33,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 8c6f3e65b61..fce7da421b1 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -32,8 +32,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index ddc595ca907..97a215dfcf9 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -33,7 +33,3 @@ topics: - url-launcher - urls -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} From ae20b0895ff72586b28058cd56f7479c62fc9421 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 20 Oct 2023 14:11:48 +0500 Subject: [PATCH 11/28] Revert more deps overrides --- packages/url_launcher/url_launcher_ios/example/pubspec.yaml | 5 ----- .../url_launcher/url_launcher_linux/example/pubspec.yaml | 5 ----- .../url_launcher/url_launcher_macos/example/pubspec.yaml | 5 ----- .../url_launcher/url_launcher_windows/example/pubspec.yaml | 5 ----- packages/url_launcher/url_launcher_windows/pubspec.yaml | 1 - 5 files changed, 21 deletions(-) diff --git a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml index 793cde0144d..d755c553f6a 100644 --- a/packages/url_launcher/url_launcher_ios/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_ios/example/pubspec.yaml @@ -27,8 +27,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index ff6a34aabdf..0dd4a4cf8a3 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -26,8 +26,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index bbe82f8c505..0ad23902782 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -26,8 +26,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index b9e23486d63..77106bc48a7 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -26,8 +26,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index 97a215dfcf9..6b17b9d7c55 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -32,4 +32,3 @@ topics: - os-integration - url-launcher - urls - From 214b0a9a0ef0ff85e2d3dba74f75b975a8f6ee7f Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 20 Oct 2023 14:12:21 +0500 Subject: [PATCH 12/28] Revert web as well --- packages/url_launcher/url_launcher_web/example/pubspec.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index adc6f4da5f3..9915164471a 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -19,8 +19,3 @@ dev_dependencies: url_launcher_platform_interface: ^2.0.3 url_launcher_web: path: ../ - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} From cd7dfc9d17543477adc60738fe894c38c9fcd054 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 20 Oct 2023 14:14:35 +0500 Subject: [PATCH 13/28] Revert go_router --- packages/go_router/example/pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml index c5597e1993e..3ff5906016d 100644 --- a/packages/go_router/example/pubspec.yaml +++ b/packages/go_router/example/pubspec.yaml @@ -26,4 +26,3 @@ dev_dependencies: flutter: uses-material-design: true - From c86ff6ef53d0c76ac5db5976ee2ff3b8276f2251 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 27 Oct 2023 16:52:55 +0500 Subject: [PATCH 14/28] Format files --- .../flutter/plugins/urllauncher/Messages.java | 73 ++++++++++--------- .../plugins/urllauncher/UrlLauncher.java | 2 +- .../lib/src/messages.g.dart | 42 +++++++---- 3 files changed, 66 insertions(+), 51 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java index 6e8efe3b352..ff79d632093 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/Messages.java @@ -16,10 +16,6 @@ import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; import java.util.Map; /** Generated class from Pigeon. */ @@ -35,8 +31,7 @@ public static class FlutterError extends RuntimeException { /** The error details. Must be a datatype supported by the api codec. */ public final Object details; - public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) - { + public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) { super(message); this.code = code; this.details = details; @@ -55,7 +50,7 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { errorList.add(exception.toString()); errorList.add(exception.getClass().getSimpleName()); errorList.add( - "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); } return errorList; } @@ -63,7 +58,7 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { /** * Configuration options for an in-app WebView. * - * Generated class from Pigeon that represents data sent in messages. + *

Generated class from Pigeon that represents data sent in messages. */ public static final class WebViewOptions { private @NonNull Boolean enableJavaScript; @@ -244,19 +239,20 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface UrlLauncherApi { /** Returns true if the URL can definitely be launched. */ - @NonNull + @NonNull Boolean canLaunchUrl(@NonNull String url); /** Opens the URL externally, returning true if successful. */ - @NonNull + @NonNull Boolean launchUrl(@NonNull String url, @NonNull Map headers); - /** - * Opens the URL in an in-app WebView, returning true if it opens - * successfully. - */ - @NonNull - Boolean openUrlInApp(@NonNull String url, @NonNull Boolean allowCustomTab, @NonNull WebViewOptions webViewOptions, @NonNull BrowserOptions browserOptions); - - @NonNull + /** Opens the URL in an in-app WebView, returning true if it opens successfully. */ + @NonNull + Boolean openUrlInApp( + @NonNull String url, + @NonNull Boolean allowCustomTab, + @NonNull WebViewOptions webViewOptions, + @NonNull BrowserOptions browserOptions); + + @NonNull Boolean supportsCustomTabs(); /** Closes the view opened by [openUrlInSafariViewController]. */ void closeWebView(); @@ -265,12 +261,14 @@ public interface UrlLauncherApi { static @NonNull MessageCodec getCodec() { return UrlLauncherApiCodec.INSTANCE; } - /**Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ + /** Sets up an instance of `UrlLauncherApi` to handle messages through the `binaryMessenger`. */ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLauncherApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -280,8 +278,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.canLaunchUrl(urlArg); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -294,7 +291,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -305,8 +304,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.launchUrl(urlArg, headersArg); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -319,7 +317,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -330,10 +330,11 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche WebViewOptions webViewOptionsArg = (WebViewOptions) args.get(2); BrowserOptions browserOptionsArg = (BrowserOptions) args.get(3); try { - Boolean output = api.openUrlInApp(urlArg, allowCustomTabArg, webViewOptionsArg, browserOptionsArg); + Boolean output = + api.openUrlInApp( + urlArg, allowCustomTabArg, webViewOptionsArg, browserOptionsArg); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -346,7 +347,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -354,8 +357,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { Boolean output = api.supportsCustomTabs(); wrapped.add(0, output); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -368,7 +370,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche { BasicMessageChannel channel = new BasicMessageChannel<>( - binaryMessenger, "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView", getCodec()); + binaryMessenger, + "dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView", + getCodec()); if (api != null) { channel.setMessageHandler( (message, reply) -> { @@ -376,8 +380,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche try { api.closeWebView(); wrapped.add(0, null); - } - catch (Throwable exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index 3f9ed23cad9..90d21ef9d24 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -18,9 +18,9 @@ import androidx.annotation.VisibleForTesting; import androidx.browser.customtabs.CustomTabsClient; import androidx.browser.customtabs.CustomTabsIntent; +import io.flutter.plugins.urllauncher.Messages.BrowserOptions; import io.flutter.plugins.urllauncher.Messages.UrlLauncherApi; import io.flutter.plugins.urllauncher.Messages.WebViewOptions; -import io.flutter.plugins.urllauncher.Messages.BrowserOptions; import java.util.Collections; import java.util.Locale; import java.util.Map; diff --git a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart index 1aafd6e1d68..546f969c880 100644 --- a/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart +++ b/packages/url_launcher/url_launcher_android/lib/src/messages.g.dart @@ -82,9 +82,9 @@ class _UrlLauncherApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 128: return BrowserOptions.decode(readValue(buffer)!); - case 129: + case 129: return WebViewOptions.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -105,7 +105,8 @@ class UrlLauncherApi { /// Returns true if the URL can definitely be launched. Future canLaunchUrl(String arg_url) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url]) as List?; @@ -131,9 +132,11 @@ class UrlLauncherApi { } /// Opens the URL externally, returning true if successful. - Future launchUrl(String arg_url, Map arg_headers) async { + Future launchUrl( + String arg_url, Map arg_headers) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_url, arg_headers]) as List?; @@ -160,12 +163,21 @@ class UrlLauncherApi { /// Opens the URL in an in-app WebView, returning true if it opens /// successfully. - Future openUrlInApp(String arg_url, bool arg_allowCustomTab, WebViewOptions arg_webViewOptions, BrowserOptions arg_browserOptions) async { + Future openUrlInApp( + String arg_url, + bool arg_allowCustomTab, + WebViewOptions arg_webViewOptions, + BrowserOptions arg_browserOptions) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_url, arg_allowCustomTab, arg_webViewOptions, arg_browserOptions]) as List?; + final List? replyList = await channel.send([ + arg_url, + arg_allowCustomTab, + arg_webViewOptions, + arg_browserOptions + ]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -189,10 +201,10 @@ class UrlLauncherApi { Future supportsCustomTabs() async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send(null) as List?; + final List? replyList = await channel.send(null) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -217,10 +229,10 @@ class UrlLauncherApi { /// Closes the view opened by [openUrlInSafariViewController]. Future closeWebView() async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', codec, + 'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send(null) as List?; + final List? replyList = await channel.send(null) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', From 92b2197bc8d11775d1566c041d8c4b9e51e35ba0 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 27 Oct 2023 16:56:57 +0500 Subject: [PATCH 15/28] Fix tests --- .../java/io/flutter/plugins/urllauncher/UrlLauncherTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java index e4aefbb6b12..30b32516a3b 100644 --- a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java +++ b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java @@ -180,7 +180,7 @@ public void openWebView_opensUrlInWebViewIfRequested() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) - .build()); + .build(), new Messages.BrowserOptions.Builder().setShowTitle(true).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -369,8 +369,9 @@ public void openWebView_handlesEnableShowTitle() { HashMap headers = new HashMap<>(); boolean showTitle = true; - api.openUrlInWebView( + api.openUrlInApp( "https://flutter.dev", + true, new Messages.WebViewOptions.Builder() .setEnableJavaScript(false) .setEnableDomStorage(enableDomStorage) From 425617e04830f47642db7ab964ceef6d93c7a29c Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Mon, 30 Oct 2023 10:38:45 +0500 Subject: [PATCH 16/28] Add browseroptions to launchUrlString & add more tests --- .../lib/src/url_launcher_string.dart | 2 + .../test/src/url_launcher_string_test.dart | 44 ++++++++++++ .../test/src/url_launcher_uri_test.dart | 6 +- .../plugins/urllauncher/UrlLauncherTest.java | 70 +++++++++++++++++-- 4 files changed, 114 insertions(+), 8 deletions(-) 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 7009cb54eb0..bf878c60dde 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 @@ -23,6 +23,7 @@ Future launchUrlString( String urlString, { LaunchMode mode = LaunchMode.platformDefault, WebViewConfiguration webViewConfiguration = const WebViewConfiguration(), + BrowserConfiguration browserConfiguration = const BrowserConfiguration(), String? webOnlyWindowName, }) async { if ((mode == LaunchMode.inAppWebView || @@ -36,6 +37,7 @@ Future launchUrlString( LaunchOptions( mode: convertLaunchMode(mode), webViewConfiguration: convertWebViewConfiguration(webViewConfiguration), + browserConfiguration: convertBrowserConfiguration(browserConfiguration), webOnlyWindowName: webOnlyWindowName, ), ); 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 a5021694cc6..0cd0f9b2eb5 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 @@ -144,6 +144,50 @@ void main() { isTrue); }); + test('in-app browser', () async { + const String urlString = 'https://flutter.dev'; + mock + ..setLaunchExpectations( + url: urlString, + launchMode: PreferredLaunchMode.inAppBrowserView, + enableJavaScript: true, + enableDomStorage: true, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + showTitle: false, + ) + ..setResponse(true); + expect( + await launchUrlString(urlString, mode: LaunchMode.inAppBrowserView), + isTrue, + ); + }); + + test('in-app browser with title', () async { + const String urlString = 'https://flutter.dev'; + mock + ..setLaunchExpectations( + url: urlString, + launchMode: PreferredLaunchMode.inAppBrowserView, + enableJavaScript: true, + enableDomStorage: true, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + showTitle: true, + ) + ..setResponse(true); + expect( + await launchUrlString( + urlString, + mode: LaunchMode.inAppBrowserView, + browserConfiguration: const BrowserConfiguration(showTitle: true), + ), + isTrue, + ); + }); + test('external non-browser only', () async { const String urlString = 'https://flutter.dev'; mock 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 a08e53b4677..15796ea659a 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 @@ -187,12 +187,12 @@ void main() { isTrue); }); - test('in-app webview with show title', () async { + test('in-app browser view with show title', () async { final Uri url = Uri.parse('https://flutter.dev'); mock ..setLaunchExpectations( url: url.toString(), - launchMode: PreferredLaunchMode.inAppWebView, + launchMode: PreferredLaunchMode.inAppBrowserView, enableJavaScript: true, enableDomStorage: true, universalLinksOnly: false, @@ -204,7 +204,7 @@ void main() { expect( await launchUrl( url, - mode: LaunchMode.inAppWebView, + mode: LaunchMode.inAppBrowserView, browserConfiguration: const BrowserConfiguration(showTitle: true), ), isTrue); diff --git a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java index 30b32516a3b..b808da57d19 100644 --- a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java +++ b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java @@ -180,7 +180,8 @@ public void openWebView_opensUrlInWebViewIfRequested() { .setEnableJavaScript(false) .setEnableDomStorage(false) .setHeaders(new HashMap<>()) - .build(), new Messages.BrowserOptions.Builder().setShowTitle(true).build()); + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(true).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture()); @@ -204,16 +205,13 @@ public void openWebView_opensUrlInCustomTabs() { .setEnableDomStorage(false) .setHeaders(new HashMap<>()) .build(), - new Messages.BrowserOptions.Builder().setShowTitle(true).build()); + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(intentCaptor.capture(), isNull()); assertTrue(result); assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); assertNull(intentCaptor.getValue().getComponent()); - assertEquals( - intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), - CustomTabsIntent.SHOW_PAGE_TITLE); } @Test @@ -247,6 +245,68 @@ public void openWebView_opensUrlInCustomTabsWithCORSAllowedHeader() { assertEquals(headers.get(headerKey), passedHeaders.getString(headerKey)); } + @Test + public void openWebView_opensUrlInCustomTabsWithShowTitle() { + Activity activity = mock(Activity.class); + UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext()); + api.setActivity(activity); + String url = "https://flutter.dev"; + HashMap headers = new HashMap<>(); + String headerKey = "Content-Type"; + headers.put(headerKey, "text/plain"); + + boolean result = + api.openUrlInApp( + url, + true, + new Messages.WebViewOptions.Builder() + .setEnableJavaScript(false) + .setEnableDomStorage(false) + .setHeaders(headers) + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(true).build()); + + final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(activity).startActivity(intentCaptor.capture(), isNull()); + assertTrue(result); + assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); + assertNull(intentCaptor.getValue().getComponent()); + assertEquals( + intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), + CustomTabsIntent.SHOW_PAGE_TITLE); + } + + @Test + public void openWebView_opensUrlInCustomTabsWithoutShowTitle() { + Activity activity = mock(Activity.class); + UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext()); + api.setActivity(activity); + String url = "https://flutter.dev"; + HashMap headers = new HashMap<>(); + String headerKey = "Content-Type"; + headers.put(headerKey, "text/plain"); + + boolean result = + api.openUrlInApp( + url, + true, + new Messages.WebViewOptions.Builder() + .setEnableJavaScript(false) + .setEnableDomStorage(false) + .setHeaders(headers) + .build(), + new Messages.BrowserOptions.Builder().setShowTitle(false).build()); + + final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(activity).startActivity(intentCaptor.capture(), isNull()); + assertTrue(result); + assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); + assertNull(intentCaptor.getValue().getComponent()); + assertEquals( + intentCaptor.getValue().getExtras().getInt(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE), + CustomTabsIntent.NO_TITLE); + } + @Test public void openWebView_fallsBackToWebViewIfCustomTabFails() { Activity activity = mock(Activity.class); From ece2b78a24b9a5fbf1fc27f199eeb99e06da4e11 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Thu, 7 Dec 2023 17:49:11 +0500 Subject: [PATCH 17/28] Fix docstrings --- packages/url_launcher/url_launcher/lib/src/types.dart | 4 ++-- .../url_launcher_android/pigeons/messages.dart | 8 ++++++-- .../url_launcher_platform_interface/lib/src/types.dart | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/url_launcher/url_launcher/lib/src/types.dart b/packages/url_launcher/url_launcher/lib/src/types.dart index dd2baea81fd..c8df68faadb 100644 --- a/packages/url_launcher/url_launcher/lib/src/types.dart +++ b/packages/url_launcher/url_launcher/lib/src/types.dart @@ -62,8 +62,8 @@ class BrowserConfiguration { /// Creates a new InAppBrowserConfiguration with given settings. const BrowserConfiguration({this.showTitle = false}); - /// Whether or not to show the webpage title when using Chrome Custom Tabs. + /// Whether or not to show the webpage title. /// - /// Only works on Android. + /// May not be supported on all platforms. final bool showTitle; } diff --git a/packages/url_launcher/url_launcher_android/pigeons/messages.dart b/packages/url_launcher/url_launcher_android/pigeons/messages.dart index 3fe8c60890d..1cfdd403044 100644 --- a/packages/url_launcher/url_launcher_android/pigeons/messages.dart +++ b/packages/url_launcher/url_launcher_android/pigeons/messages.dart @@ -27,9 +27,13 @@ class WebViewOptions { final Map headers; } +/// Configuration options for in-app browser views. class BrowserOptions { BrowserOptions({required this.showTitle}); + /// Whether or not to show the webpage title. + /// + /// May not be supported on all platforms. final bool showTitle; } @@ -41,8 +45,8 @@ abstract class UrlLauncherApi { /// Opens the URL externally, returning true if successful. bool launchUrl(String url, Map headers); - /// Opens the URL in an in-app WebView, returning true if it opens - /// successfully. + /// Opens the URL in an in-app Custom Tab or WebView, returning true if it + /// opens successfully. bool openUrlInApp( String url, bool allowCustomTab, diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart index 8c4973e7884..6b5b7bf2a15 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart @@ -56,9 +56,9 @@ class InAppBrowserConfiguration { /// Creates a new InAppBrowserConfiguration with given settings. const InAppBrowserConfiguration({this.showTitle = false}); - /// Whether or not to show the webpage title when using Chrome Custom Tabs. + /// Whether or not to show the webpage title. /// - /// Only works on Android. + /// May not be supported on all platforms. final bool showTitle; } From 3ddd644796f02ebabd446e7e8a46c3c1b87c501e Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Thu, 7 Dec 2023 17:49:16 +0500 Subject: [PATCH 18/28] Revert test format change --- .../integration_test/url_launcher_test.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart index 9a00699d220..7aa221b3e1a 100644 --- a/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_android/example/integration_test/url_launcher_test.dart @@ -43,15 +43,13 @@ void main() { // Launch a url then close. expect( - await launcher.launch( - primaryUrl, - useSafariVC: true, - useWebView: true, - enableJavaScript: false, - enableDomStorage: false, - universalLinksOnly: false, - headers: {}, - ), + await launcher.launch(primaryUrl, + useSafariVC: true, + useWebView: true, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}), true); await launcher.closeWebView(); // Delay required to catch android side crashes in onDestroy. From cd361d0329fefb377ec9925ab52a6d10d2529a0e Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 8 Dec 2023 12:34:32 +0500 Subject: [PATCH 19/28] Fix tests --- .../plugins/urllauncher/UrlLauncher.java | 6 ++--- .../plugins/urllauncher/UrlLauncherTest.java | 4 ---- .../test/url_launcher_android_test.dart | 4 ---- .../in_app_browser_configuration_test.dart | 12 ++++++++++ .../test/launch_options_test.dart | 24 +++++++++++++++++++ 5 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart create mode 100644 packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart diff --git a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index 90d21ef9d24..35094e79944 100644 --- a/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher_android/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -144,8 +144,7 @@ public void closeWebView() { return CustomTabsClient.getPackageName(applicationContext, Collections.emptyList()) != null; } - @VisibleForTesting - public static boolean openCustomTab( + private static boolean openCustomTab( @NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle, @@ -179,8 +178,7 @@ private static boolean containsRestrictedHeader(Map headersMap) return false; } - @VisibleForTesting - public static @NonNull Bundle extractBundle(Map headersMap) { + private static @NonNull Bundle extractBundle(Map headersMap) { final Bundle headersBundle = new Bundle(); for (String key : headersMap.keySet()) { final String value = headersMap.get(key); diff --git a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java index b808da57d19..9a545a54b43 100644 --- a/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java +++ b/packages/url_launcher/url_launcher_android/android/src/test/java/io/flutter/plugins/urllauncher/UrlLauncherTest.java @@ -252,8 +252,6 @@ public void openWebView_opensUrlInCustomTabsWithShowTitle() { api.setActivity(activity); String url = "https://flutter.dev"; HashMap headers = new HashMap<>(); - String headerKey = "Content-Type"; - headers.put(headerKey, "text/plain"); boolean result = api.openUrlInApp( @@ -283,8 +281,6 @@ public void openWebView_opensUrlInCustomTabsWithoutShowTitle() { api.setActivity(activity); String url = "https://flutter.dev"; HashMap headers = new HashMap<>(); - String headerKey = "Content-Type"; - headers.put(headerKey, "text/plain"); boolean result = api.openUrlInApp( diff --git a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart index 138b8dce819..7b469246a5c 100644 --- a/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart +++ b/packages/url_launcher/url_launcher_android/test/url_launcher_android_test.dart @@ -436,10 +436,6 @@ class _FakeUrlLauncherApi implements UrlLauncherApi { headers: headers, ); - passedBrowserOptions = BrowserOptions( - showTitle: true, - ); - usedWebView = false; return _launch(url); } diff --git a/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart new file mode 100644 index 00000000000..456d5dc3498 --- /dev/null +++ b/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart @@ -0,0 +1,12 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; + +void main() { + test('InAppBrowserConfiguration defaults to showTitle false', () { + expect(const InAppBrowserConfiguration().showTitle, false); + }); + + test('InAppBrowserConfiguration showTitle can be set to true', () { + expect(const InAppBrowserConfiguration(showTitle: true).showTitle, true); + }); +} diff --git a/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart new file mode 100644 index 00000000000..436fe6934ad --- /dev/null +++ b/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart @@ -0,0 +1,24 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; + +void main() { + test('LaunchOptions have default InAppBrowserConfiguration when not passed', + () { + expect( + const LaunchOptions().browserConfiguration, + const InAppBrowserConfiguration(), + ); + }); + + test('passing non-default InAppBrowserConfiguration to LaunchOptions works', + () { + const InAppBrowserConfiguration browserConfiguration = + InAppBrowserConfiguration(showTitle: true); + + const LaunchOptions launchOptions = LaunchOptions( + browserConfiguration: browserConfiguration, + ); + + expect(launchOptions.browserConfiguration, browserConfiguration); + }); +} From f0017b754176ec4b53b79c132322806eac7ce45c Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 8 Dec 2023 13:13:03 +0500 Subject: [PATCH 20/28] Version bumps and changelogs --- packages/url_launcher/url_launcher/CHANGELOG.md | 5 +++++ .../url_launcher/url_launcher/example/pubspec.yaml | 5 ----- packages/url_launcher/url_launcher/pubspec.yaml | 11 +++-------- .../url_launcher/url_launcher_android/CHANGELOG.md | 5 +++++ .../url_launcher_android/example/pubspec.yaml | 5 ----- .../url_launcher/url_launcher_android/pubspec.yaml | 7 +------ .../url_launcher_platform_interface/CHANGELOG.md | 6 ++++++ .../url_launcher_platform_interface/pubspec.yaml | 2 +- 8 files changed, 21 insertions(+), 25 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index db1516640df..7ba108a464e 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.3.0 + +* Adds `BrowserConfiguration` parameter, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController. +* Adds `showTitle` to `BrowserConfiguration`, to allow showing webpage titles in in-app browser views. + ## 6.2.1 * Fixes incorrect types in `supportsLaunchMode` and diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 514b4ec9bc2..18cc9c45044 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -29,8 +29,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher: {path: ../../../url_launcher/url_launcher}, url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 73ca34ff165..1140000d1cd 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/packages/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.2.1 +version: 6.3.0 environment: sdk: ">=3.1.0 <4.0.0" @@ -28,13 +28,13 @@ flutter: dependencies: flutter: sdk: flutter - url_launcher_android: ^6.2.0 + url_launcher_android: ^6.3.0 url_launcher_ios: ^6.2.0 # Allow either the pure-native or Dart/native hybrid versions of the desktop # implementations, as both are compatible. url_launcher_linux: ^3.1.0 url_launcher_macos: ^3.1.0 - url_launcher_platform_interface: ^2.2.0 + url_launcher_platform_interface: ^2.3.0 url_launcher_web: ^2.2.0 url_launcher_windows: ^3.1.0 @@ -50,8 +50,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_android: {path: ../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md index cf0da2faf25..f1c01adf047 100644 --- a/packages/url_launcher/url_launcher_android/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.3.0 + +* Implement taking in `BrowserConfiguration` parameter +* Implement `showTitle` functionality for Android Custom Tabs + ## 6.2.0 * Adds support for `inAppBrowserView` as a separate launch mode option from diff --git a/packages/url_launcher/url_launcher_android/example/pubspec.yaml b/packages/url_launcher/url_launcher_android/example/pubspec.yaml index 309ca202138..d234884c6b1 100644 --- a/packages/url_launcher/url_launcher_android/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/example/pubspec.yaml @@ -28,8 +28,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index c7d4c62e449..9c781d2ab00 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher_android description: Android implementation of the url_launcher plugin. repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.2.0 +version: 6.3.0 environment: sdk: ">=2.19.0 <4.0.0" flutter: ">=3.7.0" @@ -34,8 +34,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 04facb782b0..4145e6b8114 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.3.0 + +* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController. +* Adds `showTitle` parameter to `InAppBrowserConfiguration` in order to control web-page title visibility. + + ## 2.2.0 * Adds a new `inAppBrowserView` launch mode, to distinguish in-app browser diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index a999793f58e..0ec06fe5fdb 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.2.0 +version: 2.3.0 environment: sdk: ">=2.19.0 <4.0.0" From a50be0fe006bf5845fa9d3bc4abb4ec837fb69b3 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 8 Dec 2023 16:05:59 +0500 Subject: [PATCH 21/28] Return path-based dependencies --- packages/url_launcher/url_launcher/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_android/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher_android/pubspec.yaml | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 8951d07fc48..f1dacc8a015 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -29,3 +29,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher: {path: ../../../url_launcher/url_launcher}, url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 58b998310b4..91d23c0ed85 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -50,3 +50,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_android: {path: ../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/example/pubspec.yaml b/packages/url_launcher/url_launcher_android/example/pubspec.yaml index 0587fd6d95c..91794cecbd1 100644 --- a/packages/url_launcher/url_launcher_android/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/example/pubspec.yaml @@ -28,3 +28,8 @@ dev_dependencies: flutter: uses-material-design: true + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index 0f4f846bc5b..24525e33fb7 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -34,3 +34,8 @@ topics: - os-integration - url-launcher - urls + +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins +dependency_overrides: + {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} From ef9c154cacc8e392cda1468e0c7a10b4e62560ab Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Mon, 11 Dec 2023 12:11:12 +0500 Subject: [PATCH 22/28] Add licences --- .../test/in_app_browser_configuration_test.dart | 4 ++++ .../test/launch_options_test.dart | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart index 456d5dc3498..33c7fcdab73 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/in_app_browser_configuration_test.dart @@ -1,3 +1,7 @@ +// 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:flutter_test/flutter_test.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; diff --git a/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart index 436fe6934ad..9f559e88dcb 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/launch_options_test.dart @@ -1,3 +1,7 @@ +// 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:flutter_test/flutter_test.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; From 80d439bbd5c9fc2db5a2b51db22572bf33c3beda Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 26 Dec 2023 17:31:53 +0500 Subject: [PATCH 23/28] Fix documentation & changelog --- packages/url_launcher/url_launcher/example/lib/main.dart | 2 +- packages/url_launcher/url_launcher_android/CHANGELOG.md | 4 ++-- .../url_launcher_platform_interface/lib/src/types.dart | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index b33503f3ee1..e3a353f81ed 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -234,7 +234,7 @@ class _MyHomePageState extends State { onPressed: () => setState(() { _launched = _launchInAppWithBrowserOptions(toLaunch); }), - child: const Text('Launch in app with showTitle'), + child: const Text('Launch in app with title displayed'), ), const Padding(padding: EdgeInsets.all(16.0)), Link( diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md index ecee81d7954..47bd031363b 100644 --- a/packages/url_launcher/url_launcher_android/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md @@ -1,7 +1,7 @@ ## 6.3.0 -* Implement taking in `BrowserConfiguration` parameter -* Implement `showTitle` functionality for Android Custom Tabs +* Implements taking in `BrowserConfiguration` parameter. +* Implements `showTitle` functionality for Android Custom Tabs. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. ## 6.2.0 diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart index 6b5b7bf2a15..9e3b3ad1a3e 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart @@ -50,7 +50,7 @@ class InAppWebViewConfiguration { final Map headers; } -/// Additional configuration options for [PreferredLaunchMode.inAppBrowserView] +/// Additional configuration options for [PreferredLaunchMode.inAppBrowserView]. @immutable class InAppBrowserConfiguration { /// Creates a new InAppBrowserConfiguration with given settings. From fd6f0f26fe3b56fb2cb8053842bd00e48b36e145 Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Tue, 26 Dec 2023 17:57:49 +0500 Subject: [PATCH 24/28] Revert everything except for android implementation --- .../url_launcher/url_launcher/CHANGELOG.md | 5 -- .../url_launcher/example/lib/main.dart | 17 ------ .../url_launcher/example/pubspec.yaml | 5 -- .../url_launcher/lib/src/type_conversion.dart | 12 +--- .../url_launcher/lib/src/types.dart | 12 ---- .../lib/src/url_launcher_string.dart | 4 +- .../lib/src/url_launcher_uri.dart | 4 +- .../url_launcher/url_launcher/pubspec.yaml | 11 +--- .../url_launcher/test/link_test.dart | 2 - .../mocks/mock_url_launcher_platform.dart | 5 -- .../test/src/legacy_api_test.dart | 12 ---- .../test/src/url_launcher_string_test.dart | 56 ------------------- .../test/src/url_launcher_uri_test.dart | 34 ----------- .../CHANGELOG.md | 5 +- .../lib/src/types.dart | 16 ------ .../pubspec.yaml | 2 +- 16 files changed, 8 insertions(+), 194 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 7c06c8d2760..c1523e11d15 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,8 +1,3 @@ -## 6.3.0 - -* Adds `BrowserConfiguration` parameter, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController. -* Adds `showTitle` to `BrowserConfiguration`, to allow showing webpage titles in in-app browser views. - ## 6.2.2 * Adds a link about web limitations to the `url_launcher_web` package in the diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index e3a353f81ed..40307a3f715 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -74,16 +74,6 @@ class _MyHomePageState extends State { } } - Future _launchInAppWithBrowserOptions(Uri url) async { - if (!await launchUrl( - url, - mode: LaunchMode.inAppBrowserView, - browserConfiguration: const BrowserConfiguration(showTitle: true), - )) { - throw Exception('Could not launch $url'); - } - } - Future _launchAsInAppWebViewWithCustomHeaders(Uri url) async { if (!await launchUrl( url, @@ -230,13 +220,6 @@ class _MyHomePageState extends State { child: const Text('Launch in app + close after 5 seconds'), ), const Padding(padding: EdgeInsets.all(16.0)), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInAppWithBrowserOptions(toLaunch); - }), - child: const Text('Launch in app with title displayed'), - ), - const Padding(padding: EdgeInsets.all(16.0)), Link( uri: Uri.parse( 'https://pub.dev/documentation/url_launcher/latest/link/link-library.html'), diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index f1dacc8a015..8951d07fc48 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -29,8 +29,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher: {path: ../../../url_launcher/url_launcher}, url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart index 187b7839d42..3169e25dfa7 100644 --- a/packages/url_launcher/url_launcher/lib/src/type_conversion.dart +++ b/packages/url_launcher/url_launcher/lib/src/type_conversion.dart @@ -8,8 +8,7 @@ import 'types.dart'; /// Converts an (app-facing) [WebViewConfiguration] to a (platform interface) /// [InAppWebViewConfiguration]. -InAppWebViewConfiguration convertWebViewConfiguration( - WebViewConfiguration config) { +InAppWebViewConfiguration convertConfiguration(WebViewConfiguration config) { return InAppWebViewConfiguration( enableJavaScript: config.enableJavaScript, enableDomStorage: config.enableDomStorage, @@ -17,15 +16,6 @@ InAppWebViewConfiguration convertWebViewConfiguration( ); } -/// Converts an (app-facing) [BrowserConfiguration] to a (platform interface) -/// [InApp]. -InAppBrowserConfiguration convertBrowserConfiguration( - BrowserConfiguration config) { - return InAppBrowserConfiguration( - showTitle: config.showTitle, - ); -} - /// Converts an (app-facing) [LaunchMode] to a (platform interface) /// [PreferredLaunchMode]. PreferredLaunchMode convertLaunchMode(LaunchMode mode) { diff --git a/packages/url_launcher/url_launcher/lib/src/types.dart b/packages/url_launcher/url_launcher/lib/src/types.dart index c8df68faadb..2bf56e1b5d8 100644 --- a/packages/url_launcher/url_launcher/lib/src/types.dart +++ b/packages/url_launcher/url_launcher/lib/src/types.dart @@ -55,15 +55,3 @@ class WebViewConfiguration { /// Not all browsers support this, so it is not guaranteed to be honored. final Map headers; } - -/// Additional configuration options for [LaunchMode.inAppBrowserView] -@immutable -class BrowserConfiguration { - /// Creates a new InAppBrowserConfiguration with given settings. - const BrowserConfiguration({this.showTitle = false}); - - /// Whether or not to show the webpage title. - /// - /// May not be supported on all platforms. - final bool showTitle; -} 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 bf878c60dde..ca0bcc6109d 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 @@ -23,7 +23,6 @@ Future launchUrlString( String urlString, { LaunchMode mode = LaunchMode.platformDefault, WebViewConfiguration webViewConfiguration = const WebViewConfiguration(), - BrowserConfiguration browserConfiguration = const BrowserConfiguration(), String? webOnlyWindowName, }) async { if ((mode == LaunchMode.inAppWebView || @@ -36,8 +35,7 @@ Future launchUrlString( urlString, LaunchOptions( mode: convertLaunchMode(mode), - webViewConfiguration: convertWebViewConfiguration(webViewConfiguration), - browserConfiguration: convertBrowserConfiguration(browserConfiguration), + 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 4047e0f0e5f..d91558a673a 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 @@ -40,7 +40,6 @@ Future launchUrl( Uri url, { LaunchMode mode = LaunchMode.platformDefault, WebViewConfiguration webViewConfiguration = const WebViewConfiguration(), - BrowserConfiguration browserConfiguration = const BrowserConfiguration(), String? webOnlyWindowName, }) async { if ((mode == LaunchMode.inAppWebView || @@ -53,8 +52,7 @@ Future launchUrl( url.toString(), LaunchOptions( mode: convertLaunchMode(mode), - webViewConfiguration: convertWebViewConfiguration(webViewConfiguration), - browserConfiguration: convertBrowserConfiguration(browserConfiguration), + webViewConfiguration: convertConfiguration(webViewConfiguration), webOnlyWindowName: webOnlyWindowName, ), ); diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 91d23c0ed85..3a5c71ea9a3 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/packages/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.3.0 +version: 6.2.2 environment: sdk: ">=3.1.0 <4.0.0" @@ -28,13 +28,13 @@ flutter: dependencies: flutter: sdk: flutter - url_launcher_android: ^6.3.0 + url_launcher_android: ^6.2.0 url_launcher_ios: ^6.2.0 # Allow either the pure-native or Dart/native hybrid versions of the desktop # implementations, as both are compatible. url_launcher_linux: ^3.1.0 url_launcher_macos: ^3.1.0 - url_launcher_platform_interface: ^2.3.0 + url_launcher_platform_interface: ^2.2.0 url_launcher_web: ^2.2.0 url_launcher_windows: ^3.1.0 @@ -50,8 +50,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_android: {path: ../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher/test/link_test.dart b/packages/url_launcher/url_launcher/test/link_test.dart index 4d8fed20797..052ca2556e3 100644 --- a/packages/url_launcher/url_launcher/test/link_test.dart +++ b/packages/url_launcher/url_launcher/test/link_test.dart @@ -61,7 +61,6 @@ void main() { enableDomStorage: true, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); await followLink!(); @@ -93,7 +92,6 @@ void main() { enableDomStorage: true, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); await followLink!(); 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 f964d537107..fc0181d4a4e 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 @@ -17,7 +17,6 @@ class MockUrlLauncher extends Fake bool? enableJavaScript; bool? enableDomStorage; bool? universalLinksOnly; - bool? showTitle; Map? headers; String? webOnlyWindowName; @@ -42,7 +41,6 @@ class MockUrlLauncher extends Fake required bool universalLinksOnly, required Map headers, required String? webOnlyWindowName, - required bool showTitle, }) { this.url = url; this.launchMode = launchMode; @@ -53,7 +51,6 @@ class MockUrlLauncher extends Fake this.universalLinksOnly = universalLinksOnly; this.headers = headers; this.webOnlyWindowName = webOnlyWindowName; - this.showTitle = showTitle; } // ignore: use_setters_to_change_properties @@ -90,7 +87,6 @@ class MockUrlLauncher extends Fake expect(universalLinksOnly, this.universalLinksOnly); expect(headers, this.headers); expect(webOnlyWindowName, this.webOnlyWindowName); - expect(webOnlyWindowName, this.webOnlyWindowName); launchCalled = true; return response!; } @@ -102,7 +98,6 @@ class MockUrlLauncher extends Fake expect(options.webViewConfiguration.enableJavaScript, enableJavaScript); expect(options.webViewConfiguration.enableDomStorage, enableDomStorage); expect(options.webViewConfiguration.headers, headers); - expect(options.browserConfiguration.showTitle, showTitle); expect(options.webOnlyWindowName, webOnlyWindowName); launchCalled = true; return response!; diff --git a/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart b/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart index 9b98bb7a694..14f0b57828e 100644 --- a/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart +++ b/packages/url_launcher/url_launcher/test/src/legacy_api_test.dart @@ -53,7 +53,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/'), isTrue); @@ -70,7 +69,6 @@ void main() { universalLinksOnly: false, headers: {'key': 'value'}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -92,7 +90,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/', forceSafariVC: true), isTrue); @@ -109,7 +106,6 @@ void main() { universalLinksOnly: true, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -129,7 +125,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/', forceWebView: true), isTrue); @@ -146,7 +141,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -166,7 +160,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -186,7 +179,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launch('http://flutter.dev/', forceSafariVC: false), isTrue); @@ -208,7 +200,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launch('mailto:gmail-noreply@google.com?subject=Hello'), @@ -240,7 +231,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); @@ -273,7 +263,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); @@ -307,7 +296,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( 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 0cd0f9b2eb5..64065ff99f9 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 @@ -49,7 +49,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -66,7 +65,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -83,7 +81,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -100,7 +97,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); @@ -117,7 +113,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString, mode: LaunchMode.inAppWebView), @@ -135,7 +130,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -144,50 +138,6 @@ void main() { isTrue); }); - test('in-app browser', () async { - const String urlString = 'https://flutter.dev'; - mock - ..setLaunchExpectations( - url: urlString, - launchMode: PreferredLaunchMode.inAppBrowserView, - enableJavaScript: true, - enableDomStorage: true, - universalLinksOnly: false, - headers: {}, - webOnlyWindowName: null, - showTitle: false, - ) - ..setResponse(true); - expect( - await launchUrlString(urlString, mode: LaunchMode.inAppBrowserView), - isTrue, - ); - }); - - test('in-app browser with title', () async { - const String urlString = 'https://flutter.dev'; - mock - ..setLaunchExpectations( - url: urlString, - launchMode: PreferredLaunchMode.inAppBrowserView, - enableJavaScript: true, - enableDomStorage: true, - universalLinksOnly: false, - headers: {}, - webOnlyWindowName: null, - showTitle: true, - ) - ..setResponse(true); - expect( - await launchUrlString( - urlString, - mode: LaunchMode.inAppBrowserView, - browserConfiguration: const BrowserConfiguration(showTitle: true), - ), - isTrue, - ); - }); - test('external non-browser only', () async { const String urlString = 'https://flutter.dev'; mock @@ -199,7 +149,6 @@ void main() { universalLinksOnly: true, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -219,7 +168,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -241,7 +189,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -263,7 +210,6 @@ void main() { universalLinksOnly: false, headers: {'key': 'value'}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -293,7 +239,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(emailLaunchUrlString), isTrue); @@ -312,7 +257,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrlString(urlString), isTrue); 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 15796ea659a..0c5bfdcf247 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 @@ -54,7 +54,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -71,7 +70,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -88,7 +86,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -105,7 +102,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrl(url), isTrue); @@ -122,7 +118,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrl(url, mode: LaunchMode.inAppWebView), isTrue); @@ -139,7 +134,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -157,7 +151,6 @@ void main() { universalLinksOnly: true, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -176,7 +169,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -187,29 +179,6 @@ void main() { isTrue); }); - test('in-app browser view with show title', () async { - final Uri url = Uri.parse('https://flutter.dev'); - mock - ..setLaunchExpectations( - url: url.toString(), - launchMode: PreferredLaunchMode.inAppBrowserView, - enableJavaScript: true, - enableDomStorage: true, - universalLinksOnly: false, - headers: {}, - webOnlyWindowName: null, - showTitle: true, - ) - ..setResponse(true); - expect( - await launchUrl( - url, - mode: LaunchMode.inAppBrowserView, - browserConfiguration: const BrowserConfiguration(showTitle: true), - ), - isTrue); - }); - test('in-app webview without DOM storage', () async { final Uri url = Uri.parse('https://flutter.dev'); mock @@ -221,7 +190,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -243,7 +211,6 @@ void main() { universalLinksOnly: false, headers: {'key': 'value'}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect( @@ -276,7 +243,6 @@ void main() { universalLinksOnly: false, headers: {}, webOnlyWindowName: null, - showTitle: false, ) ..setResponse(true); expect(await launchUrl(emailLaunchUrl), isTrue); diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 2970933b2a2..fca9d52ae9a 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,10 +1,7 @@ -## 2.3.0 +## NEXT -* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController. -* Adds `showTitle` parameter to `InAppBrowserConfiguration` in order to control web-page title visibility. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. - ## 2.2.0 * Adds a new `inAppBrowserView` launch mode, to distinguish in-app browser diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart index 9e3b3ad1a3e..610df29f709 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/src/types.dart @@ -50,18 +50,6 @@ class InAppWebViewConfiguration { final Map headers; } -/// Additional configuration options for [PreferredLaunchMode.inAppBrowserView]. -@immutable -class InAppBrowserConfiguration { - /// Creates a new InAppBrowserConfiguration with given settings. - const InAppBrowserConfiguration({this.showTitle = false}); - - /// Whether or not to show the webpage title. - /// - /// May not be supported on all platforms. - final bool showTitle; -} - /// Options for [launchUrl]. @immutable class LaunchOptions { @@ -69,7 +57,6 @@ class LaunchOptions { const LaunchOptions({ this.mode = PreferredLaunchMode.platformDefault, this.webViewConfiguration = const InAppWebViewConfiguration(), - this.browserConfiguration = const InAppBrowserConfiguration(), this.webOnlyWindowName, }); @@ -79,9 +66,6 @@ class LaunchOptions { /// Configuration for the web view in [PreferredLaunchMode.inAppWebView] mode. final InAppWebViewConfiguration webViewConfiguration; - /// Configuration for the browser view in [PreferredLaunchMode.inAppBrowserView] mode. - final InAppBrowserConfiguration browserConfiguration; - /// A web-platform-specific option to set the link target. /// /// Default behaviour when unset should be to open the url in a new tab. diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index c490e789502..c90efd867e8 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.3.0 +version: 2.2.0 environment: sdk: ">=3.0.0 <4.0.0" From 193c076035fb79f3d308d7df3046c3f9f7e8a38b Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Thu, 4 Jan 2024 14:24:50 +0500 Subject: [PATCH 25/28] Add backticks to SFSafariViewController in platform interface changelog --- .../url_launcher/url_launcher_platform_interface/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 2970933b2a2..59dd7f121dd 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## 2.3.0 -* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController. +* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or `SFSafariViewController`. * Adds `showTitle` parameter to `InAppBrowserConfiguration` in order to control web-page title visibility. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. From 1ad83a2225219d08ac04e86d6baa528539f2a43f Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Thu, 4 Jan 2024 14:29:45 +0500 Subject: [PATCH 26/28] More merging --- packages/url_launcher/url_launcher_android/CHANGELOG.md | 4 ++++ .../url_launcher/url_launcher_platform_interface/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md index a3e6435491e..c01cd5ed2ef 100644 --- a/packages/url_launcher/url_launcher_android/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.3.0 +* Implements taking in `BrowserConfiguration` parameter. +* Implements `showTitle` functionality for Android Custom Tabs. + ## 6.2.1 * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 117f0176575..af7096206be 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.0 +* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or `SFSafariViewController`. +* Adds `showTitle` parameter to `InAppBrowserConfiguration` in order to control web-page title visibility. + ## 2.2.1 * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. From fa2e62ed6c2a6e02a2f88ab865c7655e4d37be6a Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Thu, 25 Jan 2024 17:21:05 +0500 Subject: [PATCH 27/28] Reset platform interface changes --- .../url_launcher_platform_interface/CHANGELOG.md | 9 ++++----- .../url_launcher_platform_interface/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 1ef97354560..7692e2be725 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,12 +1,11 @@ -## 2.4.0 - -* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or `SFSafariViewController`. -* Adds `showTitle` parameter to `InAppBrowserConfiguration` in order to control web-page title visibility. - ## 2.3.1 * Updates minimum required plugin_platform_interface version to 2.1.7. +## 2.3.0 +* Adds `InAppBrowserConfiguration` parameter to `LaunchOptions`, to configure in-app browser views, such as Android Custom Tabs or `SFSafariViewController`. +* Adds `showTitle` parameter to `InAppBrowserConfiguration` in order to control web-page title visibility. + ## 2.2.1 * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index 35d50347e1b..0fe27cacb40 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.4.0 +version: 2.3.1 environment: sdk: ">=3.0.0 <4.0.0" From caac8970954af723faa6bbcc210fd07f2653bfae Mon Sep 17 00:00:00 2001 From: Alex Usmanov Date: Fri, 2 Feb 2024 09:55:40 +0500 Subject: [PATCH 28/28] Fix --- packages/url_launcher/url_launcher_android/CHANGELOG.md | 2 +- .../url_launcher/url_launcher_android/example/pubspec.yaml | 7 +------ .../url_launcher_android/pigeons/messages.dart | 2 -- packages/url_launcher/url_launcher_android/pubspec.yaml | 7 +------ 4 files changed, 3 insertions(+), 15 deletions(-) diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md index ea7aa158d6d..67b01033497 100644 --- a/packages/url_launcher/url_launcher_android/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md @@ -1,6 +1,6 @@ ## 6.3.0 -* Implements taking in `BrowserConfiguration` parameter. +* Adds support for `BrowserConfiguration`. * Implements `showTitle` functionality for Android Custom Tabs. * Updates compileSdk version to 34. diff --git a/packages/url_launcher/url_launcher_android/example/pubspec.yaml b/packages/url_launcher/url_launcher_android/example/pubspec.yaml index 3b135aabd40..0d99e391616 100644 --- a/packages/url_launcher/url_launcher_android/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/example/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - url_launcher_platform_interface: ^2.2.0 + url_launcher_platform_interface: ^2.3.1 dev_dependencies: flutter_test: @@ -28,8 +28,3 @@ dev_dependencies: flutter: uses-material-design: true - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_android: {path: ../../../url_launcher/url_launcher_android}, url_launcher_platform_interface: {path: ../../../url_launcher/url_launcher_platform_interface}} diff --git a/packages/url_launcher/url_launcher_android/pigeons/messages.dart b/packages/url_launcher/url_launcher_android/pigeons/messages.dart index 1cfdd403044..6f39272c4f7 100644 --- a/packages/url_launcher/url_launcher_android/pigeons/messages.dart +++ b/packages/url_launcher/url_launcher_android/pigeons/messages.dart @@ -32,8 +32,6 @@ class BrowserOptions { BrowserOptions({required this.showTitle}); /// Whether or not to show the webpage title. - /// - /// May not be supported on all platforms. final bool showTitle; } diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml index 857145d5c44..111318fa681 100644 --- a/packages/url_launcher/url_launcher_android/pubspec.yaml +++ b/packages/url_launcher/url_launcher_android/pubspec.yaml @@ -19,7 +19,7 @@ flutter: dependencies: flutter: sdk: flutter - url_launcher_platform_interface: ^2.2.0 + url_launcher_platform_interface: ^2.3.1 dev_dependencies: flutter_test: @@ -34,8 +34,3 @@ topics: - os-integration - url-launcher - urls - -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins -dependency_overrides: - {url_launcher_platform_interface: {path: ../../url_launcher/url_launcher_platform_interface}}