diff options
author | Matthias Clasen <mclasen@redhat.com> | 2016-06-21 19:55:23 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2016-07-03 18:01:45 -0400 |
commit | 956d4858f340c56f9fe393cf4c8554fe24b1fc74 (patch) | |
tree | 07c423694fb51a082c8bd55c8473a30235681888 | |
parent | 5496d16ed30c91c8be7b17085689cf1308aac707 (diff) | |
download | glib-956d4858f340c56f9fe393cf4c8554fe24b1fc74.tar.gz |
Add a portalized network monitor implementation
The backend for this lives in xdg-desktop-portal, and is in turn
using GNetworkMonitor.
-rw-r--r-- | gio/Makefile.am | 22 | ||||
-rw-r--r-- | gio/giomodule.c | 2 | ||||
-rw-r--r-- | gio/gnetworkmonitorportal.c | 192 | ||||
-rw-r--r-- | gio/gnetworkmonitorportal.h | 53 | ||||
-rw-r--r-- | gio/org.freedesktop.portal.NetworkMonitor.xml | 31 |
5 files changed, 300 insertions, 0 deletions
diff --git a/gio/Makefile.am b/gio/Makefile.am index 3b3c104db..58d51b8ff 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -338,6 +338,27 @@ giowin32include_HEADERS = \ endif +xdp_dbus_built_sources = xdp-dbus.c xdp-dbus.h +BUILT_SOURCES += $(xdp_dbus_built_sources) + +EXTRA_DIST += org.freedesktop.portal.NetworkMonitor.xml + +$(xdp_dbus_built_sources) : $(srcdir)/org.freedesktop.portal.NetworkMonitor.xml + $(AM_V_GEN) UNINSTALLED_GLIB_SRCDIR=$(top_srcdir) \ + UNINSTALLED_GLIB_BUILDDIR=$(top_builddir) \ + $(PYTHON) $(srcdir)/gdbus-2.0/codegen/gdbus-codegen.in \ + --interface-prefix org.freedesktop.portal. \ + --c-namespace Xdp \ + --generate-c-code $(builddir)/xdp-dbus \ + $(srcdir)/org.freedesktop.portal.NetworkMonitor.xml \ + $(NULL) + +portal_sources = \ + gnetworkmonitorportal.c \ + gnetworkmonitorportal.h \ + $(xdp_dbus_built_sources) \ + $(NULL) + libgio_2_0_la_SOURCES = \ gappinfo.c \ gappinfoprivate.h \ @@ -492,6 +513,7 @@ libgio_2_0_la_SOURCES = \ $(settings_sources) \ $(gdbus_sources) \ $(local_sources) \ + $(portal_sources) \ $(NULL) EXTRA_DIST += strinfo.c diff --git a/gio/giomodule.c b/gio/giomodule.c index 54471c7a3..f84e17462 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -905,6 +905,7 @@ extern GType _g_winhttp_vfs_get_type (void); extern GType _g_dummy_proxy_resolver_get_type (void); extern GType _g_dummy_tls_backend_get_type (void); extern GType g_network_monitor_base_get_type (void); +extern GType g_network_monitor_portal_get_type (void); #ifdef HAVE_NETLINK extern GType _g_network_monitor_netlink_get_type (void); extern GType _g_network_monitor_nm_get_type (void); @@ -1130,6 +1131,7 @@ _g_io_modules_ensure_loaded (void) g_type_ensure (_g_socks5_proxy_get_type ()); g_type_ensure (_g_dummy_tls_backend_get_type ()); g_type_ensure (g_network_monitor_base_get_type ()); + g_type_ensure (g_network_monitor_portal_get_type ()); #ifdef HAVE_NETLINK g_type_ensure (_g_network_monitor_netlink_get_type ()); g_type_ensure (_g_network_monitor_nm_get_type ()); diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c new file mode 100644 index 000000000..2ff68fe0b --- /dev/null +++ b/gio/gnetworkmonitorportal.c @@ -0,0 +1,192 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "gnetworkmonitorportal.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "gnetworkmonitor.h" +#include "xdp-dbus.h" + + +static void g_network_monitor_portal_iface_init (GNetworkMonitorInterface *iface); +static void g_network_monitor_portal_initable_iface_init (GInitableIface *iface); + +enum +{ + PROP_0, + PROP_NETWORK_AVAILABLE, + PROP_NETWORK_METERED, + PROP_CONNECTIVITY +}; + +struct _GNetworkMonitorPortalPrivate +{ + XdpNetworkMonitor *proxy; +}; + +G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorPortal, g_network_monitor_portal, G_TYPE_NETWORK_MONITOR_BASE, + G_ADD_PRIVATE (GNetworkMonitorPortal) + G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR, + g_network_monitor_portal_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_network_monitor_portal_initable_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "portal", + 30)) + +static void +g_network_monitor_portal_init (GNetworkMonitorPortal *nm) +{ + nm->priv = g_network_monitor_portal_get_instance_private (nm); +} + +static void +g_network_monitor_portal_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (object); + + switch (prop_id) + { + case PROP_NETWORK_AVAILABLE: + g_value_set_boolean (value, xdp_network_monitor_get_available (nm->priv->proxy)); + break; + + case PROP_NETWORK_METERED: + g_value_set_boolean (value, xdp_network_monitor_get_metered (nm->priv->proxy)); + break; + + case PROP_CONNECTIVITY: + g_value_set_enum (value, xdp_network_monitor_get_connectivity (nm->priv->proxy)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +proxy_changed (XdpNetworkMonitor *proxy, + gboolean available, + GNetworkMonitor *monitor) +{ + g_signal_emit_by_name (monitor, "network-changed", available); +} + + +static gboolean +should_use_portal (void) +{ + const char *use_portal; + char *path; + + path = g_strdup_printf ("/run/user/%d/flatpak-info", getuid()); + if (g_file_test (path, G_FILE_TEST_EXISTS)) + use_portal = "1"; + else + { + use_portal = g_getenv ("GTK_USE_PORTAL"); + if (!use_portal) + use_portal = ""; + } + g_free (path); + + return g_str_equal (use_portal, "1"); +} + +static gboolean +g_network_monitor_portal_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (initable); + XdpNetworkMonitor *proxy; + gchar *name_owner = NULL; + + if (!should_use_portal ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not using portals"); + return FALSE; + } + + proxy = xdp_network_monitor_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START + | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + cancellable, + error); + if (!proxy) + return FALSE; + + name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy)); + + if (!name_owner) + { + g_object_unref (proxy); + return FALSE; + } + + g_free (name_owner); + + g_signal_connect (G_OBJECT (proxy), "changed", G_CALLBACK (proxy_changed), nm); + nm->priv->proxy = proxy; + + return TRUE; +} + +static void +g_network_monitor_portal_finalize (GObject *object) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (object); + + g_clear_object (&nm->priv->proxy); + + G_OBJECT_CLASS (g_network_monitor_portal_parent_class)->finalize (object); +} + +static void +g_network_monitor_portal_class_init (GNetworkMonitorPortalClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->finalize = g_network_monitor_portal_finalize; + gobject_class->get_property = g_network_monitor_portal_get_property; + + g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available"); + g_object_class_override_property (gobject_class, PROP_NETWORK_METERED, "network-metered"); + g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity"); +} + +static void +g_network_monitor_portal_iface_init (GNetworkMonitorInterface *monitor_iface) +{ +} + +static void +g_network_monitor_portal_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_network_monitor_portal_initable_init; +} diff --git a/gio/gnetworkmonitorportal.h b/gio/gnetworkmonitorportal.h new file mode 100644 index 000000000..3d25f57be --- /dev/null +++ b/gio/gnetworkmonitorportal.h @@ -0,0 +1,53 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __G_NETWORK_MONITOR_PORTAL_H__ +#define __G_NETWORK_MONITOR_PORTAL_H__ + +#include "gnetworkmonitorbase.h" + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_MONITOR_PORTAL (g_network_monitor_portal_get_type ()) +#define G_NETWORK_MONITOR_PORTAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR_PORTAL, GNetworkMonitorPortal)) +#define G_NETWORK_MONITOR_PORTAL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_MONITOR_PORTAL, GNetworkMonitorPortalClass)) +#define G_IS_NETWORK_MONITOR_PORTAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR_PORTAL)) +#define G_IS_NETWORK_MONITOR_PORTAL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_MONITOR_PORTAL)) +#define G_NETWORK_MONITOR_PORTAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_MONITOR_PORTAL, GNetworkMonitorPortalClass)) +#define G_NETWORK_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + + +typedef struct _GNetworkMonitorPortal GNetworkMonitorPortal; +typedef struct _GNetworkMonitorPortalClass GNetworkMonitorPortalClass; +typedef struct _GNetworkMonitorPortalPrivate GNetworkMonitorPortalPrivate; + +struct _GNetworkMonitorPortal { + GNetworkMonitorBase parent_instance; + + GNetworkMonitorPortalPrivate *priv; +}; + +struct _GNetworkMonitorPortalClass { + GNetworkMonitorBaseClass parent_class; +}; + +GType g_network_monitor_portal_get_type (void); + +G_END_DECLS + +#endif /* __G_NETWORK_MONITOR_PORTAL_H__ */ diff --git a/gio/org.freedesktop.portal.NetworkMonitor.xml b/gio/org.freedesktop.portal.NetworkMonitor.xml new file mode 100644 index 000000000..284b7bd3e --- /dev/null +++ b/gio/org.freedesktop.portal.NetworkMonitor.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- + Copyright (C) 2016 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + Author: Matthias Clasen <mclasen@redhat.com> +--> +<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd" name="/"> + <interface name="org.freedesktop.portal.NetworkMonitor"> + <signal name="changed"> + <arg type="b" name="available"/> + </signal> + <property name="available" type="b" access="read"/> + <property name="metered" type="b" access="read"/> + <property name="connectivity" type="u" access="read"/> + </interface> +</node> |