Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e41ea0e
add android show title customization functionality
Alex-Usmanov Oct 17, 2023
fb67692
Pass the parameter
Alex-Usmanov Oct 17, 2023
21cd06f
Dependency overrides
Alex-Usmanov Oct 17, 2023
276c08b
Add tests for native side
Alex-Usmanov Oct 17, 2023
1897451
Cover dart side with tests
Alex-Usmanov Oct 17, 2023
5cd1709
Format
Alex-Usmanov Oct 17, 2023
bc943c5
Reduce code repetition
Alex-Usmanov Oct 17, 2023
d6306ba
Revert todo change
Alex-Usmanov Oct 18, 2023
f59475b
Wrap browser customization values in another configuration object
Alex-Usmanov Oct 20, 2023
157343b
Remove deps overrides
Alex-Usmanov Oct 20, 2023
ae20b08
Revert more deps overrides
Alex-Usmanov Oct 20, 2023
214b0a9
Revert web as well
Alex-Usmanov Oct 20, 2023
cd7dfc9
Revert go_router
Alex-Usmanov Oct 20, 2023
d205c7c
Merge branch 'main' into main
Alex-Usmanov Oct 20, 2023
5eef662
Merge remote-tracking branch 'upstream/main'
Alex-Usmanov Oct 27, 2023
c86ff6e
Format files
Alex-Usmanov Oct 27, 2023
92b2197
Fix tests
Alex-Usmanov Oct 27, 2023
425617e
Add browseroptions to launchUrlString & add more tests
Alex-Usmanov Oct 30, 2023
ece2b78
Fix docstrings
Alex-Usmanov Dec 7, 2023
3ddd644
Revert test format change
Alex-Usmanov Dec 7, 2023
cd361d0
Fix tests
Alex-Usmanov Dec 8, 2023
f0017b7
Version bumps and changelogs
Alex-Usmanov Dec 8, 2023
6105671
Merge remote-tracking branch 'upstream/main'
Alex-Usmanov Dec 8, 2023
a50be0f
Return path-based dependencies
Alex-Usmanov Dec 8, 2023
ef9c154
Add licences
Alex-Usmanov Dec 11, 2023
f4b08cb
Merge remote-tracking branch 'upstream/main'
Alex-Usmanov Dec 11, 2023
80d439b
Fix documentation & changelog
Alex-Usmanov Dec 26, 2023
992d38e
Merge remote-tracking branch 'upstream/main'
Alex-Usmanov Dec 26, 2023
fd6f0f2
Revert everything except for android implementation
Alex-Usmanov Dec 26, 2023
193c076
Add backticks to SFSafariViewController in platform interface changelog
Alex-Usmanov Jan 4, 2024
b399c9b
Merge remote-tracking branch 'upstream/main'
Alex-Usmanov Jan 4, 2024
1ad83a2
More merging
Alex-Usmanov Jan 4, 2024
9737ff0
Merge branch 'main' into show-title-implementations
Alex-Usmanov Jan 4, 2024
adf977f
Merge remote-tracking branch 'upstream/main' into show-title-implemen…
Alex-Usmanov Jan 25, 2024
fa2e62e
Reset platform interface changes
Alex-Usmanov Jan 25, 2024
caac897
Fix
Alex-Usmanov Feb 2, 2024
e89b7c2
Merge remote-tracking branch 'upstream/main' into show-title-implemen…
Alex-Usmanov Feb 2, 2024
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
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'upstream/main'
  • Loading branch information
Alex-Usmanov committed Oct 27, 2023
commit 5eef6623f912700ec50f69a335ef6e82ff8f6f75
6 changes: 3 additions & 3 deletions packages/url_launcher/url_launcher/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ class _MyHomePageState extends State<MyHomePage> {
}
}

