Commit graph

1,919 commits

Author SHA1 Message Date
Fimeg
800a8fde18 charge thresholds: read and write them where they actually live
On a split gauge/charger the threshold attributes are on the charger, not
the battery, and upstream only looks at the battery — so a settable ceiling
reported as unsupported, and a write went to a path that does not exist.
Same supplier walk charge_type already uses. Also report the live value when
no hwdb CHARGE_LIMIT entry recommends a pair.
2026-08-24 14:04:28 -04:00
Fimeg
4a531856e2 project the tested ref onto the public forge
Fast-forward checked before the push, exact SHA read back after.
2026-08-23 20:55:08 -04:00
Fimeg
ca47424e47 add gettext for msgfmt
meson's policy/meson.build needs msgfmt to build the polkit policy file.
2026-08-23 20:23:19 -04:00
Fimeg
58d4e8842b review the commit that installs the gate 2026-08-23 20:15:47 -04:00
Fimeg
3a6399357b carry the publication gate on the candidate ref 2026-08-23 20:15:27 -04:00
Fimeg
9617021cbb add the publication gate this fork lacked
Upstream ships no CI in this tree, so the gate is meson's own contract:
configure, build, test, with the optional introspection and idevice halves
switched off so every run proves the same thing.
2026-08-23 19:41:36 -04:00
Fimeg
beb94dcd6f percentage-trusted: judge the source of the percentage, and set it on batteries
Two bugs, same shape as charge-type.

The heuristic assumed the percentage is derived from charge_full/energy_full.
When the kernel reports capacity directly - which is where upower actually
reads the percentage from - it is not derived from anything, so the
wrong-units failure the check guards against cannot occur. qcom-battery
reports capacity and no charge_full at all, so it failed a test against a
value it never uses and a good 56% reading was marked untrusted.

And like charge-type, the property was only ever set in UpDeviceSupply, so a
real battery reported the FALSE default regardless.

Short-circuit to trusted when capacity is present and in range; set the
property in UpDeviceSupplyBattery alongside charge-type.
2026-07-25 07:39:45 -04:00
Fimeg
f974714880 up-device-supply-battery: set charge-type on the class that backs real batteries
up-enumerator-udev.c tries UP_TYPE_DEVICE_SUPPLY_BATTERY first for every
power_supply device and only falls back to UP_TYPE_DEVICE_SUPPLY if that
fails to initialise, so a system battery is backed by UpDeviceSupplyBattery
and never runs UpDeviceSupply::refresh_device. charge-type was only ever set
there, so it sat at the UNKNOWN enum default - indistinguishable from the
driver not reporting it.

Verified on blueline: with 718e921 installed and the supplier walk correct,
upower still read charge-type: unknown while the charger read Fast.

Note charge_type (active regime) is not charge_types (settable profile list
already handled here for charge thresholds).
2026-07-25 07:29:50 -04:00
Fimeg
718e9210d7 up-device-supply: read charge_type from the supplying charger
On a discrete-PMIC platform the fuel gauge and the charger are separate
devices and only the charger knows the charge regime. On SDM845
qcom-battery is fuel-gauge@4000 and exposes no charge_type at all, while
pmi8998-charger is charger@1000 and does, so reading only the battery's
own attribute returned UNKNOWN on every refresh.

Follow the device links the kernel already publishes rather than guessing
which sibling supply is the charger:

  <native>/device/supplier:* -> /sys/devices/virtual/devlink/<s>--<c>
  <devlink>/supplier         -> the supplying device
  <supplier>/power_supply/<name>/charge_type

The battery's own attribute still wins when present, so this is inert on
hardware where the gauge reports charge_type itself.
2026-07-25 06:43:56 -04:00
Fimeg
628283fb20 up-types: recognize kernel's "N/A" spelling for CHARGE_TYPE_NONE
The kernel prints POWER_SUPPLY_CHARGE_TYPE_NONE as "N/A", not "None",
so up_device_charge_type_from_string() fell through to the warning
path and returned UNKNOWN instead of NONE on every refresh while
discharging.
2026-07-24 09:08:41 -04:00
Fimeg
f18b1a476c gitignore pycache and build dirs 2026-07-17 16:09:56 -04:00
Fimeg
5aae6d4c22 Expose ChargeType and PercentageTrusted on Device
Stock UPower maps the kernel power_supply 'status' to Device:State but
drops 'charge_type' entirely, so the entire fast/trickle/taper
distinction is invisible over D-Bus. A device reads 'Charging' the
whole constant-voltage tail, which is how a lock surface ends up
showing 'Charging N%' forever on a topped-off pack.

