Merge branch 'end-feedback' into 'main'
feedback-manager: End too noisy feedbacks on profile level change Closes #13, #55, and #35 See merge request Librem5/feedbackd!128
This commit is contained in:
+65
-3
@@ -343,8 +343,8 @@ fbd_event_get_timeout (FbdEvent *self)
|
||||
void
|
||||
fbd_event_add_feedback (FbdEvent *self, FbdFeedbackBase *feedback)
|
||||
{
|
||||
self->feedbacks = g_slist_prepend (self->feedbacks, g_object_ref(feedback));
|
||||
g_object_set_data (G_OBJECT (feedback), "event-id", GUINT_TO_POINTER(self->id));
|
||||
self->feedbacks = g_slist_prepend (self->feedbacks, g_object_ref (feedback));
|
||||
g_object_set_data (G_OBJECT (feedback), "event-id", GUINT_TO_POINTER (self->id));
|
||||
g_signal_connect_object (feedback,
|
||||
"ended",
|
||||
(GCallback) on_fb_ended,
|
||||
@@ -361,10 +361,26 @@ fbd_event_get_feedbacks (FbdEvent *self)
|
||||
int
|
||||
fbd_event_remove_feedback (FbdEvent *self, FbdFeedbackBase *feedback)
|
||||
{
|
||||
guint len;
|
||||
|
||||
g_return_val_if_fail (FBD_IS_EVENT (self), 0);
|
||||
|
||||
if (!self->feedbacks)
|
||||
return 0;
|
||||
|
||||
if (g_slist_index (self->feedbacks, feedback) >= 0) {
|
||||
g_signal_handlers_disconnect_by_data (feedback, self);
|
||||
/* Drop our reference, feedbacks end themselves when unref'ed */
|
||||
g_object_unref (feedback);
|
||||
}
|
||||
|
||||
self->feedbacks = g_slist_remove (self->feedbacks, feedback);
|
||||
return g_slist_length (self->feedbacks);
|
||||
|
||||
len = g_slist_length (self->feedbacks);
|
||||
if (!len)
|
||||
check_ended (self);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -414,6 +430,52 @@ fbd_event_end_feedbacks (FbdEvent *self)
|
||||
g_slist_foreach (self->feedbacks, (GFunc)fbd_feedback_end, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* fbd_event_end_feedbacks_by_level:
|
||||
* @self: The Event
|
||||
* @level: The profile level
|
||||
*
|
||||
* End all feedback strictly above the given profile level.
|
||||
*/
|
||||
void
|
||||
fbd_event_end_feedbacks_by_level (FbdEvent *self, guint level)
|
||||
{
|
||||
g_autoptr (GSList) feedbacks = NULL;
|
||||
guint num = 0;
|
||||
|
||||
g_return_if_fail (FBD_IS_EVENT (self));
|
||||
/* Copy the list as we will remove feedbacks from self->feedbacks */
|
||||
feedbacks = g_slist_copy (fbd_event_get_feedbacks (self));
|
||||
|
||||
for (GSList *l = feedbacks; l; l = l->next) {
|
||||
FbdFeedbackBase *fb = FBD_FEEDBACK_BASE (l->data);
|
||||
guint event_level;
|
||||
|
||||
event_level = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (fb), "fbd-level"));
|
||||
if (event_level > level)
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num == 0)
|
||||
return;
|
||||
|
||||
g_debug ("Will end %d feedbacks of event %s", num, fbd_event_get_event (self));
|
||||
/* Set 'explicit' if we end all remaining feedbacks */
|
||||
if (num == g_slist_length (self->feedbacks))
|
||||
fbd_event_set_end_reason (self, FBD_EVENT_END_REASON_EXPLICIT);
|
||||
|
||||
for (GSList *l = feedbacks; l; l = l->next) {
|
||||
FbdFeedbackBase *fb = FBD_FEEDBACK_BASE (l->data);
|
||||
guint event_level;
|
||||
|
||||
event_level = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (fb), "fbd-level"));
|
||||
if (event_level > level) {
|
||||
fbd_event_remove_feedback (self, fb);
|
||||
fbd_feedback_end (fb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fbd_event_get_feedbacks_ended:
|
||||
* @self: The Event
|
||||
|
||||
@@ -47,6 +47,7 @@ int fbd_event_remove_feedback (FbdEvent *self,
|
||||
FbdFeedbackBase *feedback);
|
||||
void fbd_event_run_feedbacks (FbdEvent *self);
|
||||
void fbd_event_end_feedbacks (FbdEvent *self);
|
||||
void fbd_event_end_feedbacks_by_level (FbdEvent *self, guint level);
|
||||
gboolean fbd_event_get_feedbacks_ended (FbdEvent *self);
|
||||
const char *fbd_event_get_sender (FbdEvent *self);
|
||||
|
||||
|
||||
@@ -201,8 +201,6 @@ on_profile_changed (FbdFeedbackManager *self, GParamSpec *psepc, gpointer unused
|
||||
|
||||
if (!fbd_feedback_manager_set_profile (self, pname))
|
||||
g_warning ("Invalid profile '%s'", pname);
|
||||
|
||||
/* TODO: end running feedbacks that aren't allowed in new profile immediately */
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -418,7 +416,7 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object,
|
||||
feedbacks = fbd_feedback_theme_lookup_feedback (self->theme, level, event);
|
||||
if (feedbacks) {
|
||||
for (l = feedbacks; l; l = l->next) {
|
||||
FbdFeedbackBase *fb = l->data;
|
||||
FbdFeedbackBase *fb = FBD_FEEDBACK_BASE (l->data);
|
||||
|
||||
if (fbd_feedback_is_available (FBD_FEEDBACK_BASE (fb))) {
|
||||
fbd_event_add_feedback (event, fb);
|
||||
@@ -626,6 +624,20 @@ fbd_feedback_manager_load_theme (FbdFeedbackManager *self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cancel_running (FbdFeedbackManager *self)
|
||||
{
|
||||
g_autoptr (GList) running = g_hash_table_get_values (self->events);
|
||||
|
||||
for (GList *l = running; l ; l = l->next) {
|
||||
FbdEvent *event = FBD_EVENT (l->data);
|
||||
|
||||
fbd_event_end_feedbacks_by_level (event, self->level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
fbd_feedback_manager_set_profile (FbdFeedbackManager *self, const gchar *profile)
|
||||
{
|
||||
@@ -645,5 +657,8 @@ fbd_feedback_manager_set_profile (FbdFeedbackManager *self, const gchar *profile
|
||||
self->level = level;
|
||||
lfb_gdbus_feedback_set_profile (LFB_GDBUS_FEEDBACK (self), profile);
|
||||
g_settings_set_string (self->settings, FEEDBACKD_KEY_PROFILE, profile);
|
||||
|
||||
cancel_running (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,8 @@ fbd_feedback_theme_lookup_feedback (FbdFeedbackTheme *self,
|
||||
FbdFeedbackBase *feedback = fbd_feedback_profile_get_feedback (profile,
|
||||
fbd_event_get_event (event));
|
||||
if (feedback) {
|
||||
feedbacks = g_slist_prepend (feedbacks, g_object_ref(feedback));
|
||||
g_object_set_data (G_OBJECT (feedback), "fbd-level", GUINT_TO_POINTER (i));
|
||||
feedbacks = g_slist_prepend (feedbacks, g_object_ref (feedback));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,15 +25,15 @@ void fbd_feedback_theme_update (FbdFeedbackTheme *self, FbdFeedba
|
||||
|
||||
const char *fbd_feedback_theme_get_name (FbdFeedbackTheme *self);
|
||||
void fbd_feedback_theme_set_name (FbdFeedbackTheme *self, const char *name);
|
||||
void fbd_feedback_theme_set_parent_name (FbdFeedbackTheme *self,
|
||||
const char *parent_name);
|
||||
void fbd_feedback_theme_set_parent_name (FbdFeedbackTheme *self,
|
||||
const char *parent_name);
|
||||
const char *fbd_feedback_theme_get_parent_name (FbdFeedbackTheme *self);
|
||||
void fbd_feedback_theme_add_profile (FbdFeedbackTheme *self,
|
||||
FbdFeedbackProfile *profile);
|
||||
FbdFeedbackProfile *fbd_feedback_theme_get_profile (FbdFeedbackTheme *self, const char *name);
|
||||
|
||||
GSList *fbd_feedback_theme_lookup_feedback (FbdFeedbackTheme *self,
|
||||
FbdFeedbackProfileLevel profile,
|
||||
FbdEvent *event);
|
||||
GSList *fbd_feedback_theme_lookup_feedback (FbdFeedbackTheme *self,
|
||||
FbdFeedbackProfileLevel profile,
|
||||
FbdEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+86
-30
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Purism SPC
|
||||
* 2023-2024 The Phosh Developers
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0+
|
||||
* Author: Guido Günther <agx@sigxcpu.org>
|
||||
*/
|
||||
@@ -12,7 +14,7 @@
|
||||
static void
|
||||
test_fbd_event (void)
|
||||
{
|
||||
g_autoptr(FbdEvent) event = NULL;
|
||||
g_autoptr (FbdEvent) event = NULL;
|
||||
g_autofree gchar *appid = NULL;
|
||||
g_autofree gchar *name = NULL;
|
||||
g_autofree gchar *sender = NULL;
|
||||
@@ -50,9 +52,9 @@ static void
|
||||
test_fbd_event_feedback (void)
|
||||
{
|
||||
GSList *feedbacks;
|
||||
g_autoptr(FbdEvent) event = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback2 = NULL;
|
||||
FbdEvent *event = NULL;
|
||||
FbdFeedbackDummy *feedback1 = NULL;
|
||||
FbdFeedbackDummy *feedback2 = NULL;
|
||||
|
||||
event = fbd_event_new (1, TEST_APP_ID, TEST_EVENT, -1, NULL);
|
||||
feedback1 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
@@ -61,21 +63,21 @@ test_fbd_event_feedback (void)
|
||||
feedbacks = fbd_event_get_feedbacks (event);
|
||||
g_assert_cmpint (g_slist_length (feedbacks), ==, 0);
|
||||
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
feedbacks = fbd_event_get_feedbacks (event);
|
||||
g_assert_cmpint (g_slist_length (feedbacks), ==, 1);
|
||||
|
||||
/* Remove non existing feedback */
|
||||
fbd_event_remove_feedback (event, FBD_FEEDBACK_BASE(feedback2));
|
||||
fbd_event_remove_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
feedbacks = fbd_event_get_feedbacks (event);
|
||||
g_assert_cmpint (g_slist_length (feedbacks), ==, 1);
|
||||
|
||||
fbd_event_remove_feedback (event, FBD_FEEDBACK_BASE(feedback1));
|
||||
fbd_event_remove_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
feedbacks = fbd_event_get_feedbacks (event);
|
||||
g_assert_cmpint (g_slist_length (feedbacks), ==, 0);
|
||||
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback2));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
feedbacks = fbd_event_get_feedbacks (event);
|
||||
g_assert_cmpint (g_slist_length (feedbacks), ==, 2);
|
||||
|
||||
@@ -83,6 +85,11 @@ test_fbd_event_feedback (void)
|
||||
fbd_event_end_feedbacks (event);
|
||||
/* Dummy feedback ends immediately */
|
||||
g_assert_true (fbd_event_get_feedbacks_ended (event));
|
||||
|
||||
/* event holds a ref on the feedbacks so finalize it first */
|
||||
g_assert_finalize_object (event);
|
||||
g_assert_finalize_object (feedback2);
|
||||
g_assert_finalize_object (feedback1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -96,16 +103,17 @@ on_feedbacks_ended (FbdEvent *event, gboolean *ended)
|
||||
static void
|
||||
test_fbd_event_feedback_ended (void)
|
||||
{
|
||||
g_autoptr(FbdEvent) event = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback2 = NULL;
|
||||
g_autoptr (FbdEvent) event = NULL;
|
||||
g_autoptr (FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr (FbdFeedbackDummy) feedback2 = NULL;
|
||||
gboolean ended = FALSE;
|
||||
|
||||
event = fbd_event_new (1, TEST_APP_ID, TEST_EVENT, FBD_EVENT_TIMEOUT_ONESHOT, NULL);
|
||||
feedback1 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
|
||||
feedback2 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback2));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
|
||||
g_signal_connect (event, "feedbacks-ended",
|
||||
(GCallback)on_feedbacks_ended, &ended);
|
||||
@@ -114,19 +122,65 @@ test_fbd_event_feedback_ended (void)
|
||||
g_assert_true (ended);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_fbd_event_feedback_end_by_level (void)
|
||||
{
|
||||
FbdEvent *event;
|
||||
FbdFeedbackDummy *feedback1, *feedback2;
|
||||
gboolean ended;
|
||||
|
||||
feedback1 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
g_object_set_data (G_OBJECT (feedback1), "fbd-level", GUINT_TO_POINTER (10));
|
||||
|
||||
feedback2 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
g_object_set_data (G_OBJECT (feedback2), "fbd-level", GUINT_TO_POINTER (5));
|
||||
|
||||
event = fbd_event_new (1, TEST_APP_ID, TEST_EVENT, FBD_EVENT_TIMEOUT_ONESHOT, NULL);
|
||||
g_signal_connect (event, "feedbacks-ended",
|
||||
(GCallback)on_feedbacks_ended, &ended);
|
||||
|
||||
/* End all feedback at once */
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
fbd_event_end_feedbacks_by_level (event, 3);
|
||||
g_assert_cmpint (g_slist_length (fbd_event_get_feedbacks (event)), ==, 0);
|
||||
g_assert_cmpint (fbd_event_get_end_reason (event), ==, FBD_EVENT_END_REASON_EXPLICIT);
|
||||
g_assert_true (ended);
|
||||
|
||||
/* End feedback one by one */
|
||||
ended = FALSE;
|
||||
fbd_event_set_end_reason (event, FBD_EVENT_END_REASON_NATURAL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
fbd_event_end_feedbacks_by_level (event, 7);
|
||||
g_assert_cmpint (g_slist_length (fbd_event_get_feedbacks (event)), ==, 1);
|
||||
g_assert_cmpint (fbd_event_get_end_reason (event), ==, FBD_EVENT_END_REASON_NATURAL);
|
||||
g_assert_false (ended);
|
||||
fbd_event_end_feedbacks_by_level (event, 4);
|
||||
g_assert_cmpint (g_slist_length (fbd_event_get_feedbacks (event)), ==, 0);
|
||||
g_assert_cmpint (fbd_event_get_end_reason (event), ==, FBD_EVENT_END_REASON_EXPLICIT);
|
||||
g_assert_true (ended);
|
||||
|
||||
g_assert_finalize_object (event);
|
||||
g_assert_finalize_object (feedback2);
|
||||
g_assert_finalize_object (feedback1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_fbd_event_feedback_loop (void)
|
||||
{
|
||||
g_autoptr(FbdEvent) event = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback2 = NULL;
|
||||
g_autoptr (FbdEvent) event = NULL;
|
||||
g_autoptr (FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr (FbdFeedbackDummy) feedback2 = NULL;
|
||||
gboolean ended = FALSE;
|
||||
|
||||
event = fbd_event_new (1, TEST_APP_ID, TEST_EVENT, FBD_EVENT_TIMEOUT_LOOP, NULL);
|
||||
feedback1 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
feedback2 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback2));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
|
||||
g_signal_connect (event, "feedbacks-ended",
|
||||
(GCallback)on_feedbacks_ended, &ended);
|
||||
@@ -139,16 +193,16 @@ test_fbd_event_feedback_loop (void)
|
||||
static void
|
||||
test_fbd_event_feedback_timeout (void)
|
||||
{
|
||||
g_autoptr(FbdEvent) event = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr(FbdFeedbackDummy) feedback2 = NULL;
|
||||
g_autoptr (FbdEvent) event = NULL;
|
||||
g_autoptr (FbdFeedbackDummy) feedback1 = NULL;
|
||||
g_autoptr (FbdFeedbackDummy) feedback2 = NULL;
|
||||
gboolean ended = FALSE;
|
||||
|
||||
event = fbd_event_new (1, TEST_APP_ID, TEST_EVENT, 1, NULL);
|
||||
feedback1 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback1));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback1));
|
||||
feedback2 = g_object_new (FBD_TYPE_FEEDBACK_DUMMY, NULL);
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE(feedback2));
|
||||
fbd_event_add_feedback (event, FBD_FEEDBACK_BASE (feedback2));
|
||||
|
||||
g_signal_connect (event, "feedbacks-ended",
|
||||
(GCallback)on_feedbacks_ended, &ended);
|
||||
@@ -163,11 +217,13 @@ main (gint argc, gchar *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func("/feedbackd/fbd/event/new", test_fbd_event);
|
||||
g_test_add_func("/feedbackd/fbd/event/feedbacks/props", test_fbd_event_feedback);
|
||||
g_test_add_func("/feedbackd/fbd/event/feedbacks/ended", test_fbd_event_feedback_ended);
|
||||
g_test_add_func("/feedbackd/fbd/event/feedbacks/loop", test_fbd_event_feedback_loop);
|
||||
g_test_add_func("/feedbackd/fbd/event/feedbacks/timeout", test_fbd_event_feedback_timeout);
|
||||
g_test_add_func ("/feedbackd/fbd/event/new", test_fbd_event);
|
||||
g_test_add_func ("/feedbackd/fbd/event/feedbacks/props", test_fbd_event_feedback);
|
||||
g_test_add_func ("/feedbackd/fbd/event/feedbacks/ended", test_fbd_event_feedback_ended);
|
||||
g_test_add_func ("/feedbackd/fbd/event/feedbacks/end_by_level",
|
||||
test_fbd_event_feedback_end_by_level);
|
||||
g_test_add_func ("/feedbackd/fbd/event/feedbacks/loop", test_fbd_event_feedback_loop);
|
||||
g_test_add_func ("/feedbackd/fbd/event/feedbacks/timeout", test_fbd_event_feedback_timeout);
|
||||
|
||||
return g_test_run();
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user