[calls] ringer: Restart ringer if quiet parameter changed
- From: Evangelos Ribeiro Tzaras <devrtz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [calls] ringer: Restart ringer if quiet parameter changed
- Date: Sun, 5 Dec 2021 09:38:58 +0000 (UTC)
commit 0f727808143da594c2cfeb680e1a5a283594d243
Author: Evangelos Ribeiro Tzaras <devrtz fortysixandtwo eu>
Date: Fri Nov 26 07:42:40 2021 +0100
ringer: Restart ringer if quiet parameter changed
This makes sure the following sequence of events works:
- Call A incoming
- Rings loudly
- Call B incoming
- Still rings loudly
- Call A accepted
- Rings quietly
- Call A hung up
- Rings loudly again
Being able to restart the ringing is needed for this case because we cannot
retroactively change the feedback levels of a event that has already been
triggered.
Without this patch Calls would continue ringing for the scenario above even
after call A was accepted.
src/calls-ringer.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
---
diff --git a/src/calls-ringer.c b/src/calls-ringer.c
index 97bef3cf..6e566fba 100644
--- a/src/calls-ringer.c
+++ b/src/calls-ringer.c
@@ -58,6 +58,7 @@ struct _CallsRinger {
GCancellable *cancel_ring;
CallsRingState state;
+ guint restart_id;
gboolean is_quiet;
};
@@ -91,6 +92,10 @@ change_ring_state (CallsRinger *self,
self->state = state;
+ /* Currently restarting, so don't notify */
+ if (self->restart_id)
+ return;
+
/* Ringing has not yet started/stopped */
if (state == CALLS_RING_STATE_REQUEST_PLAY ||
state == CALLS_RING_STATE_REQUEST_STOP)
@@ -124,6 +129,9 @@ on_event_triggered (LfbEvent *event,
g_object_unref (self);
}
+
+static void restart (CallsRinger *self, gboolean quiet);
+
static void
start (CallsRinger *self,
gboolean quiet)
@@ -133,8 +141,12 @@ start (CallsRinger *self,
lfb_event_set_feedback_profile (self->event, quiet ? "quiet" : NULL);
if (self->state == CALLS_RING_STATE_PLAYING ||
- self->state == CALLS_RING_STATE_REQUEST_PLAY)
+ self->state == CALLS_RING_STATE_REQUEST_PLAY) {
+ if (self->is_quiet != quiet)
+ restart (self, quiet);
+
return;
+ }
if (self->event) {
g_clear_object (&self->cancel_ring);
@@ -208,6 +220,69 @@ stop (CallsRinger *self)
}
+typedef struct {
+ CallsRinger *ringer;
+ gboolean quiet;
+} RestartRingerData;
+
+
+static gboolean
+on_ringer_restart (gpointer user_data)
+{
+ RestartRingerData *data = user_data;
+
+ if (data->ringer->state == CALLS_RING_STATE_PLAYING) {
+ stop (data->ringer);
+
+ return G_SOURCE_CONTINUE;
+ }
+
+ /* wait until requests have been fulfilled */
+ if (data->ringer->state == CALLS_RING_STATE_REQUEST_PLAY ||
+ data->ringer->state == CALLS_RING_STATE_REQUEST_STOP) {
+ return G_SOURCE_CONTINUE;
+ }
+
+ if (data->ringer->state == CALLS_RING_STATE_INACTIVE) {
+ start (data->ringer, data->quiet);
+
+ return G_SOURCE_REMOVE;
+ }
+
+ g_return_val_if_reached (G_SOURCE_CONTINUE);
+}
+
+
+static void
+clean_up_restart_data (gpointer user_data)
+{
+ RestartRingerData *data = user_data;
+
+ data->ringer->restart_id = 0;
+
+ g_free (data);
+}
+
+
+static void
+restart (CallsRinger *self,
+ gboolean quiet)
+{
+ RestartRingerData *data = g_new0 (RestartRingerData, 1);
+
+ data->ringer = self;
+ data->quiet = quiet;
+
+ if (self->restart_id)
+ g_source_remove (self->restart_id);
+
+ self->restart_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ G_SOURCE_FUNC (on_ringer_restart),
+ data,
+ clean_up_restart_data);
+}
+
+
static inline gboolean
is_ring_state (CallsCallState state)
{
@@ -395,6 +470,8 @@ dispose (GObject *object)
}
g_signal_handlers_disconnect_by_data (calls_manager_get_default (), self);
+ g_clear_handle_id (&self->restart_id, g_source_remove);
+
G_OBJECT_CLASS (calls_ringer_parent_class)->dispose (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]