Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/url_launcher/url_launcher_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 6.2.0

* Adds support for `inAppBrowserView` as a separate launch mode option from
`inAppWebView` mode. `inAppBrowserView` is the preferred in-app mode for most uses,
but does not support `closeInAppWebView`.
* Implements `supportsMode` and `supportsCloseForMode`.

## 6.1.1

* Updates annotations lib to 1.7.0.
Expand Down
Original file line number Diff line number Diff line change
@@ -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.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon

package io.flutter.plugins.urllauncher;
Expand Down Expand Up @@ -190,9 +190,15 @@ public interface UrlLauncherApi {
/** Opens the URL externally, returning true if successful. */
@NonNull
Boolean launchUrl(@NonNull String url, @NonNull Map<String, String> 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.
*/
@NonNull
Boolean openUrlInWebView(@NonNull String url, @NonNull WebViewOptions options);
Boolean openUrlInApp(
@NonNull String url, @NonNull Boolean allowCustomTab, @NonNull WebViewOptions options);

@NonNull
Boolean supportsCustomTabs();
/** Closes the view opened by [openUrlInSafariViewController]. */
void closeWebView();

Expand All @@ -205,7 +211,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> 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) -> {
Expand All @@ -228,7 +236,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> 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) -> {
Expand All @@ -252,16 +262,42 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.UrlLauncherApi.openUrlInWebView", getCodec());
binaryMessenger,
"dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp",
getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
String urlArg = (String) args.get(0);
WebViewOptions optionsArg = (WebViewOptions) args.get(1);
Boolean allowCustomTabArg = (Boolean) args.get(1);
WebViewOptions optionsArg = (WebViewOptions) args.get(2);
try {
Boolean output = api.openUrlInApp(urlArg, allowCustomTabArg, optionsArg);
wrapped.add(0, output);
} catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs",
getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
try {
Boolean output = api.openUrlInWebView(urlArg, optionsArg);
Boolean output = api.supportsCustomTabs();
wrapped.add(0, output);
} catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
Expand All @@ -276,7 +312,9 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> 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) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.browser.customtabs.CustomTabsClient;
import androidx.browser.customtabs.CustomTabsIntent;
import io.flutter.plugins.urllauncher.Messages.UrlLauncherApi;
import io.flutter.plugins.urllauncher.Messages.WebViewOptions;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;

Expand Down Expand Up @@ -95,14 +97,16 @@ void setActivity(@Nullable Activity activity) {
}

@Override
public @NonNull Boolean openUrlInWebView(@NonNull String url, @NonNull WebViewOptions options) {
public @NonNull Boolean openUrlInApp(
@NonNull String url, @NonNull Boolean allowCustomTab, @NonNull WebViewOptions options) {
ensureActivity();
assert activity != null;

Bundle headersBundle = extractBundle(options.getHeaders());

// Try to launch using Custom Tabs if they have the necessary functionality.
if (!containsRestrictedHeader(options.getHeaders())) {
// Try to launch using Custom Tabs if they have the necessary functionality, unless the caller
// specifically requested a web view.
if (allowCustomTab && !containsRestrictedHeader(options.getHeaders())) {
Uri uri = Uri.parse(url);
if (openCustomTab(activity, uri, headersBundle)) {
return true;
Expand Down Expand Up @@ -131,6 +135,11 @@ public void closeWebView() {
applicationContext.sendBroadcast(new Intent(WebViewActivity.ACTION_CLOSE));
}

@Override
public @NonNull Boolean supportsCustomTabs() {
return CustomTabsClient.getPackageName(applicationContext, Collections.emptyList()) != null;
}

private static boolean openCustomTab(
@NonNull Context context, @NonNull Uri uri, @NonNull Bundle headersBundle) {
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public void launch_returnsTrue() {
}

@Test
public void openWebView_opensUrl_inWebView() {
public void openUrlInApp_opensUrlInWebViewIfNecessary() {
Activity activity = mock(Activity.class);
UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext());
api.setActivity(activity);
Expand All @@ -141,8 +141,9 @@ public void openWebView_opensUrl_inWebView() {
headers.put("key", "value");

boolean result =
api.openUrlInWebView(
api.openUrlInApp(
url,
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(enableJavaScript)
.setEnableDomStorage(enableDomStorage)
Expand All @@ -162,15 +163,39 @@ public void openWebView_opensUrl_inWebView() {
}

@Test
public void openWebView_opensUrl_inCustomTabs() {
public void openWebView_opensUrlInWebViewIfRequested() {
Activity activity = mock(Activity.class);
UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext());
api.setActivity(activity);
String url = "https://flutter.dev";

boolean result =
api.openUrlInWebView(
api.openUrlInApp(
url,
false,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
.setHeaders(new HashMap<>())
.build());

final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(activity).startActivity(intentCaptor.capture());
assertTrue(result);
assertEquals(url, intentCaptor.getValue().getExtras().getString(WebViewActivity.URL_EXTRA));
}

@Test
public void openWebView_opensUrlInCustomTabs() {
Activity activity = mock(Activity.class);
UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext());
api.setActivity(activity);
String url = "https://flutter.dev";

boolean result =
api.openUrlInApp(
url,
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
Expand All @@ -185,7 +210,7 @@ public void openWebView_opensUrl_inCustomTabs() {
}

@Test
public void openWebView_opensUrl_inCustomTabs_withCORSAllowedHeader() {
public void openWebView_opensUrlInCustomTabsWithCORSAllowedHeader() {
Activity activity = mock(Activity.class);
UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext());
api.setActivity(activity);
Expand All @@ -195,8 +220,9 @@ public void openWebView_opensUrl_inCustomTabs_withCORSAllowedHeader() {
headers.put(headerKey, "text/plain");

boolean result =
api.openUrlInWebView(
api.openUrlInApp(
url,
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
Expand All @@ -214,7 +240,7 @@ public void openWebView_opensUrl_inCustomTabs_withCORSAllowedHeader() {
}

@Test
public void openWebView_fallsbackTo_inWebView() {
public void openWebView_fallsBackToWebViewIfCustomTabFails() {
Activity activity = mock(Activity.class);
UrlLauncher api = new UrlLauncher(ApplicationProvider.getApplicationContext());
api.setActivity(activity);
Expand All @@ -224,8 +250,9 @@ public void openWebView_fallsbackTo_inWebView() {
.startActivity(any(), isNull()); // for custom tabs intent

boolean result =
api.openUrlInWebView(
api.openUrlInApp(
url,
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
Expand All @@ -251,8 +278,9 @@ public void openWebView_handlesEnableJavaScript() {
HashMap<String, String> headers = new HashMap<>();
headers.put("key", "value");

api.openUrlInWebView(
api.openUrlInApp(
"https://flutter.dev",
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(enableJavaScript)
.setEnableDomStorage(false)
Expand All @@ -277,8 +305,9 @@ public void openWebView_handlesHeaders() {
headers.put(key1, "value");
headers.put(key2, "value2");

api.openUrlInWebView(
api.openUrlInApp(
"https://flutter.dev",
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
Expand All @@ -303,8 +332,9 @@ public void openWebView_handlesEnableDomStorage() {
HashMap<String, String> headers = new HashMap<>();
headers.put("key", "value");

api.openUrlInWebView(
api.openUrlInApp(
"https://flutter.dev",
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(enableDomStorage)
Expand All @@ -327,8 +357,9 @@ public void openWebView_throwsForNoCurrentActivity() {
assertThrows(
Messages.FlutterError.class,
() ->
api.openUrlInWebView(
api.openUrlInApp(
"https://flutter.dev",
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
Expand All @@ -350,8 +381,9 @@ public void openWebView_returnsFalse() {
.startActivity(any()); // for webview intent

boolean result =
api.openUrlInWebView(
api.openUrlInApp(
"https://flutter.dev",
true,
new Messages.WebViewOptions.Builder()
.setEnableJavaScript(false)
.setEnableDomStorage(false)
Expand Down
Loading