Add ChargeType (mirroring POWER_SUPPLY_CHARGE_TYPE_*) as a separate
uint property, read from sysfs 'charge_type' next to status. Also add
PercentageTrusted: capacity is derived from charge_full/energy_full,
and a driver change reporting wrong units makes a healthy pack read
~1%. Mark it untrusted when full is implausibly small vs design so
consumers can suppress the meaningless number.

Generated skeleton, lib props, Linux backend read, and introspection
XML all wired. Builds clean, self-test passes.
2026-07-17 16:09:44 -04:00
Kate Hsuan
3dc5323bf9 Release version 1.91.3
- Feature: up-device-battery: Prefer "Standard" over "Fast" charging (!316, #344)
- Fix: Resolve potential leaks (!327)
- Fix: Potential out-of-bound access (!328)
- Fix: Improve access control (!326)
- Fix: Remove unused code (!329)
- Fix: Asus battery charge threshold detection (!330, #347)
- CI: code refactoring (!324)

Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-07-02 15:39:04 +08:00
Kate Hsuan
83f86c75d2 rules: 60-upower-battery: Fix for Asus battery charge threshold detection
At boot, the Asus battery driver returns -ENODATA [1] to avoid resetting
charge threshold settings. This behavior prevents UPower's udev rules
from detecting the charge threshold feature. This issue can be resolved
by testing for the attribute's existence when matching udev rules, rather
than performing a read operation at boot.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers?id=186bf90

Resolves: #347
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-07-02 15:03:33 +08:00
Kate Hsuan
133e024e29 up-polkit: Drop unused variable
Variable 'error' is declared with g_autoptr(GError) but is never used
anywhere in up_polkit_finalize. No function in the body writes to
&error or reads from error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:10 +08:00
Kate Hsuan
6811b6e840 up-main: Set up correct timer_id for immediate exit
The return value of g_timeout_add() is discarded instead of being assigned to timer_id.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:10 +08:00
Kate Hsuan
56f57a0937 linux: up-kbd-backlight-led: Drop unused variable
Variable 'ret_str' is declared with g_autofree but is never assigned a
value or read anywhere in the function up_kbd_backlight_led_event_io.
It remains NULL throughout the function's lifetime.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:10 +08:00
Kate Hsuan
45f33eac8a up-kbd-backlight: Drop unused variable
Variable 'buf_now' is declared and initialized to NULL, freed via
g_free(buf_now), but is never assigned any value or read anywhere in the
function up_kbd_backlight_find. It is completely dead code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:10 +08:00
Kate Hsuan
f8b4e3c358 up-history: Drop unused enum
The enum values UP_HISTORY_PROGRESS and UP_HISTORY_LAST_SIGNAL are defined
but never referenced anywhere in the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:10 +08:00
Kate Hsuan
baacfe584c linux: up-device-supply-battery: drop unused variable
Struct members in _UpDeviceSupplyBattery is declared but never referenced
in any function in this file or elsewhere.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:10 +08:00
Kate Hsuan
ea964860e1 up-device-battery: free GError with Glib auto clean up
g_error() is always fatal (it calls abort() via G_LOG_LEVEL_ERROR), making
'return FALSE' unreachable dead code. The GError allocated by
g_file_set_contents() is also never freed before the process terminates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-04 14:39:00 +08:00
Kate Hsuan
95a162e789 up-device: Drop unused parameter
The 'history' parameter in up_device_history_filter() is declared but
never referenced.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-03 15:01:29 +08:00
Kate Hsuan
7bd44ba4ce libupower-glib: up-client: Test the NULL input parameter
The 'client' parameter of up_client_get_display_device() is never used in
the function body. Additionally, no g_return_val_if_fail input validation
is performed on the unused parameter, unlike all other public methods in
this file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-03 14:49:54 +08:00
Kate Hsuan
e5507e30a2 up-history: Fix access_control of the history files
g_file_set_contents() writes battery history files using default
permissions (typically 0644 with umask 0022). Since upower runs as a
system daemon, these world-readable files expose per-device
charge/discharge rate and timing patterns to all local users,
which can reveal system usage patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 23:42:16 +08:00
Kate Hsuan
19dabb1f3e up-device-battery: Fix access_control
g_file_set_contents() creates the state file with permissions
0666 & ~umask. Since UPower runs as a privileged system daemon, the
resulting file permissions depend entirely on the process umask. With a
permissive umask (e.g. 0000), the state file could be world-writable,
allowing unprivileged users to manipulate the charging-threshold-status
file and influence charge threshold behavior on next daemon startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 23:42:16 +08:00
Kate Hsuan
b3d545f260 linux: up-device-hid: Fix fd close guard to use >= 0 instead of > 0 in finalize
In up_device_hid_finalize(), the condition if (hid->priv->fd > 0) would
fail to close file descriptor 0, which is a valid fd. The sentinel value is
-1 (set in up_device_hid_init), so the correct guard is >= 0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 23:36:13 +08:00
Kate Hsuan
040e8291c7 linux: up-device-wup: Fix fd close guard to use >= 0 instead of > 0 in finalize
In up_device_wup_finalize(), the condition if (wup->priv->fd > 0) would
fail to close file descriptor 0, which is a valid fd. The sentinel value is
-1 (set in up_device_wup_init), so the correct guard is >= 0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 23:36:13 +08:00
Kate Hsuan
941f9c4b66 linux:up-input: Add defense-in-depth bounds check and fix style
In up_input_str_to_bitmask, the 'max_size' parameter (sizeof(bitmask) in bytes)
is passed directly as the max_tokens argument to g_strsplit(). On a 64-bit system
with SW_MAX=0x10, the bitmask array has NBITS(SW_MAX)=1 element (8 bytes),
but g_strsplit() is told it can return up to 8 tokens. The loop writes bitmask[j]
where j increments from 0 to g_strv_length(v)-1, so if the input string contains
more than 1 space-separated token, writes to bitmask[1] through bitmask[7]
overflow the array.

1. Extract max_elements variable and add explicit bounds check (j < max_elements)
in the loop condition. While g_strsplit already limits the token count, an explicit
guard prevents out-of-bounds writes if g_strsplit behavior changes or the logic is
refactored, providing defense-in-depth.

2. The variable v is managed by Glib auto clean up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 23:36:13 +08:00
Kate Hsuan
986ce9f18f tools: up-tool: Free the memory with GLib auto clean up
Free the memory	with GLib auto clean up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 16:44:51 +08:00
Kate Hsuan
7c05c1bc44 tools: up-tool: Fix a leak by freeing GMainLoop using GLib auto clean up
- Move the GMainLoop creation to the code path of the monitor function.
- Quit GMainLoop when receiving a signal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Security Scanner <scanner@automated>
2026-06-02 16:44:38 +08:00
Kate Hsuan
836cd94b0f up-tool: Free GPtrArray using Glib auto clean up
Free GPtrArray with Glib auto cleanup to prevent memory leak.

Co-authored by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 16:00:28 +08:00
Kate Hsuan
29943f53dd up-self-test: fix leak by freeing history_dir
Global pointer 'history_dir' is allocated via g_build_filename()
and modified in-place by mkdtemp(), but is never freed with g_free().
After rmdir(history_dir), the allocated string is leaked when the
test returns through g_test_run().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 15:46:13 +08:00
Kate Hsuan
52b859d7ba up-history: Fix floating point exception when resolution is 0
Avoid a potential crash in UPower by returning immediately if the
GetHistory() D-Bus call is invoked with a resolution value of 0.
When the resolution is 0, UPower crashes while calculating the
expected number of history records. Short-circuiting this call
prevents the invalid calculation entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 15:46:13 +08:00
Kate Hsuan
6d1d606cfc up-history: Fix a leak when getting the history data
g_ptr_array_new() is called without a free function, but items
are added to the list via g_object_ref(). When this array is later freed
with g_ptr_array_unref() in up_history_get_data(), the referenced
GObjects are never unreferenced, leaking memory on every call to
up_history_get_data() with a non-zero timespan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 15:46:09 +08:00
Kate Hsuan
2a369eeed7 linux: up-device-supply: Use g_autofreee to resolve leak
Replace manual g_free() with g_autofree to ensure the memory freed
when the function returns;

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 15:36:46 +08:00
Kate Hsuan
17643f13bb up-device-kbd-backlight: Free the variable when finalize the object
Free daemon and native when finalize the object.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 14:56:22 +08:00
Kate Hsuan
5e8672fc66 linux: up-device-bluez: Fix memory leak due to a reused pointer
In up_device_bluez_coldplug(), when the 'Appearance' property exists but
its value is 0, the GVariant 'v' is non-NULL. The if condition at line 186
evaluates to false (because the value is 0), and execution falls through to
the else-if at line 192, which overwrites 'v' with a new
g_dbus_proxy_get_cached_property(). The original GVariant from the
'Appearance' property is never unreffed.

The `g_autoptr (GVariant)` is used to ensure the allocated GVariant can be
autometically freed when up_device_bluez_coldplug() returns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 14:55:52 +08:00
Kate Hsuan
680082ee86 linux: up-backend: Free udev_enum when finalizing the object
up_backend_finalize does not free backend->priv->udev_enum. The field is
allocated in up_backend_coldplug via
g_object_new(UP_TYPE_ENUMERATOR_UDEV, ...) in up_backend_coldplug() and
freed in up_backend_unplug(), but the GObject finalize handler omits it.
If the object is destroyed without up_backend_unplug being called first,
udev_enum leaks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-06-02 14:55:04 +08:00
Kate Hsuan
43c23849a5 ci: fix meson parameter for doc generation
Fix ninja parameter when building the document.

Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-05-29 13:47:55 +08:00
Peter Hutterer
991fa101f0 ci: Revamp the CI to make more efficient use of ci-templates
The main changes:

- add the meson-build.sh helper script because it produces nicer output
  and more consistent behavior across jobs. Use that script together with
  MESON_ARGS as variables so the per-job configuration is easier
  visible.
- use the FDO_* variables for debian too and rely on ci-templates for
  images based on those variables
- always create containers, the ci-templates will skip creating those
  anyway if they already exist
- always install the extra deps we need for libgudev, this removes our
  exposure to distribution updates changing our test environment
- use a parallel:matrix for the backend jobs
- debian no longer installs the build-dep, let's use explicitly listed
  deps only

There is no more real need for scheduled pipelines, so the checks for
those have been removd.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-05-28 20:08:54 +10:00
Peter Hutterer
0c4794f072 ci: Avoid duplicate pipelines
If we have an open MR we don't need to run a separate non-MR pipeline.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-05-28 20:08:54 +10:00
Peter Hutterer
08578d1b87 ci: Use git diff --exit-code
Same thing, just more obvious

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-05-28 20:08:54 +10:00
Peter Hutterer
18f4a7ee8b ci: Use the ci-fairy job to check commit messages
Replace the custom signed-off-by job with one used across multiple fdo
projects. This one also checks a few more things including subject
lengths etc.

We don't want to run it on master so it doesn't fail after merging for
whatever reason (any error should be caught by the MR pipeline anyway).

And we need a higher git depth so ci-fairy can find the merge base.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-05-28 20:08:54 +10:00
Peter Hutterer
8f4a670de7 ci: Use a specific sha for ci-templates
Pulling in master means our CI may change as ci-templates change (and
exposes us to possible breakages/regressions). Let's pin a sha and only
update it when we actually have to.

And combine the two files from the same include so we don't need to
duplicate the sha.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-05-28 19:46:13 +10:00
Kate Hsuan
3676c71c32 HACKING: Add Signed-off-by tag in the commit message
- Signed-off-by tag should be included in the commit message.
- Update the commit message example.

Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-05-25 17:18:31 +08:00
Kate Hsuan
b40bce45cb ci: Add Signed-off-by check
Add a Signed-off-by check in the pre-commit stage when submitting the
merge request. If the Signed-off-by can't be found in the commit
message, git-signoff.py returns an error and lists all the commits without
the tag.

Co-authored-by: Cursor
Co-authored by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-05-25 17:01:27 +08:00
Armin Wolf
25303ba527 up-device-battery: Prefer "Standard" over "Fast" charging
When disabling the charging threshold feature upower will change the
charging strategy from "Long Life" to "Fast" if a battery supports
"Long Life", "Standard" and "Fast". This behavior is suboptimal
because "Fast" charging might wear down the battery over time, while
"Standard" is supposed to be used as the safe default.

Fix this by preferring "Standard" over "Fast" charging in such
situations.

Resolves: #344
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
2026-04-20 12:29:27 +02:00
Kate Hsuan
17f9e8dc5a Release version 1.91.2
- Feature: Skip the systemd inhibitor when performing CriticalPowerAction
  (!309)
- Feature: Introduce "Auto" CriticalPowerAction using systemd-logind
  Sleep() (!309)
- Fix: Test CanPowerOff() availability before calling PowerOff() (!311)
- Fix: Add charge limit support for systems providing only
  charge_control_end_threshold (!310, #342, #285)

Co-Authored-By: Cursor and Claude-4.6-sonnet
Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-04-01 16:20:02 +08:00
Kate Hsuan
61654b84af linux: up-backend: Test availability before calling systemd-logind PowerOff
Call CanPowerOff() to find the availability before calling PowerOff().
The priority of the Sleep() call should be higher than Ignore. That is the
final fallback call when the other critical power actions aren't
available.

Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-03-24 14:13:03 +08:00
Kate Hsuan
20a844b41e rules: 60-upower-battery: charge threshold is supported when start or end threshold is present
Add CHARGE_LIMIT support for systems only providing
charge_control_end_threshold. This allows UPower to configure charge
thresholds when the specific sysfs property is present.

Related: https://gitlab.freedesktop.org/upower/upower/-/merge_requests/308
Resolves: https://gitlab.freedesktop.org/upower/upower/-/issues/342

Signed-off-by: Kate Hsuan <hpa@redhat.com>
2026-03-23 17:06:14 +08:00