Skip to content

Commit d5053b5

Browse files
[url_launcher] Add an inAppBrowserView mode (flutter#5205)
Platform interface portion of flutter/packages#5155. Adds the `inAppBrowserView` launch mode, as well as the `supportsMode` and `supportsCloseForMode` support query APIs.
1 parent 30b1094 commit d5053b5

File tree

5 files changed

+91
-3
lines changed

5 files changed

+91
-3
lines changed

packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 2.2.0
2+
3+
* Adds a new `inAppBrowserView` launch mode, to distinguish in-app browser
4+
views (such as Android Custom Tabs or SFSafariViewController) from simple
5+
web views.
6+
* Adds `supportsMode` and `supportsCloseForMode` to query platform support for
7+
launching and closing with various modes.
8+
19
## 2.1.5
210

311
* Updates documentation to mention support for Android Custom Tabs.

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ enum PreferredLaunchMode {
1313
/// implementation.
1414
platformDefault,
1515

16-
/// Loads the URL in an in-app web view (e.g., Android Custom Tabs, Safari View Controller).
16+
/// Loads the URL in an in-app web view (e.g., Android WebView).
1717
inAppWebView,
1818

19+
/// Loads the URL in an in-app browser view (e.g., Android Custom Tabs,
20+
/// SFSafariViewController).
21+
inAppBrowserView,
22+
1923
/// Passes the URL to the OS to be handled by another application.
2024
externalApplication,
2125

packages/url_launcher/url_launcher_platform_interface/lib/src/url_launcher_platform.dart

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
99
import '../link.dart';
1010
import '../method_channel_url_launcher.dart';
1111
import '../url_launcher_platform_interface.dart';
12+
import 'types.dart';
1213

1314
/// The interface that implementations of url_launcher must implement.
1415
///
@@ -72,6 +73,7 @@ abstract class UrlLauncherPlatform extends PlatformInterface {
7273
Future<bool> launchUrl(String url, LaunchOptions options) {
7374
final bool isWebURL = url.startsWith('http:') || url.startsWith('https:');
7475
final bool useWebView = options.mode == PreferredLaunchMode.inAppWebView ||
76+
options.mode == PreferredLaunchMode.inAppBrowserView ||
7577
(isWebURL && options.mode == PreferredLaunchMode.platformDefault);
7678

7779
return launch(
@@ -87,8 +89,31 @@ abstract class UrlLauncherPlatform extends PlatformInterface {
8789
);
8890
}
8991

90-
/// Closes the WebView, if one was opened earlier by [launch].
92+
/// Closes the web view, if one was opened earlier by [launchUrl].
93+
///
94+
/// This will only work if the launch mode (the actual launch mode used,
95+
/// not the requested launch mode, which may not match if [supportsMode] is
96+
/// false for the requested mode) was one for which [supportsCloseForMode]
97+
/// returns true.
9198
Future<void> closeWebView() {
9299
throw UnimplementedError('closeWebView() has not been implemented.');
93100
}
101+
102+
/// Returns true if the given launch mode is supported by the current
103+
/// implementation.
104+
///
105+
/// Clients are not required to query this, as implementations are strongly
106+
/// encouraged to automatically fall back to other modes if a launch is
107+
/// requested using an unsupported mode (matching historical behavior of the
108+
/// plugin, and thus maximizing compatibility with existing code).
109+
Future<bool> supportsMode(PreferredLaunchMode mode) {
110+
return Future<bool>.value(mode == PreferredLaunchMode.platformDefault);
111+
}
112+
113+
/// Returns true if the given launch mode can be closed with [closeWebView].
114+
Future<bool> supportsCloseForMode(PreferredLaunchMode mode) {
115+
// This is the historical documented behavior, so default to that for
116+
// compatibility.
117+
return Future<bool>.value(mode == PreferredLaunchMode.inAppWebView);
118+
}
94119
}

packages/url_launcher/url_launcher_platform_interface/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
55
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
66
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
7-
version: 2.1.5
7+
version: 2.2.0
88

99
environment:
1010
sdk: ">=2.19.0 <4.0.0"

packages/url_launcher/url_launcher_platform_interface/test/url_launcher_platform_test.dart

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,55 @@ void main() {
118118
expect(launcher.headers['foo'], 'bar');
119119
expect(launcher.webOnlyWindowName, 'a_name');
120120
});
121+
122+
test('supportsMode defaults to true for platform default', () async {
123+
final UrlLauncherPlatform launcher = CapturingUrlLauncher();
124+
125+
expect(
126+
await launcher.supportsMode(PreferredLaunchMode.platformDefault), true);
127+
});
128+
129+
test('supportsMode defaults to false for all specific values', () async {
130+
final UrlLauncherPlatform launcher = CapturingUrlLauncher();
131+
132+
expect(await launcher.supportsMode(PreferredLaunchMode.externalApplication),
133+
false);
134+
expect(
135+
await launcher
136+
.supportsMode(PreferredLaunchMode.externalNonBrowserApplication),
137+
false);
138+
expect(await launcher.supportsMode(PreferredLaunchMode.inAppBrowserView),
139+
false);
140+
expect(
141+
await launcher.supportsMode(PreferredLaunchMode.inAppWebView), false);
142+
});
143+
144+
test('supportsCloseForMode defaults to true for in-app web views', () async {
145+
final UrlLauncherPlatform launcher = CapturingUrlLauncher();
146+
147+
expect(
148+
await launcher.supportsCloseForMode(PreferredLaunchMode.inAppWebView),
149+
true);
150+
});
151+
152+
test('supportsCloseForMode defaults to false for all other values', () async {
153+
final UrlLauncherPlatform launcher = CapturingUrlLauncher();
154+
155+
expect(
156+
await launcher
157+
.supportsCloseForMode(PreferredLaunchMode.externalApplication),
158+
false);
159+
expect(
160+
await launcher.supportsCloseForMode(
161+
PreferredLaunchMode.externalNonBrowserApplication),
162+
false);
163+
expect(
164+
await launcher
165+
.supportsCloseForMode(PreferredLaunchMode.inAppBrowserView),
166+
false);
167+
expect(
168+
await launcher
169+
.supportsCloseForMode(PreferredLaunchMode.platformDefault),
170+
false);
171+
});
121172
}

0 commit comments

Comments
 (0)