Skip to content

Commit

Permalink
[url_launcher] Add an inAppBrowserView mode (#5205)
Browse files Browse the repository at this point in the history
Platform interface portion of #5155. Adds the `inAppBrowserView` launch mode, as well as the `supportsMode` and `supportsCloseForMode` support query APIs.
  • Loading branch information
stuartmorgan authored Oct 23, 2023
1 parent 30b1094 commit d5053b5
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 2.2.0

* Adds a new `inAppBrowserView` launch mode, to distinguish in-app browser
views (such as Android Custom Tabs or SFSafariViewController) from simple
web views.
* Adds `supportsMode` and `supportsCloseForMode` to query platform support for
launching and closing with various modes.

## 2.1.5

* Updates documentation to mention support for Android Custom Tabs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ enum PreferredLaunchMode {
/// implementation.
platformDefault,

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

/// Loads the URL in an in-app browser view (e.g., Android Custom Tabs,
/// SFSafariViewController).
inAppBrowserView,

/// Passes the URL to the OS to be handled by another application.
externalApplication,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import '../link.dart';
import '../method_channel_url_launcher.dart';
import '../url_launcher_platform_interface.dart';
import 'types.dart';

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

return launch(
Expand All @@ -87,8 +89,31 @@ abstract class UrlLauncherPlatform extends PlatformInterface {
);
}

/// Closes the WebView, if one was opened earlier by [launch].
/// Closes the web view, if one was opened earlier by [launchUrl].
///
/// This will only work if the launch mode (the actual launch mode used,
/// not the requested launch mode, which may not match if [supportsMode] is
/// false for the requested mode) was one for which [supportsCloseForMode]
/// returns true.
Future<void> closeWebView() {
throw UnimplementedError('closeWebView() has not been implemented.');
}

/// Returns true if the given launch mode is supported by the current
/// implementation.
///
/// Clients are not required to query this, as implementations are strongly
/// encouraged to automatically fall back to other modes if a launch is
/// requested using an unsupported mode (matching historical behavior of the
/// plugin, and thus maximizing compatibility with existing code).
Future<bool> supportsMode(PreferredLaunchMode mode) {
return Future<bool>.value(mode == PreferredLaunchMode.platformDefault);
}

/// Returns true if the given launch mode can be closed with [closeWebView].
Future<bool> supportsCloseForMode(PreferredLaunchMode mode) {
// This is the historical documented behavior, so default to that for
// compatibility.
return Future<bool>.value(mode == PreferredLaunchMode.inAppWebView);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.1.5
version: 2.2.0

environment:
sdk: ">=2.19.0 <4.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,55 @@ void main() {
expect(launcher.headers['foo'], 'bar');
expect(launcher.webOnlyWindowName, 'a_name');
});

test('supportsMode defaults to true for platform default', () async {
final UrlLauncherPlatform launcher = CapturingUrlLauncher();

expect(
await launcher.supportsMode(PreferredLaunchMode.platformDefault), true);
});

test('supportsMode defaults to false for all specific values', () async {
final UrlLauncherPlatform launcher = CapturingUrlLauncher();

expect(await launcher.supportsMode(PreferredLaunchMode.externalApplication),
false);
expect(
await launcher
.supportsMode(PreferredLaunchMode.externalNonBrowserApplication),
false);
expect(await launcher.supportsMode(PreferredLaunchMode.inAppBrowserView),
false);
expect(
await launcher.supportsMode(PreferredLaunchMode.inAppWebView), false);
});

test('supportsCloseForMode defaults to true for in-app web views', () async {
final UrlLauncherPlatform launcher = CapturingUrlLauncher();

expect(
await launcher.supportsCloseForMode(PreferredLaunchMode.inAppWebView),
true);
});

test('supportsCloseForMode defaults to false for all other values', () async {
final UrlLauncherPlatform launcher = CapturingUrlLauncher();

expect(
await launcher
.supportsCloseForMode(PreferredLaunchMode.externalApplication),
false);
expect(
await launcher.supportsCloseForMode(
PreferredLaunchMode.externalNonBrowserApplication),
false);
expect(
await launcher
.supportsCloseForMode(PreferredLaunchMode.inAppBrowserView),
false);
expect(
await launcher
.supportsCloseForMode(PreferredLaunchMode.platformDefault),
false);
});
}

0 comments on commit d5053b5

Please sign in to comment.