mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-02 07:31:42 +00:00
804 lines
21 KiB
C
804 lines
21 KiB
C
/*
|
|
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#define G_LOG_DOMAIN "FuContext"
|
|
|
|
#include "config.h"
|
|
|
|
#include "fu-context-private.h"
|
|
#include "fu-hwids.h"
|
|
#include "fu-smbios-private.h"
|
|
|
|
/**
|
|
* FuContext:
|
|
*
|
|
* A context that represents the shared system state. This object is shared
|
|
* between the engine, the plugins and the devices.
|
|
*/
|
|
|
|
typedef struct {
|
|
FuHwids *hwids;
|
|
FuSmbios *smbios;
|
|
FuQuirks *quirks;
|
|
GHashTable *runtime_versions;
|
|
GHashTable *compile_versions;
|
|
GPtrArray *udev_subsystems;
|
|
GHashTable *firmware_gtypes;
|
|
FuBatteryState battery_state;
|
|
guint battery_level;
|
|
guint battery_threshold;
|
|
} FuContextPrivate;
|
|
|
|
enum { SIGNAL_SECURITY_CHANGED, SIGNAL_LAST };
|
|
|
|
enum { PROP_0, PROP_BATTERY_STATE, PROP_BATTERY_LEVEL, PROP_BATTERY_THRESHOLD, PROP_LAST };
|
|
|
|
static guint signals[SIGNAL_LAST] = {0};
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE(FuContext, fu_context, G_TYPE_OBJECT)
|
|
|
|
#define GET_PRIVATE(o) (fu_context_get_instance_private(o))
|
|
|
|
/**
|
|
* fu_context_get_smbios_string:
|
|
* @self: a #FuContext
|
|
* @structure_type: a SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
|
|
* @offset: a SMBIOS offset
|
|
*
|
|
* Gets a hardware SMBIOS string.
|
|
*
|
|
* The @type and @offset can be referenced from the DMTF SMBIOS specification:
|
|
* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
|
|
*
|
|
* Returns: a string, or %NULL
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
const gchar *
|
|
fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offset)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
return fu_smbios_get_string(priv->smbios, structure_type, offset, NULL);
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_smbios_data:
|
|
* @self: a #FuContext
|
|
* @structure_type: a SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
|
|
*
|
|
* Gets a hardware SMBIOS data.
|
|
*
|
|
* Returns: (transfer full): a #GBytes, or %NULL
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
GBytes *
|
|
fu_context_get_smbios_data(FuContext *self, guint8 structure_type)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
return fu_smbios_get_data(priv->smbios, structure_type, NULL);
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_smbios_integer:
|
|
* @self: a #FuContext
|
|
* @type: a structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
|
|
* @offset: a structure offset
|
|
*
|
|
* Reads an integer value from the SMBIOS string table of a specific structure.
|
|
*
|
|
* The @type and @offset can be referenced from the DMTF SMBIOS specification:
|
|
* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
|
|
*
|
|
* Returns: an integer, or %G_MAXUINT if invalid or not found
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
guint
|
|
fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), G_MAXUINT);
|
|
return fu_smbios_get_integer(priv->smbios, type, offset, NULL);
|
|
}
|
|
|
|
/**
|
|
* fu_context_has_hwid_guid:
|
|
* @self: a #FuContext
|
|
* @guid: a GUID, e.g. `059eb22d-6dc7-59af-abd3-94bbe017f67c`
|
|
*
|
|
* Finds out if a hardware GUID exists.
|
|
*
|
|
* Returns: %TRUE if the GUID exists
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
gboolean
|
|
fu_context_has_hwid_guid(FuContext *self, const gchar *guid)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
|
|
return fu_hwids_has_guid(priv->hwids, guid);
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_hwid_guids:
|
|
* @self: a #FuContext
|
|
*
|
|
* Returns all the HWIDs defined in the system. All hardware IDs on a
|
|
* specific system can be shown using the `fwupdmgr hwids` command.
|
|
*
|
|
* Returns: (transfer none) (element-type utf8): an array of GUIDs
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
GPtrArray *
|
|
fu_context_get_hwid_guids(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
return fu_hwids_get_guids(priv->hwids);
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_hwid_value:
|
|
* @self: a #FuContext
|
|
* @key: a DMI ID, e.g. `BiosVersion`
|
|
*
|
|
* Gets the cached value for one specific key that is valid ASCII and suitable
|
|
* for display.
|
|
*
|
|
* Returns: the string, e.g. `1.2.3`, or %NULL if not found
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
const gchar *
|
|
fu_context_get_hwid_value(FuContext *self, const gchar *key)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
g_return_val_if_fail(key != NULL, NULL);
|
|
return fu_hwids_get_value(priv->hwids, key);
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_hwid_replace_value:
|
|
* @self: a #FuContext
|
|
* @keys: a key, e.g. `HardwareID-3` or %FU_HWIDS_KEY_PRODUCT_SKU
|
|
* @error: (nullable): optional return location for an error
|
|
*
|
|
* Gets the replacement value for a specific key. All hardware IDs on a
|
|
* specific system can be shown using the `fwupdmgr hwids` command.
|
|
*
|
|
* Returns: (transfer full): a string, or %NULL for error.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
gchar *
|
|
fu_context_get_hwid_replace_value(FuContext *self, const gchar *keys, GError **error)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
g_return_val_if_fail(keys != NULL, NULL);
|
|
return fu_hwids_get_replace_values(priv->hwids, keys, error);
|
|
}
|
|
|
|
/**
|
|
* fu_context_add_runtime_version:
|
|
* @self: a #FuContext
|
|
* @component_id: an AppStream component id, e.g. `org.gnome.Software`
|
|
* @version: a version string, e.g. `1.2.3`
|
|
*
|
|
* Sets a runtime version of a specific dependency.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_add_runtime_version(FuContext *self, const gchar *component_id, const gchar *version)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(component_id != NULL);
|
|
g_return_if_fail(version != NULL);
|
|
|
|
if (priv->runtime_versions == NULL)
|
|
return;
|
|
g_hash_table_insert(priv->runtime_versions, g_strdup(component_id), g_strdup(version));
|
|
}
|
|
|
|
/**
|
|
* fu_context_set_runtime_versions:
|
|
* @self: a #FuContext
|
|
* @runtime_versions: (element-type utf8 utf8): dictionary of versions
|
|
*
|
|
* Sets the runtime versions for a plugin.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_set_runtime_versions(FuContext *self, GHashTable *runtime_versions)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(runtime_versions != NULL);
|
|
priv->runtime_versions = g_hash_table_ref(runtime_versions);
|
|
}
|
|
|
|
/**
|
|
* fu_context_add_compile_version:
|
|
* @self: a #FuContext
|
|
* @component_id: an AppStream component id, e.g. `org.gnome.Software`
|
|
* @version: a version string, e.g. `1.2.3`
|
|
*
|
|
* Sets a compile-time version of a specific dependency.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_add_compile_version(FuContext *self, const gchar *component_id, const gchar *version)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(component_id != NULL);
|
|
g_return_if_fail(version != NULL);
|
|
|
|
if (priv->compile_versions == NULL)
|
|
return;
|
|
g_hash_table_insert(priv->compile_versions, g_strdup(component_id), g_strdup(version));
|
|
}
|
|
|
|
/**
|
|
* fu_context_set_compile_versions:
|
|
* @self: a #FuContext
|
|
* @compile_versions: (element-type utf8 utf8): dictionary of versions
|
|
*
|
|
* Sets the compile time versions for a plugin.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_set_compile_versions(FuContext *self, GHashTable *compile_versions)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(compile_versions != NULL);
|
|
priv->compile_versions = g_hash_table_ref(compile_versions);
|
|
}
|
|
|
|
/**
|
|
* fu_context_add_udev_subsystem:
|
|
* @self: a #FuContext
|
|
* @subsystem: a subsystem name, e.g. `pciport`
|
|
*
|
|
* Registers the udev subsystem to be watched by the daemon.
|
|
*
|
|
* Plugins can use this method only in fu_plugin_init()
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_add_udev_subsystem(FuContext *self, const gchar *subsystem)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(subsystem != NULL);
|
|
|
|
for (guint i = 0; i < priv->udev_subsystems->len; i++) {
|
|
const gchar *subsystem_tmp = g_ptr_array_index(priv->udev_subsystems, i);
|
|
if (g_strcmp0(subsystem_tmp, subsystem) == 0)
|
|
return;
|
|
}
|
|
g_debug("added udev subsystem watch of %s", subsystem);
|
|
g_ptr_array_add(priv->udev_subsystems, g_strdup(subsystem));
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_udev_subsystems:
|
|
* @self: a #FuContext
|
|
*
|
|
* Gets the udev subsystems required by all plugins.
|
|
*
|
|
* Returns: (transfer none) (element-type utf8): List of subsystems
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
GPtrArray *
|
|
fu_context_get_udev_subsystems(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
return priv->udev_subsystems;
|
|
}
|
|
|
|
/**
|
|
* fu_context_add_firmware_gtype:
|
|
* @self: a #FuContext
|
|
* @id: (nullable): an optional string describing the type, e.g. `ihex`
|
|
* @gtype: a #GType e.g. `FU_TYPE_FOO_FIRMWARE`
|
|
*
|
|
* Adds a firmware #GType which is used when creating devices. If @id is not
|
|
* specified then it is guessed using the #GType name.
|
|
*
|
|
* Plugins can use this method only in fu_plugin_init()
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_add_firmware_gtype(FuContext *self, const gchar *id, GType gtype)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(id != NULL);
|
|
g_return_if_fail(gtype != G_TYPE_INVALID);
|
|
g_type_ensure(gtype);
|
|
g_hash_table_insert(priv->firmware_gtypes, g_strdup(id), GSIZE_TO_POINTER(gtype));
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_firmware_gtype_by_id:
|
|
* @self: a #FuContext
|
|
* @id: an string describing the type, e.g. `ihex`
|
|
*
|
|
* Returns the #GType using the firmware @id.
|
|
*
|
|
* Returns: a #GType, or %G_TYPE_INVALID
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
GType
|
|
fu_context_get_firmware_gtype_by_id(FuContext *self, const gchar *id)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), G_TYPE_INVALID);
|
|
g_return_val_if_fail(id != NULL, G_TYPE_INVALID);
|
|
return GPOINTER_TO_SIZE(g_hash_table_lookup(priv->firmware_gtypes, id));
|
|
}
|
|
|
|
static gint
|
|
fu_context_gtypes_sort_cb(gconstpointer a, gconstpointer b)
|
|
{
|
|
const gchar *stra = *((const gchar **)a);
|
|
const gchar *strb = *((const gchar **)b);
|
|
return g_strcmp0(stra, strb);
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_firmware_gtype_ids:
|
|
* @self: a #FuContext
|
|
*
|
|
* Returns all the firmware #GType IDs.
|
|
*
|
|
* Returns: (transfer none) (element-type utf8): List of subsystems
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
GPtrArray *
|
|
fu_context_get_firmware_gtype_ids(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
GPtrArray *firmware_gtypes = g_ptr_array_new_with_free_func(g_free);
|
|
g_autoptr(GList) keys = g_hash_table_get_keys(priv->firmware_gtypes);
|
|
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
|
|
for (GList *l = keys; l != NULL; l = l->next) {
|
|
const gchar *id = l->data;
|
|
g_ptr_array_add(firmware_gtypes, g_strdup(id));
|
|
}
|
|
g_ptr_array_sort(firmware_gtypes, fu_context_gtypes_sort_cb);
|
|
return firmware_gtypes;
|
|
}
|
|
|
|
/**
|
|
* fu_context_add_quirk_key:
|
|
* @self: a #FuContext
|
|
* @key: a quirk string, e.g. `DfuVersion`
|
|
*
|
|
* Adds a possible quirk key. If added by a plugin it should be namespaced
|
|
* using the plugin name, where possible.
|
|
*
|
|
* Plugins can use this method only in fu_plugin_init()
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_add_quirk_key(FuContext *self, const gchar *key)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(key != NULL);
|
|
if (priv->quirks == NULL)
|
|
return;
|
|
fu_quirks_add_possible_key(priv->quirks, key);
|
|
}
|
|
|
|
/**
|
|
* fu_context_lookup_quirk_by_id:
|
|
* @self: a #FuContext
|
|
* @guid: GUID to lookup
|
|
* @key: an ID to match the entry, e.g. `Summary`
|
|
*
|
|
* Looks up an entry in the hardware database using a string value.
|
|
*
|
|
* Returns: (transfer none): values from the database, or %NULL if not found
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
const gchar *
|
|
fu_context_lookup_quirk_by_id(FuContext *self, const gchar *guid, const gchar *key)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
|
|
g_return_val_if_fail(guid != NULL, NULL);
|
|
g_return_val_if_fail(key != NULL, NULL);
|
|
|
|
/* exact ID */
|
|
return fu_quirks_lookup_by_id(priv->quirks, guid, key);
|
|
}
|
|
|
|
/**
|
|
* fu_context_lookup_quirk_by_id_iter:
|
|
* @self: a #FuContext
|
|
* @guid: GUID to lookup
|
|
* @iter_cb: (scope async): a function to call for each result
|
|
* @user_data: user data passed to @iter_cb
|
|
*
|
|
* Looks up all entries in the hardware database using a GUID value.
|
|
*
|
|
* Returns: %TRUE if the ID was found, and @iter was called
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
gboolean
|
|
fu_context_lookup_quirk_by_id_iter(FuContext *self,
|
|
const gchar *guid,
|
|
FuContextLookupIter iter_cb,
|
|
gpointer user_data)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
|
|
g_return_val_if_fail(guid != NULL, FALSE);
|
|
g_return_val_if_fail(iter_cb != NULL, FALSE);
|
|
return fu_quirks_lookup_by_id_iter(priv->quirks, guid, (FuQuirksIter)iter_cb, user_data);
|
|
}
|
|
|
|
/**
|
|
* fu_context_security_changed:
|
|
* @self: a #FuContext
|
|
*
|
|
* Informs the daemon that the HSI state may have changed.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_security_changed(FuContext *self)
|
|
{
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_signal_emit(self, signals[SIGNAL_SECURITY_CHANGED], 0);
|
|
}
|
|
|
|
/**
|
|
* fu_context_load_hwinfo:
|
|
* @self: a #FuContext
|
|
* @error: (nullable): optional return location for an error
|
|
*
|
|
* Loads all hardware information parts of the context.
|
|
*
|
|
* Returns: %TRUE for success
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
gboolean
|
|
fu_context_load_hwinfo(FuContext *self, GError **error)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_autoptr(GError) error_smbios = NULL;
|
|
g_autoptr(GError) error_hwids = NULL;
|
|
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
|
|
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
|
|
if (!fu_smbios_setup(priv->smbios, &error_smbios))
|
|
g_warning("Failed to load SMBIOS: %s", error_smbios->message);
|
|
if (!fu_hwids_setup(priv->hwids, priv->smbios, &error_hwids))
|
|
g_warning("Failed to load HWIDs: %s", error_hwids->message);
|
|
|
|
/* always */
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* fu_context_load_quirks:
|
|
* @self: a #FuContext
|
|
* @flags: quirks load flags, e.g. %FU_QUIRKS_LOAD_FLAG_READONLY_FS
|
|
* @error: (nullable): optional return location for an error
|
|
*
|
|
* Loads all quirks into the context.
|
|
*
|
|
* Returns: %TRUE for success
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
gboolean
|
|
fu_context_load_quirks(FuContext *self, FuQuirksLoadFlags flags, GError **error)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_autoptr(GError) error_local = NULL;
|
|
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
|
|
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
|
|
/* rebuild silo if required */
|
|
if (!fu_quirks_load(priv->quirks, flags, &error_local))
|
|
g_warning("Failed to load quirks: %s", error_local->message);
|
|
|
|
/* always */
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_battery_state:
|
|
* @self: a #FuContext
|
|
*
|
|
* Gets if the system is on battery power, e.g. UPS or laptop battery.
|
|
*
|
|
* Returns: a battery state, e.g. %FU_BATTERY_STATE_DISCHARGING
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
FuBatteryState
|
|
fu_context_get_battery_state(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
|
|
return priv->battery_state;
|
|
}
|
|
|
|
/**
|
|
* fu_context_set_battery_state:
|
|
* @self: a #FuContext
|
|
* @battery_state: a battery state, e.g. %FU_BATTERY_STATE_DISCHARGING
|
|
*
|
|
* Sets if the system is on battery power, e.g. UPS or laptop battery.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_set_battery_state(FuContext *self, FuBatteryState battery_state)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
if (priv->battery_state == battery_state)
|
|
return;
|
|
priv->battery_state = battery_state;
|
|
g_debug("battery state now %s", fu_battery_state_to_string(battery_state));
|
|
g_object_notify(G_OBJECT(self), "battery-state");
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_battery_level:
|
|
* @self: a #FuContext
|
|
*
|
|
* Gets the system battery level in percent.
|
|
*
|
|
* Returns: percentage value, or %FU_BATTERY_VALUE_INVALID for unknown
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
guint
|
|
fu_context_get_battery_level(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), G_MAXUINT);
|
|
return priv->battery_level;
|
|
}
|
|
|
|
/**
|
|
* fu_context_set_battery_level:
|
|
* @self: a #FuContext
|
|
* @battery_level: value
|
|
*
|
|
* Sets the system battery level in percent.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_set_battery_level(FuContext *self, guint battery_level)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(battery_level <= FU_BATTERY_VALUE_INVALID);
|
|
if (priv->battery_level == battery_level)
|
|
return;
|
|
priv->battery_level = battery_level;
|
|
g_debug("battery level now %u", battery_level);
|
|
g_object_notify(G_OBJECT(self), "battery-level");
|
|
}
|
|
|
|
/**
|
|
* fu_context_get_battery_threshold:
|
|
* @self: a #FuContext
|
|
*
|
|
* Gets the system battery threshold in percent.
|
|
*
|
|
* Returns: percentage value, or %FU_BATTERY_VALUE_INVALID for unknown
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
guint
|
|
fu_context_get_battery_threshold(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_val_if_fail(FU_IS_CONTEXT(self), G_MAXUINT);
|
|
return priv->battery_threshold;
|
|
}
|
|
|
|
/**
|
|
* fu_context_set_battery_threshold:
|
|
* @self: a #FuContext
|
|
* @battery_threshold: value
|
|
*
|
|
* Sets the system battery threshold in percent.
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
void
|
|
fu_context_set_battery_threshold(FuContext *self, guint battery_threshold)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
g_return_if_fail(FU_IS_CONTEXT(self));
|
|
g_return_if_fail(battery_threshold <= FU_BATTERY_VALUE_INVALID);
|
|
if (priv->battery_threshold == battery_threshold)
|
|
return;
|
|
priv->battery_threshold = battery_threshold;
|
|
g_debug("battery threshold now %u", battery_threshold);
|
|
g_object_notify(G_OBJECT(self), "battery-threshold");
|
|
}
|
|
|
|
static void
|
|
fu_context_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|
{
|
|
FuContext *self = FU_CONTEXT(object);
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
switch (prop_id) {
|
|
case PROP_BATTERY_STATE:
|
|
g_value_set_uint(value, priv->battery_state);
|
|
break;
|
|
case PROP_BATTERY_LEVEL:
|
|
g_value_set_uint(value, priv->battery_level);
|
|
break;
|
|
case PROP_BATTERY_THRESHOLD:
|
|
g_value_set_uint(value, priv->battery_threshold);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
fu_context_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
|
{
|
|
FuContext *self = FU_CONTEXT(object);
|
|
switch (prop_id) {
|
|
case PROP_BATTERY_STATE:
|
|
fu_context_set_battery_state(self, g_value_get_uint(value));
|
|
break;
|
|
case PROP_BATTERY_LEVEL:
|
|
fu_context_set_battery_level(self, g_value_get_uint(value));
|
|
break;
|
|
case PROP_BATTERY_THRESHOLD:
|
|
fu_context_set_battery_threshold(self, g_value_get_uint(value));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
fu_context_finalize(GObject *object)
|
|
{
|
|
FuContext *self = FU_CONTEXT(object);
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
|
|
if (priv->runtime_versions != NULL)
|
|
g_hash_table_unref(priv->runtime_versions);
|
|
if (priv->compile_versions != NULL)
|
|
g_hash_table_unref(priv->compile_versions);
|
|
g_object_unref(priv->hwids);
|
|
g_object_unref(priv->quirks);
|
|
g_object_unref(priv->smbios);
|
|
g_hash_table_unref(priv->firmware_gtypes);
|
|
g_ptr_array_unref(priv->udev_subsystems);
|
|
|
|
G_OBJECT_CLASS(fu_context_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
fu_context_class_init(FuContextClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
GParamSpec *pspec;
|
|
|
|
object_class->get_property = fu_context_get_property;
|
|
object_class->set_property = fu_context_set_property;
|
|
|
|
pspec = g_param_spec_uint("battery-state",
|
|
NULL,
|
|
NULL,
|
|
FU_BATTERY_STATE_UNKNOWN,
|
|
FU_BATTERY_STATE_LAST,
|
|
FU_BATTERY_STATE_UNKNOWN,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
|
g_object_class_install_property(object_class, PROP_BATTERY_STATE, pspec);
|
|
|
|
pspec = g_param_spec_uint("battery-level",
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
FU_BATTERY_VALUE_INVALID,
|
|
FU_BATTERY_VALUE_INVALID,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
|
g_object_class_install_property(object_class, PROP_BATTERY_LEVEL, pspec);
|
|
|
|
pspec = g_param_spec_uint("battery-threshold",
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
FU_BATTERY_VALUE_INVALID,
|
|
FU_BATTERY_VALUE_INVALID,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
|
g_object_class_install_property(object_class, PROP_BATTERY_THRESHOLD, pspec);
|
|
|
|
signals[SIGNAL_SECURITY_CHANGED] =
|
|
g_signal_new("security-changed",
|
|
G_TYPE_FROM_CLASS(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(FuContextClass, security_changed),
|
|
NULL,
|
|
NULL,
|
|
g_cclosure_marshal_VOID__VOID,
|
|
G_TYPE_NONE,
|
|
0);
|
|
|
|
object_class->finalize = fu_context_finalize;
|
|
}
|
|
|
|
static void
|
|
fu_context_init(FuContext *self)
|
|
{
|
|
FuContextPrivate *priv = GET_PRIVATE(self);
|
|
priv->battery_level = FU_BATTERY_VALUE_INVALID;
|
|
priv->battery_threshold = FU_BATTERY_VALUE_INVALID;
|
|
priv->smbios = fu_smbios_new();
|
|
priv->hwids = fu_hwids_new();
|
|
priv->udev_subsystems = g_ptr_array_new_with_free_func(g_free);
|
|
priv->firmware_gtypes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
|
|
priv->quirks = fu_quirks_new();
|
|
}
|
|
|
|
/**
|
|
* fu_context_new:
|
|
*
|
|
* Creates a new #FuContext
|
|
*
|
|
* Returns: (transfer full): the object
|
|
*
|
|
* Since: 1.6.0
|
|
**/
|
|
FuContext *
|
|
fu_context_new(void)
|
|
{
|
|
return FU_CONTEXT(g_object_new(FU_TYPE_CONTEXT, NULL));
|
|
}
|