Navigation Menu

Skip to content

Commit

Permalink
[battery-udev] Refresh all udev properties on heartbeat. Fixes JB#48324
Browse files Browse the repository at this point in the history
There might not be udev notification about every battery capacity
percent value change. While this is usually harmless when battery
is sufficiently full, it can cause issues like missed battery low
notifications and/or delay battery empty shutdown so much that
battery gets too depleted for regular bootup.

Poll power supply device properties in process watchdog heartbeat
pace i.e. about every 36 seconds of uptime not spent in suspend.

Periodic udev polling is enabled by default, but can be disabled
via mce configuration.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Jun 25, 2020
1 parent a01dacd commit 2261f93
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
19 changes: 19 additions & 0 deletions inifiles/battery-udev-settings.ini
Expand Up @@ -26,3 +26,22 @@
# Default is:
#
# RefreshOnNotify = false

# Many/most of devices do not send udev notifications
# on every battery capacity percent change. Most of the
# times this is harmless. However it can also cause
# battery empty shutdown to be delayed so much that
# battery is too depleted for regular bootup.
#
# To avoid this udev battery plugin polls all power
# supply devices in process watchdog heartbeat pace
# i.e. about every 36 seconds of uptime not spent in
# suspend.
#
# To disable this periodic polling:
#
# RefreshOnHeartbeat = false
#
# Default is:
#
# RefreshOnHeartbeat = true
76 changes: 76 additions & 0 deletions modules/battery-udev.c
Expand Up @@ -82,6 +82,10 @@
#define MCE_CONF_BATTERY_UDEV_REFRESH_ON_NOTIFY "RefreshOnNotify"
#define DEFAULT_BATTERY_UDEV_REFRESH_ON_NOTIFY false

/** Setting for forced refresh on system heartbeat */
#define MCE_CONF_BATTERY_UDEV_REFRESH_ON_HEARTBEAT "RefreshOnHeartbeat"
#define DEFAULT_BATTERY_UDEV_REFRESH_ON_HEARTBEAT true

/** Delay between udev notifications and battery state evaluation
*
* The purpose is to increase chances of getting battery and
Expand Down Expand Up @@ -311,6 +315,14 @@ static gboolean udevtracker_refresh_cb (gpointer aptr);
static void udevtracker_schedule_refresh(void);
static void udevtracker_cancel_refresh (void);

/* ------------------------------------------------------------------------- *
* DATAPIPE_HANDLERS
* ------------------------------------------------------------------------- */

static void mcebat_datapipe_heartbeat_event_cb(gconstpointer data);
static void mcebat_datapipe_init (void);
static void mcebat_datapipe_quit (void);

/* ------------------------------------------------------------------------- *
* G_MODULE
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -418,6 +430,9 @@ static const char * const udevproperty_used_keys[] = {
/** Cached MCE_CONF_BATTERY_UDEV_REFRESH_ON_NOTIFY value */
static bool mcebat_refresh_on_notify = DEFAULT_BATTERY_UDEV_REFRESH_ON_NOTIFY;

/** Cached MCE_CONF_BATTERY_UDEV_REFRESH_ON_HEARTBEAT value */
static bool mcebat_refresh_on_heartbeat = DEFAULT_BATTERY_UDEV_REFRESH_ON_HEARTBEAT;

/* ========================================================================= *
* CLIENT
* ========================================================================= */
Expand Down Expand Up @@ -2138,6 +2153,60 @@ static void udevtracker_cancel_refresh(void)
}
}

/* ========================================================================= *
* DATAPIPE_HANDLERS
* ========================================================================= */

/** Change notifications for heartbeat_event_pipe
*
* @param data (unused dummy parameter)
*/
static void mcebat_datapipe_heartbeat_event_cb(gconstpointer data)
{
(void)data;

mce_log(LL_DEBUG, "ENTER - refresh on heartbeat");

if( mcebat_refresh_on_heartbeat && udevtracker_object )
udevtracker_refresh_all(udevtracker_object);

mce_log(LL_DEBUG, "LEAVE - refresh on heartbeat");
}

/** Array of datapipe handlers */
static datapipe_handler_t mcebat_datapipe_handlers[] =
{
// output triggers
{
.datapipe = &heartbeat_event_pipe,
.output_cb = mcebat_datapipe_heartbeat_event_cb,
},
// sentinel
{
.datapipe = 0,
}
};

static datapipe_bindings_t mcebat_datapipe_bindings =
{
.module = "battery_udev",
.handlers = mcebat_datapipe_handlers,
};

/** Append triggers/filters to datapipes
*/
static void mcebat_datapipe_init(void)
{
mce_datapipe_init_bindings(&mcebat_datapipe_bindings);
}

/** Remove triggers/filters from datapipes
*/
static void mcebat_datapipe_quit(void)
{
mce_datapipe_quit_bindings(&mcebat_datapipe_bindings);
}

/* ========================================================================= *
* G_MODULE
* ========================================================================= */
Expand Down Expand Up @@ -2166,6 +2235,11 @@ mcebat_init_settings(void)
mce_conf_get_bool(MCE_CONF_BATTERY_UDEV_SETTINGS_GROUP,
MCE_CONF_BATTERY_UDEV_REFRESH_ON_NOTIFY,
DEFAULT_BATTERY_UDEV_REFRESH_ON_NOTIFY);

mcebat_refresh_on_heartbeat =
mce_conf_get_bool(MCE_CONF_BATTERY_UDEV_SETTINGS_GROUP,
MCE_CONF_BATTERY_UDEV_REFRESH_ON_HEARTBEAT,
DEFAULT_BATTERY_UDEV_REFRESH_ON_HEARTBEAT);
}

/** Init function for the battery and charger module
Expand All @@ -2184,6 +2258,7 @@ G_MODULE_EXPORT const gchar *g_module_check_init(GModule *module)
udevproperty_init_types();

mcebat_dbus_init();
mcebat_datapipe_init();

/* Initial udev probing can take a long time.
* Do it from idle callback in order not to delay
Expand All @@ -2206,6 +2281,7 @@ G_MODULE_EXPORT void g_module_unload(GModule *module)
if( mcebat_init_tracker_id )
g_source_remove(mcebat_init_tracker_id), mcebat_init_tracker_id = 0;

mcebat_datapipe_quit();
mcebat_dbus_quit();

udevtracker_delete(udevtracker_object), udevtracker_object = 0;
Expand Down

0 comments on commit 2261f93

Please sign in to comment.