Skip to content

Commit 539a5f9

Browse files
authored
[url_launcher] Add support for setting show title on Chrome Custom Tabs (flutter#6097)
- Adds showTitle option to platform interface & app-facing api - Makes use of that parameter on android platform in order to set show title on Chrome Custom Tabs, when it is being used - Makes android implementation use both legacy & new api (instead of passthrough from new to legacy), in order to allow use of the aforementioned parameter - Adds a button to the example to test this parameter - Adds tests ![Screenshot_20231018-095928](https://github.com/flutter/packages/assets/40719830/2f32d83f-066b-4048-a439-04e2d63befde) (Notice title at the top of the page "CyLog Software - HTTP ...") flutter/flutter#136784
1 parent 24b0eb5 commit 539a5f9

File tree

12 files changed

+161
-7
lines changed

12 files changed

+161
-7
lines changed

packages/url_launcher/url_launcher/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
## NEXT
1+
## 6.3.0
22

3+
* Adds `BrowserConfiguration` parameter, to configure in-app browser views, such as Android Custom Tabs or SFSafariViewController.
4+
* Adds `showTitle` to `BrowserConfiguration`, to allow showing webpage titles in in-app browser views.
35
* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.
46

57
## 6.2.6

packages/url_launcher/url_launcher/example/lib/main.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ class _MyHomePageState extends State<MyHomePage> {
7474
}
7575
}
7676

77+
Future<void> _launchInAppWithBrowserOptions(Uri url) async {
78+
if (!await launchUrl(
79+
url,
80+
mode: LaunchMode.inAppBrowserView,
81+
browserConfiguration: const BrowserConfiguration(showTitle: true),
82+
)) {
83+
throw Exception('Could not launch $url');
84+
}
85+
}
86+
7787
Future<void> _launchAsInAppWebViewWithCustomHeaders(Uri url) async {
7888
if (!await launchUrl(
7989
url,
@@ -220,6 +230,13 @@ class _MyHomePageState extends State<MyHomePage> {
220230
child: const Text('Launch in app + close after 5 seconds'),
221231
),
222232
const Padding(padding: EdgeInsets.all(16.0)),
233+
ElevatedButton(
234+
onPressed: () => setState(() {
235+
_launched = _launchInAppWithBrowserOptions(toLaunch);
236+
}),
237+
child: const Text('Launch in app with title displayed'),
238+
),
239+
const Padding(padding: EdgeInsets.all(16.0)),
223240
Link(
224241
uri: Uri.parse(
225242
'https://pub.dev/documentation/url_launcher/latest/link/link-library.html'),

packages/url_launcher/url_launcher/lib/src/type_conversion.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,24 @@ import 'types.dart';
88

99
/// Converts an (app-facing) [WebViewConfiguration] to a (platform interface)
1010
/// [InAppWebViewConfiguration].
11-
InAppWebViewConfiguration convertConfiguration(WebViewConfiguration config) {
11+
InAppWebViewConfiguration convertWebViewConfiguration(
12+
WebViewConfiguration config) {
1213
return InAppWebViewConfiguration(
1314
enableJavaScript: config.enableJavaScript,
1415
enableDomStorage: config.enableDomStorage,
1516
headers: config.headers,
1617
);
1718
}
1819

20+
/// Converts an (app-facing) [BrowserConfiguration] to a (platform interface)
21+
/// [InAppBrowserConfiguration].
22+
InAppBrowserConfiguration convertBrowserConfiguration(
23+
BrowserConfiguration config) {
24+
return InAppBrowserConfiguration(
25+
showTitle: config.showTitle,
26+
);
27+
}
28+
1929
/// Converts an (app-facing) [LaunchMode] to a (platform interface)
2030
/// [PreferredLaunchMode].
2131
PreferredLaunchMode convertLaunchMode(LaunchMode mode) {

packages/url_launcher/url_launcher/lib/src/types.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,15 @@ class WebViewConfiguration {
5555
/// Not all browsers support this, so it is not guaranteed to be honored.
5656
final Map<String, String> headers;
5757
}
58+
59+
/// Additional configuration options for [LaunchMode.inAppBrowserView]
60+
@immutable
61+
class BrowserConfiguration {
62+
/// Creates a new InAppBrowserConfiguration with given settings.
63+
const BrowserConfiguration({this.showTitle = false});
64+
65+
/// Whether or not to show the webpage title.
66+
///
67+
/// May not be supported on all platforms.
68+
final bool showTitle;
69+
}

packages/url_launcher/url_launcher/lib/src/url_launcher_string.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Future<bool> launchUrlString(
2323
String urlString, {
2424
LaunchMode mode = LaunchMode.platformDefault,
2525
WebViewConfiguration webViewConfiguration = const WebViewConfiguration(),
26+
BrowserConfiguration browserConfiguration = const BrowserConfiguration(),
2627
String? webOnlyWindowName,
2728
}) async {
2829
if ((mode == LaunchMode.inAppWebView ||
@@ -35,7 +36,8 @@ Future<bool> launchUrlString(
3536
urlString,
3637
LaunchOptions(
3738
mode: convertLaunchMode(mode),
38-
webViewConfiguration: convertConfiguration(webViewConfiguration),
39+
webViewConfiguration: convertWebViewConfiguration(webViewConfiguration),
40+
browserConfiguration: convertBrowserConfiguration(browserConfiguration),
3941
webOnlyWindowName: webOnlyWindowName,
4042
),
4143
);

packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Future<bool> launchUrl(
4040
Uri url, {
4141
LaunchMode mode = LaunchMode.platformDefault,
4242
WebViewConfiguration webViewConfiguration = const WebViewConfiguration(),
43+
BrowserConfiguration browserConfiguration = const BrowserConfiguration(),
4344
String? webOnlyWindowName,
4445
}) async {
4546
if ((mode == LaunchMode.inAppWebView ||
@@ -52,7 +53,8 @@ Future<bool> launchUrl(
5253
url.toString(),
5354
LaunchOptions(
5455
mode: convertLaunchMode(mode),
55-
webViewConfiguration: convertConfiguration(webViewConfiguration),
56+
webViewConfiguration: convertWebViewConfiguration(webViewConfiguration),
57+
browserConfiguration: convertBrowserConfiguration(browserConfiguration),
5658
webOnlyWindowName: webOnlyWindowName,
5759
),
5860
);

packages/url_launcher/url_launcher/pubspec.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports
33
web, phone, SMS, and email schemes.
44
repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher
55
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
6-
version: 6.2.6
6+
version: 6.3.0
77

88
environment:
99
sdk: ">=3.2.0 <4.0.0"
@@ -28,13 +28,13 @@ flutter:
2828
dependencies:
2929
flutter:
3030
sdk: flutter
31-
url_launcher_android: ^6.2.0
31+
url_launcher_android: ^6.3.0
3232
url_launcher_ios: ^6.2.4
3333
# Allow either the pure-native or Dart/native hybrid versions of the desktop
3434
# implementations, as both are compatible.
3535
url_launcher_linux: ^3.1.0
3636
url_launcher_macos: ^3.1.0
37-
url_launcher_platform_interface: ^2.2.0
37+
url_launcher_platform_interface: ^2.3.0
3838
url_launcher_web: ^2.2.0
3939
url_launcher_windows: ^3.1.0
4040

packages/url_launcher/url_launcher/test/link_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void main() {
6161
enableDomStorage: true,
6262
headers: <String, String>{},
6363
webOnlyWindowName: null,
64+
showTitle: false,
6465
)
6566
..setResponse(true);
6667
await followLink!();
@@ -92,6 +93,7 @@ void main() {
9293
enableDomStorage: true,
9394
headers: <String, String>{},
9495
webOnlyWindowName: null,
96+
showTitle: false,
9597
)
9698
..setResponse(true);
9799
await followLink!();

packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class MockUrlLauncher extends Fake
1717
bool? enableJavaScript;
1818
bool? enableDomStorage;
1919
bool? universalLinksOnly;
20+
bool? showTitle;
2021
Map<String, String>? headers;
2122
String? webOnlyWindowName;
2223

@@ -41,6 +42,7 @@ class MockUrlLauncher extends Fake
4142
required bool universalLinksOnly,
4243
required Map<String, String> headers,
4344
required String? webOnlyWindowName,
45+
required bool showTitle,
4446
}) {
4547
this.url = url;
4648
this.launchMode = launchMode;
@@ -51,6 +53,7 @@ class MockUrlLauncher extends Fake
5153
this.universalLinksOnly = universalLinksOnly;
5254
this.headers = headers;
5355
this.webOnlyWindowName = webOnlyWindowName;
56+
this.showTitle = showTitle;
5457
}
5558

5659
// ignore: use_setters_to_change_properties
@@ -87,6 +90,7 @@ class MockUrlLauncher extends Fake
8790
expect(universalLinksOnly, this.universalLinksOnly);
8891
expect(headers, this.headers);
8992
expect(webOnlyWindowName, this.webOnlyWindowName);
93+
expect(webOnlyWindowName, this.webOnlyWindowName);
9094
launchCalled = true;
9195
return response!;
9296
}
@@ -98,6 +102,7 @@ class MockUrlLauncher extends Fake
98102
expect(options.webViewConfiguration.enableJavaScript, enableJavaScript);
99103
expect(options.webViewConfiguration.enableDomStorage, enableDomStorage);
100104
expect(options.webViewConfiguration.headers, headers);
105+
expect(options.browserConfiguration.showTitle, showTitle);
101106
expect(options.webOnlyWindowName, webOnlyWindowName);
102107
launchCalled = true;
103108
return response!;

packages/url_launcher/url_launcher/test/src/legacy_api_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void main() {
5353
universalLinksOnly: false,
5454
headers: <String, String>{},
5555
webOnlyWindowName: null,
56+
showTitle: false,
5657
)
5758
..setResponse(true);
5859
expect(await launch('http://flutter.dev/'), isTrue);
@@ -69,6 +70,7 @@ void main() {
6970
universalLinksOnly: false,
7071
headers: <String, String>{'key': 'value'},
7172
webOnlyWindowName: null,
73+
showTitle: false,
7274
)
7375
..setResponse(true);
7476
expect(
@@ -90,6 +92,7 @@ void main() {
9092
universalLinksOnly: false,
9193
headers: <String, String>{},
9294
webOnlyWindowName: null,
95+
showTitle: false,
9396
)
9497
..setResponse(true);
9598
expect(await launch('http://flutter.dev/', forceSafariVC: true), isTrue);
@@ -106,6 +109,7 @@ void main() {
106109
universalLinksOnly: true,
107110
headers: <String, String>{},
108111
webOnlyWindowName: null,
112+
showTitle: false,
109113
)
110114
..setResponse(true);
111115
expect(
@@ -125,6 +129,7 @@ void main() {
125129
universalLinksOnly: false,
126130
headers: <String, String>{},
127131
webOnlyWindowName: null,
132+
showTitle: false,
128133
)
129134
..setResponse(true);
130135
expect(await launch('http://flutter.dev/', forceWebView: true), isTrue);
@@ -141,6 +146,7 @@ void main() {
141146
universalLinksOnly: false,
142147
headers: <String, String>{},
143148
webOnlyWindowName: null,
149+
showTitle: false,
144150
)
145151
..setResponse(true);
146152
expect(
@@ -160,6 +166,7 @@ void main() {
160166
universalLinksOnly: false,
161167
headers: <String, String>{},
162168
webOnlyWindowName: null,
169+
showTitle: false,
163170
)
164171
..setResponse(true);
165172
expect(
@@ -179,6 +186,7 @@ void main() {
179186
universalLinksOnly: false,
180187
headers: <String, String>{},
181188
webOnlyWindowName: null,
189+
showTitle: false,
182190
)
183191
..setResponse(true);
184192
expect(await launch('http://flutter.dev/', forceSafariVC: false), isTrue);
@@ -200,6 +208,7 @@ void main() {
200208
universalLinksOnly: false,
201209
headers: <String, String>{},
202210
webOnlyWindowName: null,
211+
showTitle: false,
203212
)
204213
..setResponse(true);
205214
expect(await launch('mailto:gmail-noreply@google.com?subject=Hello'),
@@ -231,6 +240,7 @@ void main() {
231240
universalLinksOnly: false,
232241
headers: <String, String>{},
233242
webOnlyWindowName: null,
243+
showTitle: false,
234244
)
235245
..setResponse(true);
236246

@@ -263,6 +273,7 @@ void main() {
263273
universalLinksOnly: false,
264274
headers: <String, String>{},
265275
webOnlyWindowName: null,
276+
showTitle: false,
266277
)
267278
..setResponse(true);
268279

@@ -296,6 +307,7 @@ void main() {
296307
universalLinksOnly: false,
297308
headers: <String, String>{},
298309
webOnlyWindowName: null,
310+
showTitle: false,
299311
)
300312
..setResponse(true);
301313
expect(

0 commit comments

Comments
 (0)