Future<void> _launchInAppWithShowTitle(Uri url) async {
Future<void> _launchInAppWithBrowserOptions(Uri url) async {
if (!await launchUrl(
url,
mode: LaunchMode.inAppWebView,
mode: LaunchMode.inAppBrowserView,
browserConfiguration: const BrowserConfiguration(showTitle: true),
)) {
throw Exception('Could not launch $url');
Expand Down Expand Up @@ -232,7 +232,7 @@ class _MyHomePageState extends State<MyHomePage> {
const Padding(padding: EdgeInsets.all(16.0)),
ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInAppWithShowTitle(toLaunch);
_launched = _launchInAppWithBrowserOptions(toLaunch);
}),
child: const Text('Launch in app with showTitle'),
),
Expand Down
3 changes: 1 addition & 2 deletions packages/url_launcher/url_launcher/lib/src/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ class WebViewConfiguration {
final Map<String, String> headers;
}

/// Additional configuration options for [LaunchMode.inAppWebView]
// TODO(alex): replace this when the pr lands
/// Additional configuration options for [LaunchMode.inAppBrowserView]
@immutable
class BrowserConfiguration {
/// Creates a new InAppBrowserConfiguration with given settings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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;
Expand All @@ -50,15 +55,15 @@ protected static ArrayList<Object> 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;
}

/**
* Configuration options for an in-app WebView.
*
* <p>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;
Expand Down Expand Up @@ -239,34 +244,33 @@ 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<String, String> headers);
/**
* Opens the URL in an in-app Custom Tab or WebView, returning true if it opens successfully.
* Opens the URL in an in-app WebView, returning true if it opens
* successfully.
*/
@NonNull
Boolean openUrlInWebView(
@NonNull String url,
@NonNull WebViewOptions webViewOptions,
@NonNull BrowserOptions browserOptions);
@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();

/** The codec used by UrlLauncherApi. */
static @NonNull MessageCodec<Object> 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<Object> 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) -> {
Expand All @@ -276,7 +280,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<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
Expand All @@ -289,9 +294,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> 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) -> {
Expand All @@ -302,7 +305,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<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
Expand All @@ -315,22 +319,21 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.url_launcher_android.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 webViewOptionsArg = (WebViewOptions) args.get(1);
BrowserOptions browserOptionsArg = (BrowserOptions) args.get(2);
Boolean allowCustomTabArg = (Boolean) args.get(1);
WebViewOptions webViewOptionsArg = (WebViewOptions) args.get(2);
BrowserOptions browserOptionsArg = (BrowserOptions) args.get(3);
try {
Boolean output =
api.openUrlInWebView(urlArg, webViewOptionsArg, browserOptionsArg);
Boolean output = api.openUrlInApp(urlArg, allowCustomTabArg, webViewOptionsArg, browserOptionsArg);
wrapped.add(0, output);
} catch (Throwable exception) {
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
Expand All @@ -343,17 +346,38 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UrlLaunche
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView",
getCodec());
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.supportsCustomTabs();
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.closeWebView", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
try {
api.closeWebView();
wrapped.add(0, null);
} catch (Throwable exception) {
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
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;

Expand Down Expand Up @@ -97,17 +98,19 @@ void setActivity(@Nullable Activity activity) {
}

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

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

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

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

@VisibleForTesting
public static boolean openCustomTab(
@NonNull Context context,
Expand All @@ -144,7 +152,6 @@ public static boolean openCustomTab(
@NonNull BrowserOptions options) {
CustomTabsIntent customTabsIntent =
new CustomTabsIntent.Builder().setShowTitle(options.getShowTitle()).build();

customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, headersBundle);

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -105,8 +105,7 @@ class UrlLauncherApi {
/// Returns true if the URL can definitely be launched.
Future<bool> canLaunchUrl(String arg_url) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl',
codec,
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.canLaunchUrl', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_url]) as List<Object?>?;
Expand All @@ -132,11 +131,9 @@ class UrlLauncherApi {
}

/// Opens the URL externally, returning true if successful.
Future<bool> launchUrl(
String arg_url, Map<String?, String?> arg_headers) async {
Future<bool> launchUrl(String arg_url, Map<String?, String?> arg_headers) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl',
codec,
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.launchUrl', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_url, arg_headers]) as List<Object?>?;
Expand All @@ -163,17 +160,39 @@ class UrlLauncherApi {

/// Opens the URL in an in-app WebView, returning true if it opens
/// successfully.
Future<bool> openUrlInWebView(
String arg_url,
WebViewOptions arg_webViewOptions,
BrowserOptions arg_browserOptions) async {
Future<bool> openUrlInApp(String arg_url, bool arg_allowCustomTab, WebViewOptions arg_webViewOptions, BrowserOptions arg_browserOptions) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInWebView',
codec,
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.openUrlInApp', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel
.send(<Object?>[arg_url, arg_webViewOptions, arg_browserOptions])
as List<Object?>?;
final List<Object?>? replyList =
await channel.send(<Object?>[arg_url, arg_allowCustomTab, arg_webViewOptions, arg_browserOptions]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as bool?)!;
}
}

Future<bool> supportsCustomTabs() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.supportsCustomTabs', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
Expand All @@ -198,10 +217,10 @@ class UrlLauncherApi {
/// Closes the view opened by [openUrlInSafariViewController].
Future<void> closeWebView() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView',
codec,
'dev.flutter.pigeon.url_launcher_android.UrlLauncherApi.closeWebView', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
final List<Object?>? replyList =
await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.