GCC Code Coverage Report


Directory: ./
File: panels/privacy/bolt/bolt-proxy.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 204 0.0%
Functions: 0 23 0.0%
Branches: 0 123 0.0%

Line Branch Exec Source
1 /*
2 * Copyright © 2017 Red Hat, Inc
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors:
18 * Christian J. Kellner <christian@kellner.me>
19 */
20
21 #include "bolt-proxy.h"
22
23 #include "bolt-enums.h"
24 #include "bolt-error.h"
25 #include "bolt-names.h"
26 #include "bolt-str.h"
27
28 static void bolt_proxy_handle_props_changed (GDBusProxy *proxy,
29 GVariant *changed_properties,
30 GStrv invalidated_properties,
31 gpointer user_data);
32
33 static void bolt_proxy_handle_dbus_signal (GDBusProxy *proxy,
34 const gchar *sender_name,
35 const gchar *signal_name,
36 GVariant *params,
37 gpointer user_data);
38
39 G_DEFINE_TYPE (BoltProxy, bolt_proxy, G_TYPE_DBUS_PROXY);
40
41
42 static void
43 bolt_proxy_constructed (GObject *object)
44 {
45 G_OBJECT_CLASS (bolt_proxy_parent_class)->constructed (object);
46
47 g_signal_connect (object, "g-properties-changed",
48 G_CALLBACK (bolt_proxy_handle_props_changed), object);
49
50 g_signal_connect (object, "g-signal",
51 G_CALLBACK (bolt_proxy_handle_dbus_signal), object);
52 }
53
54 static const BoltProxySignal *
55 bolt_proxy_get_dbus_signals (guint *n)
56 {
57 *n = 0;
58 return NULL;
59 }
60
61 static void
62 bolt_proxy_class_init (BoltProxyClass *klass)
63 {
64 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
65
66 gobject_class->constructed = bolt_proxy_constructed;
67
68 klass->get_dbus_signals = bolt_proxy_get_dbus_signals;
69
70 }
71
72 static void
73 bolt_proxy_init (BoltProxy *object)
74 {
75 }
76
77 static void
78 bolt_proxy_handle_props_changed (GDBusProxy *proxy,
79 GVariant *changed_properties,
80 GStrv invalidated_properties,
81 gpointer user_data)
82 {
83 g_autoptr(GVariantIter) iter = NULL;
84 gboolean handled;
85 GParamSpec **pp;
86 const char *key;
87 guint n;
88
89 pp = g_object_class_list_properties (G_OBJECT_GET_CLASS (proxy), &n);
90
91 g_variant_get (changed_properties, "a{sv}", &iter);
92 while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
93 {
94 handled = FALSE;
95 for (guint i = 0; !handled && i < n; i++)
96 {
97 GParamSpec *pspec = pp[i];
98 const char *nick;
99 const char *name;
100
101 nick = g_param_spec_get_nick (pspec);
102 name = g_param_spec_get_name (pspec);
103
104 handled = bolt_streq (nick, key);
105
106 if (handled)
107 g_object_notify (G_OBJECT (user_data), name);
108 }
109 }
110
111 g_free (pp);
112 }
113
114 static void
115 bolt_proxy_handle_dbus_signal (GDBusProxy *proxy,
116 const gchar *sender_name,
117 const gchar *signal_name,
118 GVariant *params,
119 gpointer user_data)
120 {
121 const BoltProxySignal *ps;
122 guint n;
123
124 if (signal_name == NULL)
125 return;
126
127 ps = BOLT_PROXY_GET_CLASS (proxy)->get_dbus_signals (&n);
128
129 for (guint i = 0; i < n; i++)
130 {
131 const BoltProxySignal *sig = &ps[i];
132
133 if (g_str_equal (sig->theirs, signal_name))
134 {
135 sig->handle (G_OBJECT (proxy), proxy, params);
136 break;
137 }
138 }
139
140 }
141
142 /* public methods */
143
144 gboolean
145 bolt_proxy_get_dbus_property (GObject *proxy,
146 GParamSpec *spec,
147 GValue *value)
148 {
149 g_autoptr(GVariant) val = NULL;
150 const GVariantType *vt;
151 gboolean handled = FALSE;
152 const char *nick;
153
154 nick = g_param_spec_get_nick (spec);
155 val = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), nick);
156
157 if (val == NULL)
158 return FALSE;
159
160 vt = g_variant_get_type (val);
161
162 if (g_variant_type_equal (vt, G_VARIANT_TYPE_STRING) &&
163 G_IS_PARAM_SPEC_ENUM (spec))
164 {
165 GParamSpecEnum *enum_spec = G_PARAM_SPEC_ENUM (spec);
166 GEnumValue *ev;
167 const char *str;
168
169 str = g_variant_get_string (val, NULL);
170 ev = g_enum_get_value_by_nick (enum_spec->enum_class, str);
171
172 handled = ev != NULL;
173
174 if (handled)
175 g_value_set_enum (value, ev->value);
176 else
177 g_value_set_enum (value, enum_spec->default_value);
178 }
179 else if (g_variant_type_equal (vt, G_VARIANT_TYPE_STRING) &&
180 G_IS_PARAM_SPEC_FLAGS (spec))
181 {
182 GParamSpecFlags *flags_spec = G_PARAM_SPEC_FLAGS (spec);
183 GFlagsClass *flags_class = flags_spec->flags_class;
184 const char *str;
185 guint v;
186
187 str = g_variant_get_string (val, NULL);
188 handled = bolt_flags_class_from_string (flags_class, str, &v, NULL);
189
190 if (handled)
191 g_value_set_flags (value, v);
192 else
193 g_value_set_flags (value, flags_spec->default_value);
194 }
195 else
196 {
197 g_dbus_gvariant_to_gvalue (val, value);
198 }
199
200 return handled;
201 }
202
203 gboolean
204 bolt_proxy_has_name_owner (BoltProxy *proxy)
205 {
206 const char *name_owner;
207
208 g_return_val_if_fail (proxy != NULL, FALSE);
209 g_return_val_if_fail (BOLT_IS_PROXY (proxy), FALSE);
210
211 name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
212
213 return name_owner != NULL;
214 }
215
216 static GParamSpec *
217 find_property (BoltProxy *proxy,
218 const char *name,
219 GError **error)
220 {
221 GParamSpec *res = NULL;
222 GParamSpec **pp;
223 guint n;
224
225 pp = g_object_class_list_properties (G_OBJECT_GET_CLASS (proxy), &n);
226
227 for (guint i = 0; i < n; i++)
228 {
229 GParamSpec *pspec = pp[i];
230
231 if (bolt_streq (pspec->name, name))
232 {
233 res = pspec;
234 break;
235 }
236 }
237
238 if (pp == NULL)
239 g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_PROPERTY,
240 "could not find property '%s'", name);
241
242 g_free (pp);
243 return res;
244 }
245
246 static GVariant *
247 bolt_proxy_get_cached_property (BoltProxy *proxy,
248 const char *name)
249 {
250 const char *bus_name = NULL;
251 GParamSpec *pspec;
252 GVariant *var;
253
254 g_return_val_if_fail (BOLT_IS_PROXY (proxy), NULL);
255 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), name);
256
257 if (pspec == NULL)
258 return NULL;
259
260 bus_name = g_param_spec_get_nick (pspec);
261 var = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), bus_name);
262
263 return var;
264 }
265
266 gboolean
267 bolt_proxy_get_property_bool (BoltProxy *proxy,
268 const char *name,
269 gboolean *value)
270 {
271 g_autoptr(GVariant) var = NULL;
272
273 var = bolt_proxy_get_cached_property (proxy, name);
274
275 if (var == NULL)
276 return FALSE;
277 else if (value)
278 *value = g_variant_get_boolean (var);
279
280 return TRUE;
281 }
282
283 gboolean
284 bolt_proxy_get_property_enum (BoltProxy *proxy,
285 const char *name,
286 gint *value)
287 {
288 g_autoptr(GVariant) var = NULL;
289 const char *str = NULL;
290 const char *bus_name = NULL;
291 GParamSpec *pspec;
292 GEnumValue *ev;
293
294 g_return_val_if_fail (BOLT_IS_PROXY (proxy), FALSE);
295
296 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), name);
297
298 if (pspec == NULL)
299 return FALSE;
300
301 bus_name = g_param_spec_get_nick (pspec);
302 var = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), bus_name);
303 if (var == NULL)
304 return FALSE;
305
306 str = g_variant_get_string (var, NULL);
307
308 if (str == NULL)
309 return FALSE;
310
311 ev = g_enum_get_value_by_nick (G_PARAM_SPEC_ENUM (pspec)->enum_class, str);
312
313 if (ev == NULL)
314 return FALSE;
315
316 if (value)
317 *value = ev->value;
318
319 return TRUE;
320 }
321
322 gboolean
323 bolt_proxy_get_property_flags (BoltProxy *proxy,
324 const char *name,
325 guint *value)
326 {
327 g_autoptr(GVariant) var = NULL;
328 const char *str = NULL;
329 const char *bus_name = NULL;
330 GFlagsClass *flags_class;
331 GParamSpec *pspec;
332 guint v;
333 gboolean ok;
334
335 g_return_val_if_fail (BOLT_IS_PROXY (proxy), FALSE);
336
337 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), name);
338
339 if (pspec == NULL || !G_IS_PARAM_SPEC_FLAGS (pspec))
340 return FALSE;
341
342 bus_name = g_param_spec_get_nick (pspec);
343 var = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), bus_name);
344 if (var == NULL)
345 return FALSE;
346
347 str = g_variant_get_string (var, NULL);
348
349 if (str == NULL)
350 return FALSE;
351
352 flags_class = G_PARAM_SPEC_FLAGS (pspec)->flags_class;
353 ok = bolt_flags_class_from_string (flags_class, str, &v, NULL);
354
355 if (ok && value)
356 *value = v;
357
358 return ok;
359 }
360
361 gboolean
362 bolt_proxy_get_property_uint32 (BoltProxy *proxy,
363 const char *name,
364 guint *value)
365 {
366 g_autoptr(GVariant) var = NULL;
367
368 var = bolt_proxy_get_cached_property (proxy, name);
369
370 if (var == NULL)
371 return FALSE;
372 else if (value)
373 *value = g_variant_get_uint32 (var);
374
375 return TRUE;
376 }
377
378 gboolean
379 bolt_proxy_get_property_int64 (BoltProxy *proxy,
380 const char *name,
381 gint64 *value)
382 {
383 g_autoptr(GVariant) var = NULL;
384
385 var = bolt_proxy_get_cached_property (proxy, name);
386
387 if (var == NULL)
388 return FALSE;
389 else if (value)
390 *value = g_variant_get_int64 (var);
391
392 return TRUE;
393 }
394
395 gboolean
396 bolt_proxy_get_property_uint64 (BoltProxy *proxy,
397 const char *name,
398 guint64 *value)
399 {
400 g_autoptr(GVariant) var = NULL;
401
402 var = bolt_proxy_get_cached_property (proxy, name);
403
404 if (var == NULL)
405 return FALSE;
406 else if (value)
407 *value = g_variant_get_uint64 (var);
408
409 return TRUE;
410 }
411
412 const char *
413 bolt_proxy_get_property_string (BoltProxy *proxy,
414 const char *name)
415 {
416 g_autoptr(GVariant) var = NULL;
417 const char *val = NULL;
418
419 var = bolt_proxy_get_cached_property (proxy, name);
420
421 if (var != NULL)
422 val = g_variant_get_string (var, NULL);
423
424 if (val && *val == '\0')
425 val = NULL;
426
427 return val;
428 }
429
430 gboolean
431 bolt_proxy_set_property (BoltProxy *proxy,
432 const char *name,
433 GVariant *value,
434 GCancellable *cancellable,
435 GError **error)
436 {
437 GParamSpec *pp;
438 const char *iface;
439 gboolean ok = FALSE;
440 GVariant *res;
441
442 pp = find_property (proxy, name, NULL);
443 if (pp != NULL)
444 name = g_param_spec_get_nick (pp);
445
446 iface = g_dbus_proxy_get_interface_name (G_DBUS_PROXY (proxy));
447
448 res = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
449 "org.freedesktop.DBus.Properties.Set",
450 g_variant_new ("(ssv)",
451 iface,
452 name,
453 value),
454 G_DBUS_CALL_FLAGS_NONE,
455 -1,
456 cancellable,
457 error);
458
459 if (res)
460 {
461 g_variant_unref (res);
462 ok = TRUE;
463 }
464
465 return ok;
466 }
467
468 void
469 bolt_proxy_set_property_async (BoltProxy *proxy,
470 const char *name,
471 GVariant *value,
472 GCancellable *cancellable,
473 GAsyncReadyCallback callback,
474 gpointer user_data)
475 {
476 GParamSpec *pp;
477 const char *iface;
478
479 pp = find_property (proxy, name, NULL);
480
481 if (pp != NULL)
482 name = g_param_spec_get_nick (pp);
483
484 iface = g_dbus_proxy_get_interface_name (G_DBUS_PROXY (proxy));
485
486 g_dbus_proxy_call (G_DBUS_PROXY (proxy),
487 "org.freedesktop.DBus.Properties.Set",
488 g_variant_new ("(ssv)",
489 iface,
490 name,
491 value),
492 G_DBUS_CALL_FLAGS_NONE,
493 -1,
494 cancellable,
495 callback,
496 user_data);
497 }
498
499 gboolean
500 bolt_proxy_set_property_finish (GAsyncResult *res,
501 GError **error)
502 {
503 BoltProxy *proxy;
504 GVariant *val = NULL;
505
506 proxy = (BoltProxy *) g_async_result_get_source_object (res);
507 val = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
508
509 if (val == NULL)
510 return FALSE;
511
512 g_variant_unref (val);
513 return TRUE;
514 }
515