1 | /* GIO - GLib Input, Output and Streaming Library |
2 | * |
3 | * Copyright 2019 Red Hat, Inc. |
4 | * |
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. |
9 | * |
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. |
14 | * |
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/>. |
17 | */ |
18 | |
19 | #include "config.h" |
20 | |
21 | #include "gmemorymonitor.h" |
22 | #include "gmemorymonitorportal.h" |
23 | #include "ginitable.h" |
24 | #include "giomodule-priv.h" |
25 | #include "xdp-dbus.h" |
26 | #include "gportalsupport.h" |
27 | |
28 | #define G_MEMORY_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) |
29 | |
30 | static void g_memory_monitor_portal_iface_init (GMemoryMonitorInterface *iface); |
31 | static void g_memory_monitor_portal_initable_iface_init (GInitableIface *iface); |
32 | |
33 | struct _GMemoryMonitorPortal |
34 | { |
35 | GObject parent_instance; |
36 | |
37 | GDBusProxy *proxy; |
38 | gulong signal_id; |
39 | }; |
40 | |
41 | G_DEFINE_TYPE_WITH_CODE (GMemoryMonitorPortal, g_memory_monitor_portal, G_TYPE_OBJECT, |
42 | G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, |
43 | g_memory_monitor_portal_initable_iface_init) |
44 | G_IMPLEMENT_INTERFACE (G_TYPE_MEMORY_MONITOR, |
45 | g_memory_monitor_portal_iface_init) |
46 | _g_io_modules_ensure_extension_points_registered (); |
47 | g_io_extension_point_implement (G_MEMORY_MONITOR_EXTENSION_POINT_NAME, |
48 | g_define_type_id, |
49 | "portal" , |
50 | 40)) |
51 | |
52 | static void |
53 | g_memory_monitor_portal_init (GMemoryMonitorPortal *portal) |
54 | { |
55 | } |
56 | |
57 | static void |
58 | proxy_signal (GDBusProxy *proxy, |
59 | const char *sender, |
60 | const char *signal, |
61 | GVariant *parameters, |
62 | GMemoryMonitorPortal *portal) |
63 | { |
64 | guint8 level; |
65 | |
66 | if (strcmp (s1: signal, s2: "LowMemoryWarning" ) != 0) |
67 | return; |
68 | if (!parameters) |
69 | return; |
70 | |
71 | g_variant_get (value: parameters, format_string: "(y)" , &level); |
72 | g_signal_emit_by_name (instance: portal, detailed_signal: "low-memory-warning" , level); |
73 | } |
74 | |
75 | static gboolean |
76 | g_memory_monitor_portal_initable_init (GInitable *initable, |
77 | GCancellable *cancellable, |
78 | GError **error) |
79 | { |
80 | GMemoryMonitorPortal *portal = G_MEMORY_MONITOR_PORTAL (ptr: initable); |
81 | GDBusProxy *proxy; |
82 | gchar *name_owner = NULL; |
83 | |
84 | if (!glib_should_use_portal ()) |
85 | { |
86 | g_set_error (err: error, domain: G_IO_ERROR, code: G_IO_ERROR_FAILED, format: "Not using portals" ); |
87 | return FALSE; |
88 | } |
89 | |
90 | proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, |
91 | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, |
92 | NULL, |
93 | "org.freedesktop.portal.Desktop" , |
94 | "/org/freedesktop/portal/desktop" , |
95 | "org.freedesktop.portal.MemoryMonitor" , |
96 | cancellable, |
97 | error); |
98 | if (!proxy) |
99 | return FALSE; |
100 | |
101 | name_owner = g_dbus_proxy_get_name_owner (proxy); |
102 | |
103 | if (name_owner == NULL) |
104 | { |
105 | g_object_unref (object: proxy); |
106 | g_set_error (err: error, |
107 | domain: G_DBUS_ERROR, |
108 | code: G_DBUS_ERROR_NAME_HAS_NO_OWNER, |
109 | format: "Desktop portal not found" ); |
110 | return FALSE; |
111 | } |
112 | |
113 | g_free (mem: name_owner); |
114 | |
115 | portal->signal_id = g_signal_connect (proxy, "g-signal" , |
116 | G_CALLBACK (proxy_signal), portal); |
117 | |
118 | portal->proxy = proxy; |
119 | |
120 | return TRUE; |
121 | } |
122 | |
123 | static void |
124 | g_memory_monitor_portal_finalize (GObject *object) |
125 | { |
126 | GMemoryMonitorPortal *portal = G_MEMORY_MONITOR_PORTAL (ptr: object); |
127 | |
128 | if (portal->proxy != NULL) |
129 | g_clear_signal_handler (&portal->signal_id, portal->proxy); |
130 | g_clear_object (&portal->proxy); |
131 | |
132 | G_OBJECT_CLASS (g_memory_monitor_portal_parent_class)->finalize (object); |
133 | } |
134 | |
135 | static void |
136 | g_memory_monitor_portal_class_init (GMemoryMonitorPortalClass *nl_class) |
137 | { |
138 | GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); |
139 | |
140 | gobject_class->finalize = g_memory_monitor_portal_finalize; |
141 | } |
142 | |
143 | static void |
144 | g_memory_monitor_portal_iface_init (GMemoryMonitorInterface *monitor_iface) |
145 | { |
146 | } |
147 | |
148 | static void |
149 | g_memory_monitor_portal_initable_iface_init (GInitableIface *iface) |
150 | { |
151 | iface->init = g_memory_monitor_portal_initable_init; |
152 | } |
153 | |