From f9f248ef230a32fcea44f3ab1d96be7bd7fde984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 25 Apr 2025 09:39:02 +0200 Subject: [PATCH] fbd-dev-led: Sort leds by priority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure we e.g. prefer multicolor leds over single color ones and those that can be on insuspend (qcom) over those that can't. We can extend this to allow to set the priority via udev/hwdb in the future. Signed-off-by: Guido Günther --- src/fbd-dev-led-flash.c | 1 + src/fbd-dev-led-multicolor.c | 1 + src/fbd-dev-led-priv.h | 1 + src/fbd-dev-led-qcom-multicolor.c | 1 + src/fbd-dev-led-qcom.c | 1 + src/fbd-dev-led.c | 28 ++++++++++++++++++++++++++++ src/fbd-dev-led.h | 1 + src/fbd-dev-leds.c | 25 ++++++++++++++++++------- tests/test-fbd-dev-led.c | 5 +++++ 9 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/fbd-dev-led-flash.c b/src/fbd-dev-led-flash.c index 32653cb..d0b6c46 100644 --- a/src/fbd-dev-led-flash.c +++ b/src/fbd-dev-led-flash.c @@ -71,6 +71,7 @@ fbd_dev_led_flash_class_init (FbdDevLedFlashClass *klass) static void fbd_dev_led_flash_init (FbdDevLedFlash *self) { + fbd_dev_led_set_priority (FBD_DEV_LED (self), 5); } diff --git a/src/fbd-dev-led-multicolor.c b/src/fbd-dev-led-multicolor.c index 47a55fb..30d02c3 100644 --- a/src/fbd-dev-led-multicolor.c +++ b/src/fbd-dev-led-multicolor.c @@ -195,6 +195,7 @@ fbd_dev_led_multicolor_class_init (FbdDevLedMulticolorClass *klass) static void fbd_dev_led_multicolor_init (FbdDevLedMulticolor *self) { + fbd_dev_led_set_priority (FBD_DEV_LED (self), 50); } diff --git a/src/fbd-dev-led-priv.h b/src/fbd-dev-led-priv.h index b2300b2..184f729 100644 --- a/src/fbd-dev-led-priv.h +++ b/src/fbd-dev-led-priv.h @@ -18,5 +18,6 @@ G_BEGIN_DECLS GUdevDevice *fbd_dev_led_get_device (FbdDevLed *led); void fbd_dev_led_set_max_brightness (FbdDevLed *led, guint max_brightness); void fbd_dev_led_set_supported_color (FbdDevLed *led, FbdFeedbackLedColor color); +void fbd_dev_led_set_priority (FbdDevLed *self, int priority); G_END_DECLS diff --git a/src/fbd-dev-led-qcom-multicolor.c b/src/fbd-dev-led-qcom-multicolor.c index ee42cff..45a2622 100644 --- a/src/fbd-dev-led-qcom-multicolor.c +++ b/src/fbd-dev-led-qcom-multicolor.c @@ -75,6 +75,7 @@ fbd_dev_led_qcom_multicolor_class_init (FbdDevLedQcomMulticolorClass *klass) static void fbd_dev_led_qcom_multicolor_init (FbdDevLedQcomMulticolor *self) { + fbd_dev_led_set_priority (FBD_DEV_LED (self), 60); } diff --git a/src/fbd-dev-led-qcom.c b/src/fbd-dev-led-qcom.c index c1abf24..69a5cff 100644 --- a/src/fbd-dev-led-qcom.c +++ b/src/fbd-dev-led-qcom.c @@ -141,6 +141,7 @@ fbd_dev_led_qcom_class_init (FbdDevLedQcomClass *klass) static void fbd_dev_led_qcom_init (FbdDevLedQcom *self) { + fbd_dev_led_set_priority (FBD_DEV_LED (self), 20); } diff --git a/src/fbd-dev-led.c b/src/fbd-dev-led.c index 351430e..2008e97 100644 --- a/src/fbd-dev-led.c +++ b/src/fbd-dev-led.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2020 Purism SPC + * 2025 The Phosh Developers + * * SPDX-License-Identifier: GPL-3.0+ * Author: Guido Günther * @@ -34,6 +36,7 @@ typedef struct _FbdDevLedPrivate { GUdevDevice *dev; guint max_brightness; + int priority; FbdFeedbackLedColor color; } FbdDevLedPrivate; @@ -251,6 +254,7 @@ fbd_dev_led_class_init (FbdDevLedClass *klass) static void fbd_dev_led_init (FbdDevLed *self) { + fbd_dev_led_set_priority (self, 10); } @@ -363,3 +367,27 @@ fbd_dev_led_set_max_brightness (FbdDevLed *led, guint max_brightness) priv->max_brightness = max_brightness; } + + +int +fbd_dev_led_get_priority (FbdDevLed *self) +{ + FbdDevLedPrivate *priv; + + g_return_val_if_fail (FBD_IS_DEV_LED (self), 0); + priv = fbd_dev_led_get_instance_private (self); + + return priv->priority; +} + + +void +fbd_dev_led_set_priority (FbdDevLed *self, int priority) +{ + FbdDevLedPrivate *priv; + + g_return_if_fail (FBD_IS_DEV_LED (self)); + priv = fbd_dev_led_get_instance_private (self); + + priv->priority = priority; +} diff --git a/src/fbd-dev-led.h b/src/fbd-dev-led.h index 0122ecd..6e143cf 100644 --- a/src/fbd-dev-led.h +++ b/src/fbd-dev-led.h @@ -27,6 +27,7 @@ gboolean fbd_dev_led_start_periodic (FbdDevLed *led, guint max_brightness_percentage, guint freq); gboolean fbd_dev_led_supports_color (FbdDevLed *led, FbdFeedbackLedColor color); +int fbd_dev_led_get_priority (FbdDevLed *self); struct _FbdDevLedClass { GObjectClass parent_class; diff --git a/src/fbd-dev-leds.c b/src/fbd-dev-leds.c index 467d1f9..634961b 100644 --- a/src/fbd-dev-leds.c +++ b/src/fbd-dev-leds.c @@ -43,6 +43,7 @@ static void initable_iface_init (GInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (FbdDevLeds, fbd_dev_leds, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)); + static FbdDevLed * find_led_by_color (FbdDevLeds *self, FbdFeedbackLedColor color) { @@ -109,6 +110,16 @@ probe_led (GUdevDevice *dev, GError **error) { } +static int +priority_cmp (gconstpointer a, gconstpointer b) +{ + int prio_a = fbd_dev_led_get_priority ((FbdDevLed *)a); + int prio_b = fbd_dev_led_get_priority ((FbdDevLed *)b); + + return prio_b - prio_a; +} + + static gboolean initable_init (GInitable *initable, GCancellable *cancellable, @@ -117,7 +128,7 @@ initable_init (GInitable *initable, const gchar * const subsystems[] = { LED_SUBSYSTEM, NULL }; FbdDevLeds *self = FBD_DEV_LEDS (initable); g_autolist (GUdevDevice) leds = NULL; - gboolean found = FALSE; + GSList *usable_leds = NULL; self->client = g_udev_client_new (subsystems); @@ -135,21 +146,21 @@ initable_init (GInitable *initable, led = probe_led (dev, &err); - if (led) { - self->leds = g_slist_append (self->leds, led); - found = TRUE; - } + if (led) + usable_leds = g_slist_append (usable_leds, led); } /* TODO: listen for new leds via udev events */ - if (!found) { + if (usable_leds) { + self->leds = g_slist_sort (usable_leds, priority_cmp); + } else { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "No usable LEDs found"); } - return found; + return !!usable_leds; } static void diff --git a/tests/test-fbd-dev-led.c b/tests/test-fbd-dev-led.c index 024e27a..afa0207 100644 --- a/tests/test-fbd-dev-led.c +++ b/tests/test-fbd-dev-led.c @@ -36,6 +36,7 @@ test_fbd_dev_led_simple (FbdUmockdevFixture *fixture, gconstpointer unused) led = fbd_dev_led_new (dev, &err); g_assert_no_error (err); g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 255); + g_assert_cmpint (fbd_dev_led_get_priority (led), ==, 10); g_assert_true (fbd_dev_led_supports_color (led, FBD_FEEDBACK_LED_COLOR_BLUE)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); g_assert_finalize_object (led); @@ -63,6 +64,7 @@ test_fbd_dev_led_multicolor (FbdUmockdevFixture *fixture, gconstpointer unused) led = fbd_dev_led_multicolor_new (dev, &err); g_assert_no_error (err); g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 248); + g_assert_cmpint (fbd_dev_led_get_priority (led), ==, 50); g_assert_true (fbd_dev_led_supports_color (led, FBD_FEEDBACK_LED_COLOR_BLUE)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); @@ -91,6 +93,7 @@ test_fbd_dev_led_flash (FbdUmockdevFixture *fixture, gconstpointer unused) led = fbd_dev_led_flash_new (dev, &err); g_assert_no_error (err); g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 255); + g_assert_cmpint (fbd_dev_led_get_priority (led), ==, 5); g_assert_true (fbd_dev_led_supports_color (led, FBD_FEEDBACK_LED_COLOR_FLASH)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 0)); @@ -120,6 +123,7 @@ test_fbd_dev_led_qcom_simple (FbdUmockdevFixture *fixture, gconstpointer unused) led = fbd_dev_led_qcom_new (dev, &err); g_assert_no_error (err); g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 511); + g_assert_cmpint (fbd_dev_led_get_priority (led), ==, 20); g_assert_true (fbd_dev_led_supports_color (led, FBD_FEEDBACK_LED_COLOR_WHITE)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); g_assert_finalize_object (led); @@ -147,6 +151,7 @@ test_fbd_dev_led_qcom_multicolor (FbdUmockdevFixture *fixture, gconstpointer unu led = fbd_dev_led_qcom_multicolor_new (dev, &err); g_assert_no_error (err); g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 511); + g_assert_cmpint (fbd_dev_led_get_priority (led), ==, 60); g_assert_true (fbd_dev_led_supports_color (led, FBD_FEEDBACK_LED_COLOR_BLUE)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50));