Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[url_launcher] Simplify Linux implementation #5376

Merged
merged 2 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions packages/url_launcher/url_launcher_linux/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.1.1

* Implements `launchUrl`.
* Simplifies method channel interface by removing unused elements.

## 3.1.0

* Implements `supportsMode` and `supportsCloseForMode`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ class UrlLauncherLinux extends UrlLauncherPlatform {
final LinkDelegate? linkDelegate = null;

@override
Future<bool> canLaunch(String url) {
return _channel.invokeMethod<bool>(
'canLaunch',
<String, Object>{'url': url},
).then((bool? value) => value ?? false);
Future<bool> canLaunch(String url) async {
return (await _channel.invokeMethod<bool>('canLaunch', url)) ?? false;
}

@override
Expand All @@ -40,16 +37,14 @@ class UrlLauncherLinux extends UrlLauncherPlatform {
required Map<String, String> headers,
String? webOnlyWindowName,
}) {
return _channel.invokeMethod<bool>(
'launch',
<String, Object>{
'url': url,
'enableJavaScript': enableJavaScript,
'enableDomStorage': enableDomStorage,
'universalLinksOnly': universalLinksOnly,
'headers': headers,
},
).then((bool? value) => value ?? false);
// None of the options are supported, so they don't need to be converted to
// LaunchOptions.
return launchUrl(url, const LaunchOptions());
}

@override
Future<bool> launchUrl(String url, LaunchOptions options) async {
return (await _channel.invokeMethod<bool>('launch', url)) ?? false;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ namespace url_launcher_plugin {
namespace test {

TEST(UrlLauncherPlugin, CanLaunchSuccess) {
g_autoptr(FlValue) args = fl_value_new_map();
fl_value_set_string_take(args, "url",
fl_value_new_string("https://flutter.dev"));
g_autoptr(FlValue) args = fl_value_new_string("https://flutter.dev");
g_autoptr(FlMethodResponse) response = can_launch(nullptr, args);
ASSERT_NE(response, nullptr);
ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
Expand All @@ -28,8 +26,7 @@ TEST(UrlLauncherPlugin, CanLaunchSuccess) {
}

TEST(UrlLauncherPlugin, CanLaunchFailureUnhandled) {
g_autoptr(FlValue) args = fl_value_new_map();
fl_value_set_string_take(args, "url", fl_value_new_string("madeup:scheme"));
g_autoptr(FlValue) args = fl_value_new_string("madeup:scheme");
g_autoptr(FlMethodResponse) response = can_launch(nullptr, args);
ASSERT_NE(response, nullptr);
ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
Expand All @@ -40,8 +37,7 @@ TEST(UrlLauncherPlugin, CanLaunchFailureUnhandled) {
}

TEST(UrlLauncherPlugin, CanLaunchFileSuccess) {
g_autoptr(FlValue) args = fl_value_new_map();
fl_value_set_string_take(args, "url", fl_value_new_string("file:///"));
g_autoptr(FlValue) args = fl_value_new_string("file:///");
g_autoptr(FlMethodResponse) response = can_launch(nullptr, args);
ASSERT_NE(response, nullptr);
ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
Expand All @@ -52,9 +48,8 @@ TEST(UrlLauncherPlugin, CanLaunchFileSuccess) {
}

TEST(UrlLauncherPlugin, CanLaunchFailureInvalidFileExtension) {
g_autoptr(FlValue) args = fl_value_new_map();
fl_value_set_string_take(
args, "url", fl_value_new_string("file:///madeup.madeupextension"));
g_autoptr(FlValue) args =
fl_value_new_string("file:///madeup.madeupextension");
g_autoptr(FlMethodResponse) response = can_launch(nullptr, args);
ASSERT_NE(response, nullptr);
ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
Expand All @@ -67,8 +62,7 @@ TEST(UrlLauncherPlugin, CanLaunchFailureInvalidFileExtension) {
// For consistency with the established mobile implementations,
// an invalid URL should return false, not an error.
TEST(UrlLauncherPlugin, CanLaunchFailureInvalidUrl) {
g_autoptr(FlValue) args = fl_value_new_map();
fl_value_set_string_take(args, "url", fl_value_new_string(""));
g_autoptr(FlValue) args = fl_value_new_string("");
g_autoptr(FlMethodResponse) response = can_launch(nullptr, args);
ASSERT_NE(response, nullptr);
ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@

// See url_launcher_channel.dart for documentation.
const char kChannelName[] = "plugins.flutter.io/url_launcher_linux";
const char kBadArgumentsError[] = "Bad Arguments";
const char kLaunchError[] = "Launch Error";
const char kCanLaunchMethod[] = "canLaunch";
const char kLaunchMethod[] = "launch";
const char kUrlKey[] = "url";

struct _FlUrlLauncherPlugin {
GObject parent_instance;
Expand All @@ -30,21 +28,6 @@ struct _FlUrlLauncherPlugin {

G_DEFINE_TYPE(FlUrlLauncherPlugin, fl_url_launcher_plugin, g_object_get_type())

// Gets the URL from the arguments or generates an error.
static gchar* get_url(FlValue* args, GError** error) {
if (fl_value_get_type(args) != FL_VALUE_TYPE_MAP) {
g_set_error(error, 0, 0, "Argument map missing or malformed");
return nullptr;
}
FlValue* url_value = fl_value_lookup_string(args, kUrlKey);
if (url_value == nullptr) {
g_set_error(error, 0, 0, "Missing URL");
return nullptr;
}

return g_strdup(fl_value_get_string(url_value));
}

// Checks if URI has launchable file resource.
static gboolean can_launch_uri_with_file_resource(FlUrlLauncherPlugin* self,
const gchar* url) {
Expand All @@ -57,12 +40,7 @@ static gboolean can_launch_uri_with_file_resource(FlUrlLauncherPlugin* self,

// Called to check if a URL can be launched.
FlMethodResponse* can_launch(FlUrlLauncherPlugin* self, FlValue* args) {
g_autoptr(GError) error = nullptr;
g_autofree gchar* url = get_url(args, &error);
if (url == nullptr) {
return FL_METHOD_RESPONSE(fl_method_error_response_new(
kBadArgumentsError, error->message, nullptr));
}
const gchar* url = fl_value_get_string(args);

gboolean is_launchable = FALSE;
g_autofree gchar* scheme = g_uri_parse_scheme(url);
Expand All @@ -82,14 +60,10 @@ FlMethodResponse* can_launch(FlUrlLauncherPlugin* self, FlValue* args) {

// Called when a URL should launch.
static FlMethodResponse* launch(FlUrlLauncherPlugin* self, FlValue* args) {
g_autoptr(GError) error = nullptr;
g_autofree gchar* url = get_url(args, &error);
if (url == nullptr) {
return FL_METHOD_RESPONSE(fl_method_error_response_new(
kBadArgumentsError, error->message, nullptr));
}
const gchar* url = fl_value_get_string(args);

FlView* view = fl_plugin_registrar_get_view(self->registrar);
g_autoptr(GError) error = nullptr;
gboolean launched;
if (view != nullptr) {
GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view)));
Expand Down
2 changes: 1 addition & 1 deletion packages/url_launcher/url_launcher_linux/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: url_launcher_linux
description: Linux implementation of the url_launcher plugin.
repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_linux
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
version: 3.1.0
version: 3.1.1

environment:
sdk: ">=2.19.0 <4.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ void main() {
await launcher.canLaunch('http://example.com/');
expect(
log,
<Matcher>[
isMethodCall('canLaunch', arguments: <String, Object>{
'url': 'http://example.com/',
})
],
<Matcher>[isMethodCall('canLaunch', arguments: 'http://example.com/')],
);
});

Expand All @@ -66,65 +62,7 @@ void main() {
);
expect(
log,
<Matcher>[
isMethodCall('launch', arguments: <String, Object>{
'url': 'http://example.com/',
'enableJavaScript': false,
'enableDomStorage': false,
'universalLinksOnly': false,
'headers': <String, String>{},
})
],
);
});

test('launch with headers', () async {
final UrlLauncherLinux launcher = UrlLauncherLinux();
await launcher.launch(
'http://example.com/',
useSafariVC: true,
useWebView: false,
enableJavaScript: false,
enableDomStorage: false,
universalLinksOnly: false,
headers: const <String, String>{'key': 'value'},
);
expect(
log,
<Matcher>[
isMethodCall('launch', arguments: <String, Object>{
'url': 'http://example.com/',
'enableJavaScript': false,
'enableDomStorage': false,
'universalLinksOnly': false,
'headers': <String, String>{'key': 'value'},
})
],
);
});

test('launch universal links only', () async {
final UrlLauncherLinux launcher = UrlLauncherLinux();
await launcher.launch(
'http://example.com/',
useSafariVC: false,
useWebView: false,
enableJavaScript: false,
enableDomStorage: false,
universalLinksOnly: true,
headers: const <String, String>{},
);
expect(
log,
<Matcher>[
isMethodCall('launch', arguments: <String, Object>{
'url': 'http://example.com/',
'enableJavaScript': false,
'enableDomStorage': false,
'universalLinksOnly': true,
'headers': <String, String>{},
})
],
<Matcher>[isMethodCall('launch', arguments: 'http://example.com/')],
);
});

Expand All @@ -143,6 +81,25 @@ void main() {
expect(launched, false);
});

group('launchUrl', () {
test('passes URL', () async {
final UrlLauncherLinux launcher = UrlLauncherLinux();
await launcher.launchUrl('http://example.com/', const LaunchOptions());
expect(
log,
<Matcher>[isMethodCall('launch', arguments: 'http://example.com/')],
);
});

test('returns false if platform returns null', () async {
final UrlLauncherLinux launcher = UrlLauncherLinux();
final bool launched = await launcher.launchUrl(
'http://example.com/', const LaunchOptions());

expect(launched, false);
});
});

group('supportsMode', () {
test('returns true for platformDefault', () async {
final UrlLauncherLinux launcher = UrlLauncherLinux();
Expand Down