blob: e26e4320d9e20ea9de30fcc919937d4273961e4c [file] [log] [blame]
Richard Hughesb333e002021-04-01 10:40:02 +01001/*
2 * Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1+
5 */
6
7#define G_LOG_DOMAIN "FuContext"
8
9#include "config.h"
10
Richard Hughesb333e002021-04-01 10:40:02 +010011#include "fu-context-private.h"
12#include "fu-hwids.h"
13#include "fu-smbios-private.h"
14
15/**
16 * SECTION:fu-context
17 * @short_description: a context shared between all the plugins and the daemon
18 *
19 * An object that represents the shared system state. This object is shared
20 * between the engine, the plugins and the devices.
21 */
22
23typedef struct {
24 FuHwids *hwids;
25 FuSmbios *smbios;
26 FuQuirks *quirks;
27 GHashTable *runtime_versions;
28 GHashTable *compile_versions;
29 GPtrArray *udev_subsystems;
30 GHashTable *firmware_gtypes;
Richard Hughes4d76d182021-04-06 13:35:15 +010031 FuBatteryState battery_state;
32 guint battery_level;
33 guint battery_threshold;
Richard Hughesb333e002021-04-01 10:40:02 +010034} FuContextPrivate;
35
36enum {
37 SIGNAL_SECURITY_CHANGED,
38 SIGNAL_LAST
39};
40
Richard Hughes4d76d182021-04-06 13:35:15 +010041enum {
42 PROP_0,
43 PROP_BATTERY_STATE,
44 PROP_BATTERY_LEVEL,
45 PROP_BATTERY_THRESHOLD,
46 PROP_LAST
47};
48
Richard Hughesb333e002021-04-01 10:40:02 +010049static guint signals[SIGNAL_LAST] = { 0 };
50
51G_DEFINE_TYPE_WITH_PRIVATE (FuContext, fu_context, G_TYPE_OBJECT)
52
53#define GET_PRIVATE(o) (fu_context_get_instance_private (o))
54
55/**
56 * fu_context_get_smbios_string:
57 * @self: A #FuContext
58 * @structure_type: A SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
59 * @offset: A SMBIOS offset
60 *
61 * Gets a hardware SMBIOS string.
62 *
63 * The @type and @offset can be referenced from the DMTF SMBIOS specification:
64 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
65 *
66 * Returns: A string, or %NULL
67 *
68 * Since: 1.6.0
69 **/
70const gchar *
71fu_context_get_smbios_string (FuContext *self, guint8 structure_type, guint8 offset)
72{
73 FuContextPrivate *priv = GET_PRIVATE (self);
74 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
75 return fu_smbios_get_string (priv->smbios, structure_type, offset, NULL);
76}
77
78/**
79 * fu_context_get_smbios_data:
80 * @self: A #FuContext
81 * @structure_type: A SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
82 *
83 * Gets a hardware SMBIOS data.
84 *
85 * Returns: (transfer full): A #GBytes, or %NULL
86 *
87 * Since: 1.6.0
88 **/
89GBytes *
90fu_context_get_smbios_data (FuContext *self, guint8 structure_type)
91{
92 FuContextPrivate *priv = GET_PRIVATE (self);
93 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
94 return fu_smbios_get_data (priv->smbios, structure_type, NULL);
95}
96
97/**
98 * fu_context_get_smbios_integer:
99 * @self: A #FuContext
100 * @type: A structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
101 * @offset: A structure offset
102 *
103 * Reads an integer value from the SMBIOS string table of a specific structure.
104 *
105 * The @type and @offset can be referenced from the DMTF SMBIOS specification:
106 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
107 *
108 * Returns: an integer, or %G_MAXUINT if invalid or not found
109 *
110 * Since: 1.6.0
111 **/
112guint
113fu_context_get_smbios_integer (FuContext *self, guint8 type, guint8 offset)
114{
115 FuContextPrivate *priv = GET_PRIVATE (self);
116 g_return_val_if_fail (FU_IS_CONTEXT (self), G_MAXUINT);
117 return fu_smbios_get_integer (priv->smbios, type, offset, NULL);
118}
119
120/**
121 * fu_context_has_hwid_guid:
122 * @self: A #FuContext
123 * @guid: A GUID, e.g. `059eb22d-6dc7-59af-abd3-94bbe017f67c`
124 *
125 * Finds out if a hardware GUID exists.
126 *
127 * Returns: %TRUE if the GUID exists
128 *
129 * Since: 1.6.0
130 **/
131gboolean
132fu_context_has_hwid_guid (FuContext *self, const gchar *guid)
133{
134 FuContextPrivate *priv = GET_PRIVATE (self);
135 g_return_val_if_fail (FU_IS_CONTEXT (self), FALSE);
136 return fu_hwids_has_guid (priv->hwids, guid);
137}
138
139/**
140 * fu_context_get_hwid_guids:
141 * @self: A #FuContext
142 *
143 * Returns all the HWIDs defined in the system. All hardware IDs on a
144 * specific system can be shown using the `fwupdmgr hwids` command.
145 *
146 * Returns: (transfer none) (element-type utf8): An array of GUIDs
147 *
148 * Since: 1.6.0
149 **/
150GPtrArray *
151fu_context_get_hwid_guids (FuContext *self)
152{
153 FuContextPrivate *priv = GET_PRIVATE (self);
154 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
155 return fu_hwids_get_guids (priv->hwids);
156}
157
158/**
159 * fu_context_get_hwid_value:
160 * @self: A #FuContext
161 * @key: A DMI ID, e.g. `BiosVersion`
162 *
163 * Gets the cached value for one specific key that is valid ASCII and suitable
164 * for display.
165 *
166 * Returns: the string, e.g. `1.2.3`, or %NULL if not found
167 *
168 * Since: 1.6.0
169 **/
170const gchar *
171fu_context_get_hwid_value (FuContext *self, const gchar *key)
172{
173 FuContextPrivate *priv = GET_PRIVATE (self);
174 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
175 g_return_val_if_fail (key != NULL, NULL);
176 return fu_hwids_get_value (priv->hwids, key);
177}
178
179/**
180 * fu_context_get_hwid_replace_value:
181 * @self: A #FuContext
182 * @keys: A key, e.g. `HardwareID-3` or %FU_HWIDS_KEY_PRODUCT_SKU
183 * @error: A #GError or %NULL
184 *
185 * Gets the replacement value for a specific key. All hardware IDs on a
186 * specific system can be shown using the `fwupdmgr hwids` command.
187 *
188 * Returns: (transfer full): a string, or %NULL for error.
189 *
190 * Since: 1.6.0
191 **/
192gchar *
193fu_context_get_hwid_replace_value (FuContext *self, const gchar *keys, GError **error)
194{
195 FuContextPrivate *priv = GET_PRIVATE (self);
196 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
197 g_return_val_if_fail (keys != NULL, NULL);
198 return fu_hwids_get_replace_values (priv->hwids, keys, error);
199}
200
201/**
202 * fu_context_add_runtime_version:
203 * @self: A #FuContext
204 * @component_id: An AppStream component id, e.g. "org.gnome.Software"
205 * @version: A version string, e.g. "1.2.3"
206 *
207 * Sets a runtime version of a specific dependency.
208 *
209 * Since: 1.6.0
210 **/
211void
212fu_context_add_runtime_version (FuContext *self,
213 const gchar *component_id,
214 const gchar *version)
215{
216 FuContextPrivate *priv = GET_PRIVATE (self);
217
218 g_return_if_fail (FU_IS_CONTEXT (self));
219 g_return_if_fail (component_id != NULL);
220 g_return_if_fail (version != NULL);
221
222 if (priv->runtime_versions == NULL)
223 return;
224 g_hash_table_insert (priv->runtime_versions,
225 g_strdup (component_id),
226 g_strdup (version));
227}
228
229/**
230 * fu_context_set_runtime_versions:
231 * @self: A #FuContext
232 * @runtime_versions: A #GHashTables
233 *
234 * Sets the runtime versions for a plugin
235 *
236 * Since: 1.6.0
237 **/
238void
239fu_context_set_runtime_versions (FuContext *self, GHashTable *runtime_versions)
240{
241 FuContextPrivate *priv = GET_PRIVATE (self);
242 g_return_if_fail (FU_IS_CONTEXT (self));
243 g_return_if_fail (runtime_versions != NULL);
244 priv->runtime_versions = g_hash_table_ref (runtime_versions);
245}
246
247/**
248 * fu_context_add_compile_version:
249 * @self: A #FuContext
250 * @component_id: An AppStream component id, e.g. "org.gnome.Software"
251 * @version: A version string, e.g. "1.2.3"
252 *
253 * Sets a compile-time version of a specific dependency.
254 *
255 * Since: 1.6.0
256 **/
257void
258fu_context_add_compile_version (FuContext *self,
259 const gchar *component_id,
260 const gchar *version)
261{
262 FuContextPrivate *priv = GET_PRIVATE (self);
263
264 g_return_if_fail (FU_IS_CONTEXT (self));
265 g_return_if_fail (component_id != NULL);
266 g_return_if_fail (version != NULL);
267
268 if (priv->compile_versions == NULL)
269 return;
270 g_hash_table_insert (priv->compile_versions,
271 g_strdup (component_id),
272 g_strdup (version));
273}
274
275/**
276 * fu_context_set_compile_versions:
277 * @self: A #FuContext
278 * @compile_versions: A #GHashTables
279 *
280 * Sets the compile time versions for a plugin
281 *
282 * Since: 1.6.0
283 **/
284void
285fu_context_set_compile_versions (FuContext *self, GHashTable *compile_versions)
286{
287 FuContextPrivate *priv = GET_PRIVATE (self);
288 g_return_if_fail (FU_IS_CONTEXT (self));
289 g_return_if_fail (compile_versions != NULL);
290 priv->compile_versions = g_hash_table_ref (compile_versions);
291}
292
293/**
294 * fu_context_add_udev_subsystem:
295 * @self: a #FuContext
296 * @subsystem: a subsystem name, e.g. `pciport`
297 *
298 * Registers the udev subsystem to be watched by the daemon.
299 *
300 * Plugins can use this method only in fu_plugin_init()
301 *
302 * Since: 1.6.0
303 **/
304void
305fu_context_add_udev_subsystem (FuContext *self, const gchar *subsystem)
306{
307 FuContextPrivate *priv = GET_PRIVATE (self);
308
309 g_return_if_fail (FU_IS_CONTEXT (self));
310 g_return_if_fail (subsystem != NULL);
311
312 for (guint i = 0; i < priv->udev_subsystems->len; i++) {
313 const gchar *subsystem_tmp = g_ptr_array_index (priv->udev_subsystems, i);
314 if (g_strcmp0 (subsystem_tmp, subsystem) == 0)
315 return;
316 }
317 g_debug ("added udev subsystem watch of %s", subsystem);
318 g_ptr_array_add (priv->udev_subsystems, g_strdup (subsystem));
319}
320
321/**
322 * fu_context_get_udev_subsystems:
323 * @self: A #FuContext
324 *
325 * Gets the udev subsystems required by all plugins.
326 *
327 * Returns: (transfer none) (element-type utf8): List of subsystems
328 *
329 * Since: 1.6.0
330 **/
331GPtrArray *
332fu_context_get_udev_subsystems (FuContext *self)
333{
334 FuContextPrivate *priv = GET_PRIVATE (self);
335 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
336 return priv->udev_subsystems;
337}
338
339/**
340 * fu_context_add_firmware_gtype:
341 * @self: a #FuContext
342 * @id: (nullable): An optional string describing the type, e.g. "ihex"
343 * @gtype: a #GType e.g. `FU_TYPE_FOO_FIRMWARE`
344 *
345 * Adds a firmware #GType which is used when creating devices. If @id is not
346 * specified then it is guessed using the #GType name.
347 *
348 * Plugins can use this method only in fu_plugin_init()
349 *
350 * Since: 1.6.0
351 **/
352void
353fu_context_add_firmware_gtype (FuContext *self, const gchar *id, GType gtype)
354{
355 FuContextPrivate *priv = GET_PRIVATE (self);
356 g_return_if_fail (FU_IS_CONTEXT (self));
357 g_return_if_fail (id != NULL);
358 g_return_if_fail (gtype != G_TYPE_INVALID);
Richard Hughes48f04722021-04-15 09:31:02 +0100359 g_type_ensure (gtype);
Richard Hughesb333e002021-04-01 10:40:02 +0100360 g_hash_table_insert (priv->firmware_gtypes, g_strdup (id), GSIZE_TO_POINTER (gtype));
361}
362
363/**
364 * fu_context_get_firmware_gtype_by_id:
365 * @self: a #FuContext
366 * @id: An string describing the type, e.g. "ihex"
367 *
368 * Returns the #GType using the firmware @id.
369 *
370 * Returns: a #GType, or %G_TYPE_INVALID
371 *
372 * Since: 1.6.0
373 **/
374GType
375fu_context_get_firmware_gtype_by_id (FuContext *self, const gchar *id)
376{
377 FuContextPrivate *priv = GET_PRIVATE (self);
378 g_return_val_if_fail (FU_IS_CONTEXT (self), G_TYPE_INVALID);
379 g_return_val_if_fail (id != NULL, G_TYPE_INVALID);
380 return GPOINTER_TO_SIZE (g_hash_table_lookup (priv->firmware_gtypes, id));
381}
382
383static gint
384fu_context_gtypes_sort_cb (gconstpointer a, gconstpointer b)
385{
386 const gchar *stra = *((const gchar **) a);
387 const gchar *strb = *((const gchar **) b);
388 return g_strcmp0 (stra, strb);
389}
390
391/**
392 * fu_context_get_firmware_gtype_ids:
393 * @self: a #FuContext
394 *
395 * Returns all the firmware #GType IDs.
396 *
397 * Returns: (transfer none) (element-type utf8): List of subsystems
398 *
399 * Since: 1.6.0
400 **/
401GPtrArray *
402fu_context_get_firmware_gtype_ids (FuContext *self)
403{
404 FuContextPrivate *priv = GET_PRIVATE (self);
405 GPtrArray *firmware_gtypes = g_ptr_array_new_with_free_func (g_free);
406 g_autoptr(GList) keys = g_hash_table_get_keys (priv->firmware_gtypes);
407
408 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
409
410 for (GList *l = keys; l != NULL; l = l->next) {
411 const gchar *id = l->data;
412 g_ptr_array_add (firmware_gtypes, g_strdup (id));
413 }
414 g_ptr_array_sort (firmware_gtypes, fu_context_gtypes_sort_cb);
415 return firmware_gtypes;
416}
417
418/**
419 * fu_context_add_quirk_key:
420 * @self: a #FuContext
421 * @key: A quirk string, e.g. `DfuVersion`
422 *
423 * Adds a possible quirk key. If added by a plugin it should be namespaced
424 * using the plugin name, where possible.
425 *
426 * Plugins can use this method only in fu_plugin_init()
427 *
428 * Since: 1.6.0
429 **/
430void
431fu_context_add_quirk_key (FuContext *self, const gchar *key)
432{
433 FuContextPrivate *priv = GET_PRIVATE (self);
434 g_return_if_fail (FU_IS_CONTEXT (self));
435 g_return_if_fail (key != NULL);
436 if (priv->quirks == NULL)
437 return;
438 fu_quirks_add_possible_key (priv->quirks, key);
439}
440
441/**
442 * fu_context_lookup_quirk_by_id:
443 * @self: A #FuContext
444 * @guid: GUID to lookup
445 * @key: An ID to match the entry, e.g. "Summary"
446 *
447 * Looks up an entry in the hardware database using a string value.
448 *
449 * Returns: (transfer none): values from the database, or %NULL if not found
450 *
451 * Since: 1.6.0
452 **/
453const gchar *
454fu_context_lookup_quirk_by_id (FuContext *self, const gchar *guid, const gchar *key)
455{
456 FuContextPrivate *priv = GET_PRIVATE (self);
457 g_return_val_if_fail (FU_IS_CONTEXT (self), NULL);
458
459 /* exact ID */
460 return fu_quirks_lookup_by_id (priv->quirks, guid, key);
461}
462
463/**
464 * fu_context_lookup_quirk_by_id_iter:
465 * @self: A #FuContext
466 * @guid: GUID to lookup
467 * @iter_cb: (scope async): A #FuContextLookupIter
468 * @user_data: user data passed to @iter_cb
469 *
470 * Looks up all entries in the hardware database using a GUID value.
471 *
472 * Returns: %TRUE if the ID was found, and @iter was called
473 *
474 * Since: 1.6.0
475 **/
476gboolean
477fu_context_lookup_quirk_by_id_iter (FuContext *self, const gchar *guid,
478 FuContextLookupIter iter_cb, gpointer user_data)
479{
480 FuContextPrivate *priv = GET_PRIVATE (self);
481 g_return_val_if_fail (FU_IS_CONTEXT (self), FALSE);
482 g_return_val_if_fail (guid != NULL, FALSE);
483 g_return_val_if_fail (iter_cb != NULL, FALSE);
484 return fu_quirks_lookup_by_id_iter (priv->quirks, guid, (FuQuirksIter) iter_cb, user_data);
485}
486
487/**
488 * fu_context_security_changed:
489 * @self: A #FuContext
490 *
491 * Informs the daemon that the HSI state may have changed.
492 *
493 * Since: 1.6.0
494 **/
495void
496fu_context_security_changed (FuContext *self)
497{
498 g_return_if_fail (FU_IS_CONTEXT (self));
499 g_signal_emit (self, signals[SIGNAL_SECURITY_CHANGED], 0);
500}
501
502/**
503 * fu_context_load_hwinfo:
504 * @self: A #FuContext
505 * @error: (nullable): A #GError, or %NULL
506 *
507 * Loads all hardware information parts of the context.
508 *
509 * Returns: %TRUE for success
510 *
511 * Since: 1.6.0
512 **/
513gboolean
514fu_context_load_hwinfo (FuContext *self, GError **error)
515{
516 FuContextPrivate *priv = GET_PRIVATE (self);
517 g_autoptr(GError) error_smbios = NULL;
518 g_autoptr(GError) error_hwids = NULL;
519
520 g_return_val_if_fail (FU_IS_CONTEXT (self), FALSE);
521 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
522
523 if (!fu_smbios_setup (priv->smbios, &error_smbios))
524 g_warning ("Failed to load SMBIOS: %s", error_smbios->message);
525 if (!fu_hwids_setup (priv->hwids, priv->smbios, &error_hwids))
526 g_warning ("Failed to load HWIDs: %s", error_hwids->message);
527
528 /* always */
529 return TRUE;
530}
531
532/**
533 * fu_context_load_quirks:
534 * @self: A #FuContext
535 * @error: (nullable): A #GError, or %NULL
536 *
537 * Loads all quirks into the context.
538 *
539 * Returns: %TRUE for success
540 *
541 * Since: 1.6.0
542 **/
543gboolean
544fu_context_load_quirks (FuContext *self, FuQuirksLoadFlags flags, GError **error)
545{
546 FuContextPrivate *priv = GET_PRIVATE (self);
547 g_autoptr(GError) error_local = NULL;
548
549 g_return_val_if_fail (FU_IS_CONTEXT (self), FALSE);
550 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
551
552 /* rebuild silo if required */
553 if (!fu_quirks_load (priv->quirks, flags, &error_local))
554 g_warning ("Failed to load quirks: %s", error_local->message);
555
556 /* always */
557 return TRUE;
558}
559
Richard Hughes4d76d182021-04-06 13:35:15 +0100560/**
561 * fu_context_get_battery_state:
562 * @self: A #FuContext
563 *
564 * Gets if the system is on battery power, e.g. UPS or laptop battery.
565 *
566 * Returns: a #FuBatteryState, e.g. %FU_BATTERY_STATE_DISCHARGING
567 *
568 * Since: 1.6.0
569 **/
570FuBatteryState
571fu_context_get_battery_state (FuContext *self)
572{
573 FuContextPrivate *priv = GET_PRIVATE (self);
574 g_return_val_if_fail (FU_IS_CONTEXT (self), FALSE);
575 return priv->battery_state;
576}
577
578/**
579 * fu_context_set_battery_state:
580 * @self: A #FuContext
581 * @battery_state: a #FuBatteryState, e.g. %FU_BATTERY_STATE_DISCHARGING
582 *
583 * Sets if the system is on battery power, e.g. UPS or laptop battery.
584 *
585 * Since: 1.6.0
586 **/
587void
588fu_context_set_battery_state (FuContext *self, FuBatteryState battery_state)
589{
590 FuContextPrivate *priv = GET_PRIVATE (self);
591 g_return_if_fail (FU_IS_CONTEXT (self));
592 if (priv->battery_state == battery_state)
593 return;
594 priv->battery_state = battery_state;
595 g_debug ("battery state now %s",
596 fu_battery_state_to_string (battery_state));
597 g_object_notify (G_OBJECT (self), "battery-state");
598}
599
600/**
601 * fu_context_get_battery_level:
602 * @self: A #FuContext
603 *
604 * Gets the system battery level in percent.
605 *
606 * Returns: percentage value, or %FU_BATTERY_VALUE_INVALID for unknown
607 *
608 * Since: 1.6.0
609 **/
610guint
611fu_context_get_battery_level (FuContext *self)
612{
613 FuContextPrivate *priv = GET_PRIVATE (self);
614 g_return_val_if_fail (FU_IS_CONTEXT (self), G_MAXUINT);
615 return priv->battery_level;
616}
617
618/**
619 * fu_context_set_battery_level:
620 * @self: A #FuContext
621 * @battery_level: value
622 *
623 * Sets the system battery level in percent.
624 *
625 * Since: 1.6.0
626 **/
627void
628fu_context_set_battery_level (FuContext *self, guint battery_level)
629{
630 FuContextPrivate *priv = GET_PRIVATE (self);
631 g_return_if_fail (FU_IS_CONTEXT (self));
632 g_return_if_fail (battery_level <= FU_BATTERY_VALUE_INVALID);
633 if (priv->battery_level == battery_level)
634 return;
635 priv->battery_level = battery_level;
636 g_debug ("battery level now %u", battery_level);
637 g_object_notify (G_OBJECT (self), "battery-level");
638}
639
640/**
641 * fu_context_get_battery_threshold:
642 * @self: A #FuContext
643 *
644 * Gets the system battery threshold in percent.
645 *
646 * Returns: percentage value, or %FU_BATTERY_VALUE_INVALID for unknown
647 *
648 * Since: 1.6.0
649 **/
650guint
651fu_context_get_battery_threshold (FuContext *self)
652{
653 FuContextPrivate *priv = GET_PRIVATE (self);
654 g_return_val_if_fail (FU_IS_CONTEXT (self), G_MAXUINT);
655 return priv->battery_threshold;
656}
657
658/**
659 * fu_context_set_battery_threshold:
660 * @self: A #FuContext
661 * @battery_threshold: value
662 *
663 * Sets the system battery threshold in percent.
664 *
665 * Since: 1.6.0
666 **/
667void
668fu_context_set_battery_threshold (FuContext *self, guint battery_threshold)
669{
670 FuContextPrivate *priv = GET_PRIVATE (self);
671 g_return_if_fail (FU_IS_CONTEXT (self));
672 g_return_if_fail (battery_threshold <= FU_BATTERY_VALUE_INVALID);
673 if (priv->battery_threshold == battery_threshold)
674 return;
675 priv->battery_threshold = battery_threshold;
676 g_debug ("battery threshold now %u", battery_threshold);
677 g_object_notify (G_OBJECT (self), "battery-threshold");
678}
679
680static void
681fu_context_get_property (GObject *object, guint prop_id,
682 GValue *value, GParamSpec *pspec)
683{
684 FuContext *self = FU_CONTEXT (object);
685 FuContextPrivate *priv = GET_PRIVATE (self);
686 switch (prop_id) {
687 case PROP_BATTERY_STATE:
688 g_value_set_uint (value, priv->battery_state);
689 break;
690 case PROP_BATTERY_LEVEL:
691 g_value_set_uint (value, priv->battery_level);
692 break;
693 case PROP_BATTERY_THRESHOLD:
694 g_value_set_uint (value, priv->battery_threshold);
695 break;
696 default:
697 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
698 break;
699 }
700}
701
702static void
703fu_context_set_property (GObject *object, guint prop_id,
704 const GValue *value, GParamSpec *pspec)
705{
706 FuContext *self = FU_CONTEXT (object);
707 switch (prop_id) {
708 case PROP_BATTERY_STATE:
709 fu_context_set_battery_state (self, g_value_get_uint (value));
710 break;
711 case PROP_BATTERY_LEVEL:
712 fu_context_set_battery_level (self, g_value_get_uint (value));
713 break;
714 case PROP_BATTERY_THRESHOLD:
715 fu_context_set_battery_threshold (self, g_value_get_uint (value));
716 break;
717 default:
718 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
719 break;
720 }
721}
722
Richard Hughesb333e002021-04-01 10:40:02 +0100723static void
724fu_context_finalize (GObject *object)
725{
726 FuContext *self = FU_CONTEXT (object);
727 FuContextPrivate *priv = GET_PRIVATE (self);
728
Richard Hughes45493b02021-04-11 16:45:06 +0100729 if (priv->runtime_versions != NULL)
730 g_hash_table_unref (priv->runtime_versions);
731 if (priv->compile_versions != NULL)
732 g_hash_table_unref (priv->compile_versions);
Richard Hughesb333e002021-04-01 10:40:02 +0100733 g_object_unref (priv->hwids);
734 g_object_unref (priv->quirks);
735 g_object_unref (priv->smbios);
736 g_hash_table_unref (priv->firmware_gtypes);
737 g_ptr_array_unref (priv->udev_subsystems);
738
739 G_OBJECT_CLASS (fu_context_parent_class)->finalize (object);
740}
741
742static void
743fu_context_class_init (FuContextClass *klass)
744{
745 GObjectClass *object_class = G_OBJECT_CLASS (klass);
Richard Hughes4d76d182021-04-06 13:35:15 +0100746 GParamSpec *pspec;
747
748 object_class->get_property = fu_context_get_property;
749 object_class->set_property = fu_context_set_property;
750
751 pspec = g_param_spec_uint ("battery-state", NULL, NULL,
752 FU_BATTERY_STATE_UNKNOWN,
753 FU_BATTERY_STATE_LAST,
754 FU_BATTERY_STATE_UNKNOWN,
755 G_PARAM_READWRITE |
756 G_PARAM_STATIC_NAME);
757 g_object_class_install_property (object_class, PROP_BATTERY_STATE, pspec);
758
759 pspec = g_param_spec_uint ("battery-level", NULL, NULL,
760 0,
761 FU_BATTERY_VALUE_INVALID,
762 FU_BATTERY_VALUE_INVALID,
763 G_PARAM_READWRITE |
764 G_PARAM_STATIC_NAME);
765 g_object_class_install_property (object_class, PROP_BATTERY_LEVEL, pspec);
766
767 pspec = g_param_spec_uint ("battery-threshold", NULL, NULL,
768 0,
769 FU_BATTERY_VALUE_INVALID,
770 FU_BATTERY_VALUE_INVALID,
771 G_PARAM_READWRITE |
772 G_PARAM_STATIC_NAME);
773 g_object_class_install_property (object_class, PROP_BATTERY_THRESHOLD, pspec);
Richard Hughesb333e002021-04-01 10:40:02 +0100774
775 signals[SIGNAL_SECURITY_CHANGED] =
776 g_signal_new ("security-changed",
777 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
778 G_STRUCT_OFFSET (FuContextClass, security_changed),
779 NULL, NULL, g_cclosure_marshal_VOID__VOID,
780 G_TYPE_NONE, 0);
781
782 object_class->finalize = fu_context_finalize;
783}
784
785static void
786fu_context_init (FuContext *self)
787{
788 FuContextPrivate *priv = GET_PRIVATE (self);
Richard Hughes4d76d182021-04-06 13:35:15 +0100789 priv->battery_level = FU_BATTERY_VALUE_INVALID;
790 priv->battery_threshold = FU_BATTERY_VALUE_INVALID;
Richard Hughesb333e002021-04-01 10:40:02 +0100791 priv->smbios = fu_smbios_new ();
792 priv->hwids = fu_hwids_new ();
793 priv->udev_subsystems = g_ptr_array_new_with_free_func (g_free);
794 priv->firmware_gtypes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
795 priv->quirks = fu_quirks_new ();
796}
797
798/**
799 * fu_context_new:
800 *
801 * Creates a new #FuContext
802 *
803 * Returns: the object
804 *
805 * Since: 1.6.0
806 **/
807FuContext *
808fu_context_new (void)
809{
810 return FU_CONTEXT (g_object_new (FU_TYPE_CONTEXT, NULL));
811}