diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-08-23 23:02:41 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2018-08-27 10:55:01 -0400 |
commit | a090d8605bc5e393c603f5ec0cfcf31259e82e3e (patch) | |
tree | 9df9fc0765ae09e8122a07eaeabcacf4fe297782 | |
parent | 3a3a32a2bb55cd64510dcdbe3bf8e844a747b49a (diff) | |
download | glib-a090d8605bc5e393c603f5ec0cfcf31259e82e3e.tar.gz |
portal network monitor: Implement can_reach
Version 3 of the network monitor portal interface adds
a CanReach method. Use it to implement can_reach.
The docs state that can_reach will either return TRUE
or set an error. So, set an error of G_IO_ERROR_HOST_UNREACHABLE
when the portal returns FALSE for CanReach.
-rw-r--r-- | gio/gnetworkmonitorportal.c | 123 |
1 files changed, 121 insertions, 2 deletions
diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c index 33bdea87f..ebf210e5b 100644 --- a/gio/gnetworkmonitorportal.c +++ b/gio/gnetworkmonitorportal.c @@ -325,7 +325,7 @@ g_network_monitor_portal_initable_init (GInitable *initable, g_variant_get (ret, "u", &version); g_variant_unref (ret); - if (version != 1 && version != 2) + if (version != 1 && version != 2 && version != 3) { g_object_unref (proxy); g_set_error (error, @@ -345,7 +345,7 @@ g_network_monitor_portal_initable_init (GInitable *initable, if (!initable_parent_iface->init (initable, cancellable, error)) return FALSE; - if (nm->priv->has_network && nm->priv->version == 2) + if (nm->priv->has_network && nm->priv->version > 1) update_properties (proxy, nm); return TRUE; @@ -374,9 +374,128 @@ g_network_monitor_portal_class_init (GNetworkMonitorPortalClass *class) g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity"); } +static gboolean +g_network_monitor_portal_can_reach (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (monitor); + GVariant *ret; + GNetworkAddress *address; + gboolean reachable = FALSE; + + if (!G_IS_NETWORK_ADDRESS (connectable)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Can't handle this kind of GSocketConnectable (%s)", + G_OBJECT_TYPE_NAME (connectable)); + return FALSE; + } + + address = G_NETWORK_ADDRESS (connectable); + + ret = g_dbus_proxy_call_sync (nm->priv->proxy, + "CanReach", + g_variant_new ("(su)", + g_network_address_get_hostname (address), + g_network_address_get_port (address)), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + + if (ret) + { + g_variant_get (ret, "(b)", &reachable); + g_variant_unref (ret); + } + + return reachable; +} + +static void +can_reach_done (GObject *source, + GAsyncResult *result, + gpointer data) +{ + GTask *task = data; + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (g_task_get_source_object (task)); + GError *error = NULL; + GVariant *ret; + gboolean reachable; + + ret = g_dbus_proxy_call_finish (nm->priv->proxy, result, &error); + if (ret == NULL) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_variant_get (ret, "(b)", &reachable); + g_variant_unref (ret); + + if (reachable) + g_task_return_boolean (task, TRUE); + else + g_task_return_new_error (task, + G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, + "Can't reach host"); + + g_object_unref (task); +} + +static void +g_network_monitor_portal_can_reach_async (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (monitor); + GTask *task; + GNetworkAddress *address; + + task = g_task_new (monitor, cancellable, callback, data); + + if (!G_IS_NETWORK_ADDRESS (connectable)) + { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Can't handle this kind of GSocketConnectable (%s)", + G_OBJECT_TYPE_NAME (connectable)); + g_object_unref (task); + return; + } + + address = G_NETWORK_ADDRESS (connectable); + + g_dbus_proxy_call (nm->priv->proxy, + "CanReach", + g_variant_new ("(su)", + g_network_address_get_hostname (address), + g_network_address_get_port (address)), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + can_reach_done, + task); +} + +static gboolean +g_network_monitor_portal_can_reach_finish (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + static void g_network_monitor_portal_iface_init (GNetworkMonitorInterface *monitor_iface) { + monitor_iface->can_reach = g_network_monitor_portal_can_reach; + monitor_iface->can_reach_async = g_network_monitor_portal_can_reach_async; + monitor_iface->can_reach_finish = g_network_monitor_portal_can_reach_finish; } static void |