fbd-dev-led: Sort leds by priority

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 <agx@sigxcpu.org>
This commit is contained in:
Guido Günther
2025-05-06 14:54:52 +00:00
parent 651c4f9fac
commit f9f248ef23
9 changed files with 57 additions and 7 deletions
+1
View File
@@ -71,6 +71,7 @@ fbd_dev_led_flash_class_init (FbdDevLedFlashClass *klass)
static void static void
fbd_dev_led_flash_init (FbdDevLedFlash *self) fbd_dev_led_flash_init (FbdDevLedFlash *self)
{ {
fbd_dev_led_set_priority (FBD_DEV_LED (self), 5);
} }
+1
View File
@@ -195,6 +195,7 @@ fbd_dev_led_multicolor_class_init (FbdDevLedMulticolorClass *klass)
static void static void
fbd_dev_led_multicolor_init (FbdDevLedMulticolor *self) fbd_dev_led_multicolor_init (FbdDevLedMulticolor *self)
{ {
fbd_dev_led_set_priority (FBD_DEV_LED (self), 50);
} }
+1
View File
@@ -18,5 +18,6 @@ G_BEGIN_DECLS
GUdevDevice *fbd_dev_led_get_device (FbdDevLed *led); 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_max_brightness (FbdDevLed *led, guint max_brightness);
void fbd_dev_led_set_supported_color (FbdDevLed *led, FbdFeedbackLedColor color); void fbd_dev_led_set_supported_color (FbdDevLed *led, FbdFeedbackLedColor color);
void fbd_dev_led_set_priority (FbdDevLed *self, int priority);
G_END_DECLS G_END_DECLS
+1
View File
@@ -75,6 +75,7 @@ fbd_dev_led_qcom_multicolor_class_init (FbdDevLedQcomMulticolorClass *klass)
static void static void
fbd_dev_led_qcom_multicolor_init (FbdDevLedQcomMulticolor *self) fbd_dev_led_qcom_multicolor_init (FbdDevLedQcomMulticolor *self)
{ {
fbd_dev_led_set_priority (FBD_DEV_LED (self), 60);
} }
+1
View File
@@ -141,6 +141,7 @@ fbd_dev_led_qcom_class_init (FbdDevLedQcomClass *klass)
static void static void
fbd_dev_led_qcom_init (FbdDevLedQcom *self) fbd_dev_led_qcom_init (FbdDevLedQcom *self)
{ {
fbd_dev_led_set_priority (FBD_DEV_LED (self), 20);
} }
+28
View File
@@ -1,5 +1,7 @@
/* /*
* Copyright (C) 2020 Purism SPC * Copyright (C) 2020 Purism SPC
* 2025 The Phosh Developers
*
* SPDX-License-Identifier: GPL-3.0+ * SPDX-License-Identifier: GPL-3.0+
* Author: Guido Günther <agx@sigxcpu.org> * Author: Guido Günther <agx@sigxcpu.org>
* *
@@ -34,6 +36,7 @@ typedef struct _FbdDevLedPrivate {
GUdevDevice *dev; GUdevDevice *dev;
guint max_brightness; guint max_brightness;
int priority;
FbdFeedbackLedColor color; FbdFeedbackLedColor color;
} FbdDevLedPrivate; } FbdDevLedPrivate;
@@ -251,6 +254,7 @@ fbd_dev_led_class_init (FbdDevLedClass *klass)
static void static void
fbd_dev_led_init (FbdDevLed *self) 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; 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;
}
+1
View File
@@ -27,6 +27,7 @@ gboolean fbd_dev_led_start_periodic (FbdDevLed *led,
guint max_brightness_percentage, guint max_brightness_percentage,
guint freq); guint freq);
gboolean fbd_dev_led_supports_color (FbdDevLed *led, FbdFeedbackLedColor color); gboolean fbd_dev_led_supports_color (FbdDevLed *led, FbdFeedbackLedColor color);
int fbd_dev_led_get_priority (FbdDevLed *self);
struct _FbdDevLedClass { struct _FbdDevLedClass {
GObjectClass parent_class; GObjectClass parent_class;
+18 -7
View File
@@ -43,6 +43,7 @@ static void initable_iface_init (GInitableIface *iface);
G_DEFINE_TYPE_WITH_CODE (FbdDevLeds, fbd_dev_leds, G_TYPE_OBJECT, G_DEFINE_TYPE_WITH_CODE (FbdDevLeds, fbd_dev_leds, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)); G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init));
static FbdDevLed * static FbdDevLed *
find_led_by_color (FbdDevLeds *self, FbdFeedbackLedColor color) 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 static gboolean
initable_init (GInitable *initable, initable_init (GInitable *initable,
GCancellable *cancellable, GCancellable *cancellable,
@@ -117,7 +128,7 @@ initable_init (GInitable *initable,
const gchar * const subsystems[] = { LED_SUBSYSTEM, NULL }; const gchar * const subsystems[] = { LED_SUBSYSTEM, NULL };
FbdDevLeds *self = FBD_DEV_LEDS (initable); FbdDevLeds *self = FBD_DEV_LEDS (initable);
g_autolist (GUdevDevice) leds = NULL; g_autolist (GUdevDevice) leds = NULL;
gboolean found = FALSE; GSList *usable_leds = NULL;
self->client = g_udev_client_new (subsystems); self->client = g_udev_client_new (subsystems);
@@ -135,21 +146,21 @@ initable_init (GInitable *initable,
led = probe_led (dev, &err); led = probe_led (dev, &err);
if (led) { if (led)
self->leds = g_slist_append (self->leds, led); usable_leds = g_slist_append (usable_leds, led);
found = TRUE;
}
} }
/* TODO: listen for new leds via udev events */ /* 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_set_error (error,
G_FILE_ERROR, G_FILE_ERROR_FAILED, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"No usable LEDs found"); "No usable LEDs found");
} }
return found; return !!usable_leds;
} }
static void static void
+5
View File
@@ -36,6 +36,7 @@ test_fbd_dev_led_simple (FbdUmockdevFixture *fixture, gconstpointer unused)
led = fbd_dev_led_new (dev, &err); led = fbd_dev_led_new (dev, &err);
g_assert_no_error (err); g_assert_no_error (err);
g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 255); 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_supports_color (led, FBD_FEEDBACK_LED_COLOR_BLUE));
g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50));
g_assert_finalize_object (led); 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); led = fbd_dev_led_multicolor_new (dev, &err);
g_assert_no_error (err); g_assert_no_error (err);
g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 248); 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_supports_color (led, FBD_FEEDBACK_LED_COLOR_BLUE));
g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); 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); led = fbd_dev_led_flash_new (dev, &err);
g_assert_no_error (err); g_assert_no_error (err);
g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 255); 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_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, 50));
g_assert_true (fbd_dev_led_start_periodic (led, 50, 0)); 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); led = fbd_dev_led_qcom_new (dev, &err);
g_assert_no_error (err); g_assert_no_error (err);
g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 511); 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_supports_color (led, FBD_FEEDBACK_LED_COLOR_WHITE));
g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50));
g_assert_finalize_object (led); 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); led = fbd_dev_led_qcom_multicolor_new (dev, &err);
g_assert_no_error (err); g_assert_no_error (err);
g_assert_cmpint (fbd_dev_led_get_max_brightness (led), ==, 511); 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_supports_color (led, FBD_FEEDBACK_LED_COLOR_BLUE));
g_assert_true (fbd_dev_led_start_periodic (led, 50, 50)); g_assert_true (fbd_dev_led_start_periodic (led, 50, 50));