1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright 2016 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "gnetworkmonitorportal.h"
22 #include "ginitable.h"
23 #include "giomodule-priv.h"
25 #include "gportalsupport.h"
27 static GInitableIface
*initable_parent_iface
;
28 static void g_network_monitor_portal_iface_init (GNetworkMonitorInterface
*iface
);
29 static void g_network_monitor_portal_initable_iface_init (GInitableIface
*iface
);
34 PROP_NETWORK_AVAILABLE
,
39 struct _GNetworkMonitorPortalPrivate
47 GNetworkConnectivity connectivity
;
50 G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorPortal
, g_network_monitor_portal
, G_TYPE_NETWORK_MONITOR_BASE
,
51 G_ADD_PRIVATE (GNetworkMonitorPortal
)
52 G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR
,
53 g_network_monitor_portal_iface_init
)
54 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE
,
55 g_network_monitor_portal_initable_iface_init
)
56 _g_io_modules_ensure_extension_points_registered ();
57 g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME
,
63 g_network_monitor_portal_init (GNetworkMonitorPortal
*nm
)
65 nm
->priv
= g_network_monitor_portal_get_instance_private (nm
);
69 g_network_monitor_portal_get_property (GObject
*object
,
74 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (object
);
78 case PROP_NETWORK_AVAILABLE
:
79 g_value_set_boolean (value
, nm
->priv
->available
);
82 case PROP_NETWORK_METERED
:
83 g_value_set_boolean (value
, nm
->priv
->metered
);
86 case PROP_CONNECTIVITY
:
87 g_value_set_enum (value
, nm
->priv
->connectivity
);
91 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
97 got_available (GObject
*source
,
101 GDBusProxy
*proxy
= G_DBUS_PROXY (source
);
102 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (data
);
103 GError
*error
= NULL
;
107 ret
= g_dbus_proxy_call_finish (proxy
, res
, &error
);
110 g_warning ("%s", error
->message
);
111 g_clear_error (&error
);
115 g_variant_get (ret
, "(b)", &available
);
116 g_variant_unref (ret
);
118 if (nm
->priv
->available
!= available
)
120 nm
->priv
->available
= available
;
121 g_object_notify (G_OBJECT (nm
), "network-available");
122 g_signal_emit_by_name (nm
, "network-changed", available
);
127 got_metered (GObject
*source
,
131 GDBusProxy
*proxy
= G_DBUS_PROXY (source
);
132 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (data
);
133 GError
*error
= NULL
;
137 ret
= g_dbus_proxy_call_finish (proxy
, res
, &error
);
140 g_warning ("%s", error
->message
);
141 g_clear_error (&error
);
145 g_variant_get (ret
, "(b)", &metered
);
146 g_variant_unref (ret
);
148 if (nm
->priv
->metered
!= metered
)
150 nm
->priv
->metered
= metered
;
151 g_object_notify (G_OBJECT (nm
), "network-metered");
156 got_connectivity (GObject
*source
,
160 GDBusProxy
*proxy
= G_DBUS_PROXY (source
);
161 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (data
);
162 GError
*error
= NULL
;
164 GNetworkConnectivity connectivity
;
166 ret
= g_dbus_proxy_call_finish (proxy
, res
, &error
);
169 g_warning ("%s", error
->message
);
170 g_clear_error (&error
);
174 g_variant_get (ret
, "(u)", &connectivity
);
175 g_variant_unref (ret
);
177 if (nm
->priv
->connectivity
!= connectivity
)
179 nm
->priv
->connectivity
= connectivity
;
180 g_object_notify (G_OBJECT (nm
), "connectivity");
185 update_properties (GDBusProxy
*proxy
,
186 GNetworkMonitorPortal
*nm
)
188 g_dbus_proxy_call (proxy
, "GetConnectivity", NULL
, 0, -1, NULL
, got_connectivity
, nm
);
189 g_dbus_proxy_call (proxy
, "GetMetered", NULL
, 0, -1, NULL
, got_metered
, nm
);
190 g_dbus_proxy_call (proxy
, "GetAvailable", NULL
, 0, -1, NULL
, got_available
, nm
);
194 proxy_signal (GDBusProxy
*proxy
,
197 GVariant
*parameters
,
198 GNetworkMonitorPortal
*nm
)
200 if (!nm
->priv
->has_network
)
203 if (nm
->priv
->version
== 1)
207 g_variant_get (parameters
, "(b)", &available
);
208 g_signal_emit_by_name (nm
, "network-changed", available
);
210 else if (nm
->priv
->version
== 2)
212 update_properties (proxy
, nm
);
217 proxy_properties_changed (GDBusProxy
*proxy
,
219 GVariant
*invalidated
,
220 GNetworkMonitorPortal
*nm
)
222 if (!nm
->priv
->has_network
)
225 if (nm
->priv
->version
== 1)
229 ret
= g_dbus_proxy_get_cached_property (proxy
, "connectivity");
232 GNetworkConnectivity connectivity
= g_variant_get_uint32 (ret
);
233 if (nm
->priv
->connectivity
!= connectivity
)
235 nm
->priv
->connectivity
= connectivity
;
236 g_object_notify (G_OBJECT (nm
), "connectivity");
238 g_variant_unref (ret
);
241 ret
= g_dbus_proxy_get_cached_property (proxy
, "metered");
244 gboolean metered
= g_variant_get_boolean (ret
);
245 if (nm
->priv
->metered
!= metered
)
247 nm
->priv
->metered
= metered
;
248 g_object_notify (G_OBJECT (nm
), "network-metered");
250 g_variant_unref (ret
);
253 ret
= g_dbus_proxy_get_cached_property (proxy
, "available");
256 gboolean available
= g_variant_get_boolean (ret
);
257 if (nm
->priv
->available
!= available
)
259 nm
->priv
->available
= available
;
260 g_object_notify (G_OBJECT (nm
), "network-available");
261 g_signal_emit_by_name (nm
, "network-changed", available
);
263 g_variant_unref (ret
);
269 g_network_monitor_portal_initable_init (GInitable
*initable
,
270 GCancellable
*cancellable
,
273 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (initable
);
275 gchar
*name_owner
= NULL
;
279 nm
->priv
->available
= FALSE
;
280 nm
->priv
->metered
= FALSE
;
281 nm
->priv
->connectivity
= G_NETWORK_CONNECTIVITY_LOCAL
;
283 if (!glib_should_use_portal ())
285 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
, "Not using portals");
289 proxy
= g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION
,
290 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START
291 | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES
,
293 "org.freedesktop.portal.Desktop",
294 "/org/freedesktop/portal/desktop",
295 "org.freedesktop.portal.NetworkMonitor",
301 name_owner
= g_dbus_proxy_get_name_owner (proxy
);
305 g_object_unref (proxy
);
308 G_DBUS_ERROR_NAME_HAS_NO_OWNER
,
309 "Desktop portal not found");
315 ret
= g_dbus_proxy_get_cached_property (proxy
, "version");
316 g_variant_get (ret
, "u", &version
);
317 g_variant_unref (ret
);
319 if (version
!= 1 && version
!= 2)
321 g_object_unref (proxy
);
324 G_DBUS_ERROR_NAME_HAS_NO_OWNER
,
325 "NetworkMonitor portal unsupported version: %d", version
);
329 g_signal_connect (proxy
, "g-signal", G_CALLBACK (proxy_signal
), nm
);
330 g_signal_connect (proxy
, "g-properties-changed", G_CALLBACK (proxy_properties_changed
), nm
);
332 nm
->priv
->proxy
= proxy
;
333 nm
->priv
->has_network
= glib_network_available_in_sandbox ();
334 nm
->priv
->version
= version
;
336 if (!initable_parent_iface
->init (initable
, cancellable
, error
))
339 if (nm
->priv
->has_network
&& nm
->priv
->version
== 2)
340 update_properties (proxy
, nm
);
346 g_network_monitor_portal_finalize (GObject
*object
)
348 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (object
);
350 g_clear_object (&nm
->priv
->proxy
);
352 G_OBJECT_CLASS (g_network_monitor_portal_parent_class
)->finalize (object
);
356 g_network_monitor_portal_class_init (GNetworkMonitorPortalClass
*class)
358 GObjectClass
*gobject_class
= G_OBJECT_CLASS (class);
360 gobject_class
->finalize
= g_network_monitor_portal_finalize
;
361 gobject_class
->get_property
= g_network_monitor_portal_get_property
;
363 g_object_class_override_property (gobject_class
, PROP_NETWORK_AVAILABLE
, "network-available");
364 g_object_class_override_property (gobject_class
, PROP_NETWORK_METERED
, "network-metered");
365 g_object_class_override_property (gobject_class
, PROP_CONNECTIVITY
, "connectivity");
369 g_network_monitor_portal_iface_init (GNetworkMonitorInterface
*monitor_iface
)
374 g_network_monitor_portal_initable_iface_init (GInitableIface
*iface
)
376 initable_parent_iface
= g_type_interface_peek_parent (iface
);
378 iface
->init
= g_network_monitor_portal_initable_init
;