diff --git a/libfwupdplugin/fu-device.c b/libfwupdplugin/fu-device.c index d75b435d4..ecac21359 100644 --- a/libfwupdplugin/fu-device.c +++ b/libfwupdplugin/fu-device.c @@ -23,6 +23,8 @@ #define FU_DEVICE_RETRY_OPEN_COUNT 5 #define FU_DEVICE_RETRY_OPEN_DELAY 500 /* ms */ +#define FU_DEVICE_DEFAULT_BATTERY_THRESHOLD 10 /* % */ + /** * SECTION:fu-device * @short_description: a physical or logical device @@ -51,6 +53,7 @@ typedef struct { guint remove_delay; /* ms */ guint progress; guint battery_level; + guint battery_threshold; gint order; guint priority; guint poll_id; @@ -77,6 +80,7 @@ enum { PROP_0, PROP_PROGRESS, PROP_BATTERY_LEVEL, + PROP_BATTERY_THRESHOLD, PROP_PHYSICAL_ID, PROP_LOGICAL_ID, PROP_BACKEND_ID, @@ -101,6 +105,9 @@ fu_device_get_property (GObject *object, guint prop_id, 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; case PROP_PHYSICAL_ID: g_value_set_string (value, priv->physical_id); break; @@ -134,6 +141,9 @@ fu_device_set_property (GObject *object, guint prop_id, case PROP_BATTERY_LEVEL: fu_device_set_battery_level (self, g_value_get_uint (value)); break; + case PROP_BATTERY_THRESHOLD: + fu_device_set_battery_threshold (self, g_value_get_uint (value)); + break; case PROP_PHYSICAL_ID: fu_device_set_physical_id (self, g_value_get_string (value)); break; @@ -1221,6 +1231,10 @@ fu_device_set_quirk_kv (FuDevice *self, fu_device_set_priority (self, fu_common_strtoull (value)); return TRUE; } + if (g_strcmp0 (key, FU_QUIRKS_BATTERY_THRESHOLD) == 0) { + fu_device_set_battery_threshold (self, fu_common_strtoull (value)); + return TRUE; + } if (g_strcmp0 (key, FU_QUIRKS_REMOVE_DELAY) == 0) { fu_device_set_remove_delay (self, fu_common_strtoull (value)); return TRUE; @@ -2550,6 +2564,55 @@ fu_device_set_battery_level (FuDevice *self, guint battery_level) g_object_notify (G_OBJECT (self), "battery-level"); } +/** + * fu_device_get_battery_threshold: + * @self: A #FuDevice + * + * Returns the battery threshold under which a firmware update cannot be + * performed. + * + * If fu_device_set_battery_threshold() has not been used, a default value is + * used instead. + * + * Returns: value in percent + * + * Since: 1.6.0 + **/ +guint +fu_device_get_battery_threshold (FuDevice *self) +{ + FuDevicePrivate *priv = GET_PRIVATE (self); + g_return_val_if_fail (FU_IS_DEVICE (self), 0); + + /* default value */ + if (priv->battery_threshold == 0) + return FU_DEVICE_DEFAULT_BATTERY_THRESHOLD; + + return priv->battery_threshold; +} + +/** + * fu_device_set_battery_threshold: + * @self: A #FuDevice + * @battery_threshold: the percentage value + * + * Sets the battery level, or 0 for the default. Setting this allows fwupd to + * show a warning if the device change is too low to perform the update. + * + * Since: 1.6.0 + **/ +void +fu_device_set_battery_threshold (FuDevice *self, guint battery_threshold) +{ + FuDevicePrivate *priv = GET_PRIVATE (self); + g_return_if_fail (FU_IS_DEVICE (self)); + g_return_if_fail (battery_threshold <= 100); + if (priv->battery_threshold == battery_threshold) + return; + priv->battery_threshold = battery_threshold; + g_object_notify (G_OBJECT (self), "battery-threshold"); +} + static void fu_device_add_string (FuDevice *self, guint idt, GString *str) { @@ -2583,6 +2646,8 @@ fu_device_add_string (FuDevice *self, guint idt, GString *str) fu_common_string_append_kv (str, idt + 1, "ProxyGuid", priv->proxy_guid); if (priv->battery_level != 0) fu_common_string_append_ku (str, idt + 1, "BatteryLevel", priv->battery_level); + if (priv->battery_threshold != 0) + fu_common_string_append_ku (str, idt + 1, "BatteryThreshold", priv->battery_threshold); if (priv->size_min > 0) { g_autofree gchar *sz = g_strdup_printf ("%" G_GUINT64_FORMAT, priv->size_min); fu_common_string_append_kv (str, idt + 1, "FirmwareSizeMin", sz); @@ -3679,6 +3744,12 @@ fu_device_class_init (FuDeviceClass *klass) 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, 100, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME); + g_object_class_install_property (object_class, PROP_BATTERY_THRESHOLD, pspec); + pspec = g_param_spec_object ("quirks", NULL, NULL, FU_TYPE_QUIRKS, G_PARAM_READWRITE | diff --git a/libfwupdplugin/fu-device.h b/libfwupdplugin/fu-device.h index ac2866f25..380bf985f 100644 --- a/libfwupdplugin/fu-device.h +++ b/libfwupdplugin/fu-device.h @@ -330,6 +330,9 @@ void fu_device_set_progress (FuDevice *self, guint fu_device_get_battery_level (FuDevice *self); void fu_device_set_battery_level (FuDevice *self, guint battery_level); +guint fu_device_get_battery_threshold (FuDevice *self); +void fu_device_set_battery_threshold (FuDevice *self, + guint battery_threshold); void fu_device_set_progress_full (FuDevice *self, gsize progress_done, gsize progress_total); diff --git a/libfwupdplugin/fu-quirks.c b/libfwupdplugin/fu-quirks.c index 0e5d4dc42..c62b8fb3a 100644 --- a/libfwupdplugin/fu-quirks.c +++ b/libfwupdplugin/fu-quirks.c @@ -510,6 +510,7 @@ fu_quirks_init (FuQuirks *self) fu_quirks_add_possible_key (self, FU_QUIRKS_PRIORITY); fu_quirks_add_possible_key (self, FU_QUIRKS_PROTOCOL); fu_quirks_add_possible_key (self, FU_QUIRKS_PROXY_GUID); + fu_quirks_add_possible_key (self, FU_QUIRKS_BATTERY_THRESHOLD); fu_quirks_add_possible_key (self, FU_QUIRKS_REMOVE_DELAY); fu_quirks_add_possible_key (self, FU_QUIRKS_SUMMARY); fu_quirks_add_possible_key (self, FU_QUIRKS_UPDATE_IMAGE); diff --git a/libfwupdplugin/fu-quirks.h b/libfwupdplugin/fu-quirks.h index 9db6a1124..b185010b7 100644 --- a/libfwupdplugin/fu-quirks.h +++ b/libfwupdplugin/fu-quirks.h @@ -70,4 +70,5 @@ void fu_quirks_add_possible_key (FuQuirks *self, #define FU_QUIRKS_UPDATE_MESSAGE "UpdateMessage" #define FU_QUIRKS_UPDATE_IMAGE "UpdateImage" #define FU_QUIRKS_PRIORITY "Priority" +#define FU_QUIRKS_BATTERY_THRESHOLD "BatteryThreshold" #define FU_QUIRKS_REMOVE_DELAY "RemoveDelay" diff --git a/libfwupdplugin/fwupdplugin.map b/libfwupdplugin/fwupdplugin.map index a96f523c5..6e8aea984 100644 --- a/libfwupdplugin/fwupdplugin.map +++ b/libfwupdplugin/fwupdplugin.map @@ -761,6 +761,8 @@ LIBFWUPDPLUGIN_1.6.0 { fu_byte_array_set_size_full; fu_common_align_up; fu_device_add_security_attrs; + fu_device_get_battery_threshold; + fu_device_set_battery_threshold; fu_firmware_add_chunk; fu_firmware_build_from_xml; fu_firmware_export; diff --git a/plugins/upower/fu-plugin-upower.c b/plugins/upower/fu-plugin-upower.c index 5e7ebd9d2..dedfe1cb4 100644 --- a/plugins/upower/fu-plugin-upower.c +++ b/plugins/upower/fu-plugin-upower.c @@ -164,7 +164,7 @@ fu_plugin_update_prepare (FuPlugin *plugin, g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW, - "Cannot install update when battery " + "Cannot install update when system battery " "is not at least %" G_GUINT64_FORMAT "%% unless forced", data->minimum_battery); return FALSE; diff --git a/src/fu-engine.c b/src/fu-engine.c index 4125b768d..7c04bc1a8 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -129,8 +129,6 @@ static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE (FuEngine, fu_engine, G_TYPE_OBJECT) -#define FU_ENGINE_BATTERY_LEVEL_THRESHOLD 10 /* % */ - static void fu_engine_emit_changed (FuEngine *self) { @@ -2625,10 +2623,9 @@ fu_engine_device_prepare (FuEngine *self, return FALSE; } - /* check battery level is sane -- if the device needs a higher - * threshold then it can be checked in FuDevice->prepare() */ + /* check battery level is sane */ if (fu_device_get_battery_level (device) > 0 && - fu_device_get_battery_level (device) < FU_ENGINE_BATTERY_LEVEL_THRESHOLD) { + fu_device_get_battery_level (device) < fu_device_get_battery_threshold (device)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW,