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 proxy_signal (GDBusProxy
*proxy
,
188 GVariant
*parameters
,
189 GNetworkMonitorPortal
*nm
)
191 if (!nm
->priv
->has_network
)
194 if (nm
->priv
->version
== 1)
198 g_variant_get (parameters
, "(b)", &available
);
199 g_signal_emit_by_name (nm
, "network-changed", available
);
201 else if (nm
->priv
->version
== 2)
203 g_dbus_proxy_call (proxy
, "GetConnectivity", NULL
, 0, -1, NULL
, got_connectivity
, nm
);
204 g_dbus_proxy_call (proxy
, "GetMetered", NULL
, 0, -1, NULL
, got_metered
, nm
);
205 g_dbus_proxy_call (proxy
, "GetAvailable", NULL
, 0, -1, NULL
, got_available
, nm
);
210 proxy_properties_changed (GDBusProxy
*proxy
,
212 GVariant
*invalidated
,
213 GNetworkMonitorPortal
*nm
)
215 if (!nm
->priv
->has_network
)
218 if (nm
->priv
->version
== 1)
222 ret
= g_dbus_proxy_get_cached_property (proxy
, "connectivity");
225 GNetworkConnectivity connectivity
= g_variant_get_uint32 (ret
);
226 if (nm
->priv
->connectivity
!= connectivity
)
228 nm
->priv
->connectivity
= connectivity
;
229 g_object_notify (G_OBJECT (nm
), "connectivity");
231 g_variant_unref (ret
);
234 ret
= g_dbus_proxy_get_cached_property (proxy
, "metered");
237 gboolean metered
= g_variant_get_boolean (ret
);
238 if (nm
->priv
->metered
!= metered
)
240 nm
->priv
->metered
= metered
;
241 g_object_notify (G_OBJECT (nm
), "network-metered");
243 g_variant_unref (ret
);
246 ret
= g_dbus_proxy_get_cached_property (proxy
, "available");
249 gboolean available
= g_variant_get_boolean (ret
);
250 if (nm
->priv
->available
!= available
)
252 nm
->priv
->available
= available
;
253 g_object_notify (G_OBJECT (nm
), "network-available");
254 g_signal_emit_by_name (nm
, "network-changed", available
);
256 g_variant_unref (ret
);
262 g_network_monitor_portal_initable_init (GInitable
*initable
,
263 GCancellable
*cancellable
,
266 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (initable
);
268 gchar
*name_owner
= NULL
;
272 nm
->priv
->available
= FALSE
;
273 nm
->priv
->metered
= FALSE
;
274 nm
->priv
->connectivity
= G_NETWORK_CONNECTIVITY_LOCAL
;
276 if (!glib_should_use_portal ())
278 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
, "Not using portals");
282 proxy
= g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION
,
283 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START
284 | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES
,
286 "org.freedesktop.portal.Desktop",
287 "/org/freedesktop/portal/desktop",
288 "org.freedesktop.portal.NetworkMonitor",
294 name_owner
= g_dbus_proxy_get_name_owner (proxy
);
298 g_object_unref (proxy
);
301 G_DBUS_ERROR_NAME_HAS_NO_OWNER
,
302 "Desktop portal not found");
308 ret
= g_dbus_proxy_get_cached_property (proxy
, "version");
309 g_variant_get (ret
, "u", &version
);
310 g_variant_unref (ret
);
312 if (version
!= 1 && version
!= 2)
314 g_object_unref (proxy
);
317 G_DBUS_ERROR_NAME_HAS_NO_OWNER
,
318 "NetworkMonitor portal unsupported version: %d", version
);
322 g_signal_connect (proxy
, "g-signal", G_CALLBACK (proxy_signal
), nm
);
323 g_signal_connect (proxy
, "g-properties-changed", G_CALLBACK (proxy_properties_changed
), nm
);
325 nm
->priv
->proxy
= proxy
;
326 nm
->priv
->has_network
= glib_network_available_in_sandbox ();
327 nm
->priv
->version
= version
;
329 return initable_parent_iface
->init (initable
, cancellable
, error
);
333 g_network_monitor_portal_finalize (GObject
*object
)
335 GNetworkMonitorPortal
*nm
= G_NETWORK_MONITOR_PORTAL (object
);
337 g_clear_object (&nm
->priv
->proxy
);
339 G_OBJECT_CLASS (g_network_monitor_portal_parent_class
)->finalize (object
);
343 g_network_monitor_portal_class_init (GNetworkMonitorPortalClass
*class)
345 GObjectClass
*gobject_class
= G_OBJECT_CLASS (class);
347 gobject_class
->finalize
= g_network_monitor_portal_finalize
;
348 gobject_class
->get_property
= g_network_monitor_portal_get_property
;
350 g_object_class_override_property (gobject_class
, PROP_NETWORK_AVAILABLE
, "network-available");
351 g_object_class_override_property (gobject_class
, PROP_NETWORK_METERED
, "network-metered");
352 g_object_class_override_property (gobject_class
, PROP_CONNECTIVITY
, "connectivity");
356 g_network_monitor_portal_iface_init (GNetworkMonitorInterface
*monitor_iface
)
361 g_network_monitor_portal_initable_iface_init (GInitableIface
*iface
)
363 initable_parent_iface
= g_type_interface_peek_parent (iface
);
365 iface
->init
= g_network_monitor_portal_initable_init
;