Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-fdo-session"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <libpeas.h>
9 : : #include <valent.h>
10 : :
11 : : #include "valent-fdo-session.h"
12 : :
13 : :
14 : : struct _ValentFdoSession
15 : : {
16 : : ValentSessionAdapter parent_instance;
17 : :
18 : : GDBusProxy *proxy;
19 : :
20 : : gboolean active;
21 : : gboolean locked;
22 : : };
23 : :
24 : : static void g_async_initable_iface_init (GAsyncInitableIface *iface);
25 : :
26 [ + + + - ]: 15 : G_DEFINE_FINAL_TYPE_WITH_CODE (ValentFdoSession, valent_fdo_session, VALENT_TYPE_SESSION_ADAPTER,
27 : : G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, g_async_initable_iface_init))
28 : :
29 : :
30 : : /*
31 : : * DBus Callbacks
32 : : */
33 : : static void
34 : 1 : on_properties_changed (GDBusProxy *proxy,
35 : : GVariant *changed_properties,
36 : : GStrv invalidated_properties,
37 : : ValentFdoSession *self)
38 : : {
39 [ + - ]: 1 : g_assert (VALENT_IS_FDO_SESSION (self));
40 : :
41 [ + - ]: 1 : if (!g_variant_lookup (changed_properties, "Active", "b", &self->active))
42 : : return;
43 : :
44 : 1 : g_object_notify (G_OBJECT (self), "active");
45 : : }
46 : :
47 : : static void
48 : 1 : on_signal (GDBusProxy *proxy,
49 : : const char *sender_name,
50 : : const char *signal_name,
51 : : GVariant *parameters,
52 : : ValentFdoSession *self)
53 : : {
54 [ + - ]: 1 : g_assert (VALENT_IS_FDO_SESSION (self));
55 : :
56 [ + - ]: 1 : if (g_strcmp0 (signal_name, "Lock") == 0)
57 : 1 : self->locked = TRUE;
58 [ # # ]: 0 : else if (g_strcmp0 (signal_name, "Unlock") == 0)
59 : 0 : self->locked = FALSE;
60 : :
61 : 1 : g_object_notify (G_OBJECT (self), "locked");
62 : 1 : }
63 : :
64 : : /*
65 : : * ValentSessionAdapter
66 : : */
67 : : static gboolean
68 : 2 : valent_fdo_session_get_active (ValentSessionAdapter *adapter)
69 : : {
70 : 2 : ValentFdoSession *self = VALENT_FDO_SESSION (adapter);
71 : :
72 [ + - ]: 2 : g_assert (VALENT_IS_FDO_SESSION (self));
73 : :
74 : 2 : return self->active;
75 : : }
76 : :
77 : : static gboolean
78 : 2 : valent_fdo_session_get_locked (ValentSessionAdapter *adapter)
79 : : {
80 : 2 : ValentFdoSession *self = VALENT_FDO_SESSION (adapter);
81 : :
82 [ + - ]: 2 : g_assert (VALENT_IS_FDO_SESSION (self));
83 : :
84 : 2 : return self->locked;
85 : : }
86 : :
87 : : static void
88 : 1 : valent_fdo_session_set_locked (ValentSessionAdapter *adapter,
89 : : gboolean state)
90 : : {
91 : 1 : ValentFdoSession *self = VALENT_FDO_SESSION (adapter);
92 : :
93 [ + - ]: 1 : g_assert (VALENT_IS_FDO_SESSION (self));
94 [ + - + - : 1 : g_return_if_fail (G_IS_DBUS_PROXY (self->proxy));
- + - - ]
95 : :
96 [ - + ]: 1 : g_dbus_proxy_call (self->proxy,
97 : : state ? "Lock" : "Unlock",
98 : : NULL,
99 : : G_DBUS_CALL_FLAGS_NONE,
100 : : -1,
101 : : NULL,
102 : : NULL,
103 : : NULL);
104 : : }
105 : :
106 : : static void
107 : 1 : new_session_cb (GObject *object,
108 : : GAsyncResult *result,
109 : : gpointer user_data)
110 : : {
111 : 1 : g_autoptr (GTask) task = G_TASK (user_data);
112 : 1 : ValentFdoSession *self = g_task_get_source_object (task);
113 : 1 : g_autoptr (GVariant) active = NULL;
114 [ + - ]: 1 : g_autoptr (GVariant) locked = NULL;
115 [ + - ]: 1 : g_autoptr (GError) error = NULL;
116 : :
117 [ + - + - : 1 : g_assert (G_IS_TASK (task));
- + - - ]
118 [ - + ]: 1 : g_assert (VALENT_IS_FDO_SESSION (self));
119 : :
120 : 1 : self->proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
121 : :
122 [ - + ]: 1 : if (self->proxy == NULL)
123 : : {
124 : 0 : valent_extension_plugin_state_changed (VALENT_EXTENSION (self),
125 : : VALENT_PLUGIN_STATE_ERROR,
126 : : error);
127 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
128 : : }
129 : :
130 : : /* Preload properties */
131 : 1 : active = g_dbus_proxy_get_cached_property (self->proxy, "Active");
132 : :
133 [ + - ]: 1 : if (active != NULL)
134 : 1 : self->active = g_variant_get_boolean (active);
135 : :
136 : 1 : locked = g_dbus_proxy_get_cached_property (self->proxy, "LockedHint");
137 : :
138 [ + - ]: 1 : if (locked != NULL)
139 : 1 : self->locked = g_variant_get_boolean (locked);
140 : :
141 : : /* Watch for changes */
142 : 1 : g_signal_connect_object (self->proxy,
143 : : "g-properties-changed",
144 : : G_CALLBACK (on_properties_changed),
145 : : self, 0);
146 : :
147 : 1 : g_signal_connect_object (self->proxy,
148 : : "g-signal",
149 : : G_CALLBACK (on_signal),
150 : : self, 0);
151 : :
152 : :
153 : : /* Report the adapter as active */
154 : 1 : valent_extension_plugin_state_changed (VALENT_EXTENSION (self),
155 : : VALENT_PLUGIN_STATE_ACTIVE,
156 : : NULL);
157 [ - + ]: 1 : g_task_return_boolean (task, TRUE);
158 : : }
159 : :
160 : : static void
161 : 1 : get_display_cb (GDBusConnection *connection,
162 : : GAsyncResult *result,
163 : : gpointer user_data)
164 : : {
165 : 1 : g_autoptr (GTask) task = G_TASK (user_data);
166 : 1 : ValentFdoSession *self = g_task_get_source_object (task);
167 : 1 : g_autoptr (GError) error = NULL;
168 [ - + ]: 1 : g_autoptr (GVariant) reply = NULL;
169 [ - - ]: 1 : g_autoptr (GVariant) value = NULL;
170 : 1 : const char *session_id, *object_path;
171 : :
172 [ + - + - : 1 : g_assert (G_IS_TASK (task));
- + - - ]
173 : :
174 : 1 : reply = g_dbus_connection_call_finish (connection, result, &error);
175 : :
176 [ - + ]: 1 : if (reply == NULL)
177 : : {
178 : 0 : valent_extension_plugin_state_changed (VALENT_EXTENSION (self),
179 : : VALENT_PLUGIN_STATE_ERROR,
180 : : error);
181 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
182 : : }
183 : :
184 : 1 : g_variant_get (reply, "(v)", &value);
185 : 1 : g_variant_get (value, "(&s&o)", &session_id, &object_path);
186 [ + - ]: 1 : g_dbus_proxy_new (connection,
187 : : G_DBUS_PROXY_FLAGS_NONE,
188 : : NULL,
189 : : "org.freedesktop.login1",
190 : : object_path,
191 : : "org.freedesktop.login1.Session",
192 : : g_task_get_cancellable (task),
193 : : (GAsyncReadyCallback)new_session_cb,
194 : : g_object_ref (task));
195 : : }
196 : :
197 : : static void
198 : 1 : get_user_cb (GDBusConnection *connection,
199 : : GAsyncResult *result,
200 : : gpointer user_data)
201 : : {
202 : 1 : g_autoptr (GTask) task = G_TASK (user_data);
203 : 1 : ValentFdoSession *self = g_task_get_source_object (task);
204 : 1 : g_autoptr (GError) error = NULL;
205 [ - - - + ]: 1 : g_autoptr (GVariant) reply = NULL;
206 : 1 : const char *object_path;
207 : :
208 [ + - + - : 1 : g_assert (G_IS_TASK (task));
- + - - ]
209 : :
210 : 1 : reply = g_dbus_connection_call_finish (connection, result, &error);
211 : :
212 [ - + ]: 1 : if (reply == NULL)
213 : : {
214 : 0 : valent_extension_plugin_state_changed (VALENT_EXTENSION (self),
215 : : VALENT_PLUGIN_STATE_ERROR,
216 : : error);
217 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
218 : : }
219 : :
220 : 1 : g_variant_get (reply, "(&o)", &object_path);
221 : 1 : g_dbus_connection_call (connection,
222 : : "org.freedesktop.login1",
223 : : object_path,
224 : : "org.freedesktop.DBus.Properties",
225 : : "Get",
226 : : g_variant_new ("(ss)",
227 : : "org.freedesktop.login1.User",
228 : : "Display"),
229 : : G_VARIANT_TYPE ("(v)"),
230 : : G_DBUS_CALL_FLAGS_NONE,
231 : : -1,
232 : : g_task_get_cancellable (task),
233 : : (GAsyncReadyCallback)get_display_cb,
234 : : g_object_ref (task));
235 : : }
236 : :
237 : : /*
238 : : * GAsyncInitable
239 : : */
240 : : static void
241 : 1 : valent_fdo_notifications_init_async (GAsyncInitable *initable,
242 : : int io_priority,
243 : : GCancellable *cancellable,
244 : : GAsyncReadyCallback callback,
245 : : gpointer user_data)
246 : : {
247 : 1 : g_autoptr (GTask) task = NULL;
248 [ - - ]: 1 : g_autoptr (GCancellable) destroy = NULL;
249 [ - - + - ]: 1 : g_autoptr (GDBusConnection) connection = NULL;
250 [ - - ]: 1 : g_autoptr (GError) error = NULL;
251 : :
252 [ + - ]: 1 : g_assert (VALENT_IS_FDO_SESSION (initable));
253 : :
254 : : /* Cede the primary position until complete */
255 : 1 : valent_extension_plugin_state_changed (VALENT_EXTENSION (initable),
256 : : VALENT_PLUGIN_STATE_INACTIVE,
257 : : NULL);
258 : :
259 : : /* Cancel initialization if the object is destroyed */
260 : 1 : destroy = valent_object_chain_cancellable (VALENT_OBJECT (initable),
261 : : cancellable);
262 : :
263 : 1 : task = g_task_new (initable, destroy, callback, user_data);
264 : 1 : g_task_set_priority (task, io_priority);
265 [ + - ]: 1 : g_task_set_source_tag (task, valent_fdo_notifications_init_async);
266 : :
267 : : /* Get a bus address */
268 : 1 : connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, destroy, &error);
269 : :
270 [ - + ]: 1 : if (connection == NULL)
271 : : {
272 : 0 : valent_extension_plugin_state_changed (VALENT_EXTENSION (initable),
273 : : VALENT_PLUGIN_STATE_ERROR,
274 : : error);
275 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
276 : : }
277 : :
278 : : /* Check for logind */
279 [ - + ]: 1 : g_dbus_connection_call (connection,
280 : : "org.freedesktop.login1",
281 : : "/org/freedesktop/login1",
282 : : "org.freedesktop.login1.Manager",
283 : : "GetUser",
284 : : g_variant_new ("(u)", geteuid ()),
285 : : G_VARIANT_TYPE ("(o)"),
286 : : G_DBUS_CALL_FLAGS_NONE,
287 : : -1,
288 : : destroy,
289 : : (GAsyncReadyCallback)get_user_cb,
290 : : g_steal_pointer (&task));
291 : : }
292 : :
293 : : static void
294 : 2 : g_async_initable_iface_init (GAsyncInitableIface *iface)
295 : : {
296 : 2 : iface->init_async = valent_fdo_notifications_init_async;
297 : 2 : }
298 : :
299 : : /*
300 : : * ValentObject
301 : : */
302 : : static void
303 : 1 : valent_fdo_session_destroy (ValentObject *object)
304 : : {
305 : 1 : ValentFdoSession *self = VALENT_FDO_SESSION (object);
306 : :
307 [ + - ]: 1 : g_clear_object (&self->proxy);
308 : :
309 : 1 : VALENT_OBJECT_CLASS (valent_fdo_session_parent_class)->destroy (object);
310 : 1 : }
311 : :
312 : : /*
313 : : * GObject
314 : : */
315 : : static void
316 : 2 : valent_fdo_session_class_init (ValentFdoSessionClass *klass)
317 : : {
318 : 2 : ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
319 : 2 : ValentSessionAdapterClass *session_class = VALENT_SESSION_ADAPTER_CLASS (klass);
320 : :
321 : 2 : vobject_class->destroy = valent_fdo_session_destroy;
322 : :
323 : 2 : session_class->get_active = valent_fdo_session_get_active;
324 : 2 : session_class->get_locked = valent_fdo_session_get_locked;
325 : 2 : session_class->set_locked = valent_fdo_session_set_locked;
326 : : }
327 : :
328 : : static void
329 : 1 : valent_fdo_session_init (ValentFdoSession *self)
330 : : {
331 : 1 : }
332 : :
|