1
0
Fork 0
mirror of https://gitlab.gnome.org/GNOME/calls.git synced 2024-06-28 14:49:30 +00:00

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.
This commit is contained in:
Evangelos Ribeiro Tzaras 2021-11-26 07:42:40 +01:00
parent b89f6a6f17
commit 0f72780814

View file

@ -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);
}