mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2025-01-09 13:25:35 +00:00
ringer: Never cancel async DBus calls and refactor
Previously our code assumed that g_cancellable_cancel() the async DBus calls to libfeedback would guarantee that the underlying operation would not be performed (i.e. triggering or ending a feedback). However the endless ringing exhibited in #470 shows this assumption not to hold. Therefore we avoid using g_cancellable_cancel () completely and default to waiting for the async operation to finish. update_ring () now sets the target state by inspecting managed calls and the main logic will now step towards the target state: Changing from regular/loud to soft/quiet ringing (or vice versa) requires we first end feedback before (re)triggering it. Additionally the "is-quiet" and "is-ringing" properties are replaced by a new "state" property to allow changing the combination atomically. Closes: #470
This commit is contained in:
parent
db1f0e310c
commit
01ca267c10
4 changed files with 231 additions and 257 deletions
|
@ -29,6 +29,8 @@
|
||||||
#include "calls-ringer.h"
|
#include "calls-ringer.h"
|
||||||
#include "calls-ui-call-data.h"
|
#include "calls-ui-call-data.h"
|
||||||
|
|
||||||
|
#include "enum-types.h"
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
@ -38,78 +40,67 @@
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_IS_RINGING,
|
PROP_RING_STATE,
|
||||||
PROP_RING_IS_QUIET,
|
|
||||||
PROP_LAST_PROP
|
PROP_LAST_PROP
|
||||||
};
|
};
|
||||||
static GParamSpec *props[PROP_LAST_PROP];
|
static GParamSpec *props[PROP_LAST_PROP];
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CALLS_RING_STATE_INACTIVE,
|
|
||||||
CALLS_RING_STATE_REQUEST_PLAY,
|
|
||||||
CALLS_RING_STATE_PLAYING,
|
|
||||||
CALLS_RING_STATE_REQUEST_STOP
|
|
||||||
} CallsRingState;
|
|
||||||
|
|
||||||
|
|
||||||
struct _CallsRinger {
|
struct _CallsRinger {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
GList *calls;
|
GList *calls;
|
||||||
LfbEvent *event;
|
LfbEvent *ringing_event;
|
||||||
GCancellable *cancel_ring;
|
LfbEvent *ringing_soft_event;
|
||||||
CallsRingState state;
|
|
||||||
|
|
||||||
guint restart_id;
|
GCancellable *cancel;
|
||||||
gboolean is_quiet;
|
|
||||||
|
CallsRingState state;
|
||||||
|
CallsRingState target_state;
|
||||||
|
|
||||||
|
gboolean freeze_state_notify;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (CallsRinger, calls_ringer, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (CallsRinger, calls_ringer, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
|
||||||
|
static void target_state_step (CallsRinger *self);
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
ring_state_to_string (CallsRingState state)
|
ring_state_to_string (CallsRingState state)
|
||||||
{
|
{
|
||||||
switch (state) {
|
g_autoptr (GEnumClass) enum_class = NULL;
|
||||||
case CALLS_RING_STATE_INACTIVE:
|
GEnumValue *enum_val;
|
||||||
return "inactive";
|
|
||||||
case CALLS_RING_STATE_REQUEST_PLAY:
|
enum_class = g_type_class_ref (CALLS_TYPE_RING_STATE);
|
||||||
return "request-play";
|
enum_val = g_enum_get_value (enum_class, state);
|
||||||
case CALLS_RING_STATE_PLAYING:
|
|
||||||
return "playing";
|
return enum_val ? enum_val->value_nick : "invalid-state";
|
||||||
case CALLS_RING_STATE_REQUEST_STOP:
|
|
||||||
return "request-stop";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
change_ring_state (CallsRinger *self,
|
set_ring_state (CallsRinger *self,
|
||||||
CallsRingState state)
|
CallsRingState state)
|
||||||
{
|
{
|
||||||
g_debug ("%s: old: %s; new: %s",
|
g_assert (CALLS_IS_RINGER (self));
|
||||||
__func__, ring_state_to_string (self->state), ring_state_to_string (state));
|
g_assert (state >= CALLS_RING_STATE_INACTIVE && state <= CALLS_RING_STATE_ERROR);
|
||||||
|
|
||||||
if (self->state == state)
|
if (self->state == state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
g_debug ("Setting ring state to '%s'", ring_state_to_string (state));
|
||||||
self->state = state;
|
self->state = state;
|
||||||
|
|
||||||
/* Currently restarting, so don't notify */
|
if (state == self->target_state)
|
||||||
if (self->restart_id)
|
self->freeze_state_notify = FALSE;
|
||||||
return;
|
else
|
||||||
|
target_state_step (self);
|
||||||
|
|
||||||
/* Ringing has not yet started/stopped */
|
if (!self->freeze_state_notify)
|
||||||
if (state == CALLS_RING_STATE_REQUEST_PLAY ||
|
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_RING_STATE]);
|
||||||
state == CALLS_RING_STATE_REQUEST_STOP)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_debug ("%s: notify ring", __func__);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_IS_RINGING]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,54 +110,39 @@ on_event_triggered (LfbEvent *event,
|
||||||
CallsRinger *self)
|
CallsRinger *self)
|
||||||
{
|
{
|
||||||
g_autoptr (GError) err = NULL;
|
g_autoptr (GError) err = NULL;
|
||||||
|
CallsRingState state;
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
g_return_if_fail (LFB_IS_EVENT (event));
|
g_return_if_fail (LFB_IS_EVENT (event));
|
||||||
g_return_if_fail (CALLS_IS_RINGER (self));
|
|
||||||
|
|
||||||
g_debug ("%s", __func__);
|
ok = lfb_event_trigger_feedback_finish (event, res, &err);
|
||||||
if (lfb_event_trigger_feedback_finish (event, res, &err)) {
|
g_debug ("Feedback '%s' triggered %ssuccessfully",
|
||||||
change_ring_state (self, CALLS_RING_STATE_PLAYING);
|
lfb_event_get_event (event),
|
||||||
} else {
|
ok ? "" : "un");
|
||||||
if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
||||||
g_warning ("Failed to trigger feedback for '%s': %s",
|
|
||||||
lfb_event_get_event (event), err->message);
|
|
||||||
change_ring_state (self, CALLS_RING_STATE_INACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void restart (CallsRinger *self, gboolean quiet);
|
|
||||||
|
|
||||||
static void
|
|
||||||
start (CallsRinger *self,
|
|
||||||
gboolean quiet)
|
|
||||||
{
|
|
||||||
g_debug ("%s: state: %s", __func__, ring_state_to_string (self->state));
|
|
||||||
if (self->event)
|
|
||||||
lfb_event_set_feedback_profile (self->event, quiet ? "quiet" : NULL);
|
|
||||||
|
|
||||||
if (self->state == CALLS_RING_STATE_PLAYING ||
|
|
||||||
self->state == CALLS_RING_STATE_REQUEST_PLAY) {
|
|
||||||
if (self->is_quiet != quiet)
|
|
||||||
restart (self, quiet);
|
|
||||||
|
|
||||||
|
if (!CALLS_IS_RINGER (self)) {
|
||||||
|
g_warning ("Event feedback triggered, but ringer is gone");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->event) {
|
if (!ok) {
|
||||||
g_clear_object (&self->cancel_ring);
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
self->cancel_ring = g_cancellable_new ();
|
g_debug ("Feedback has been cancelled");
|
||||||
|
else
|
||||||
|
g_warning ("Failed to trigger feedback for '%s': %s",
|
||||||
|
lfb_event_get_event (event), err->message);
|
||||||
|
|
||||||
self->is_quiet = quiet;
|
set_ring_state (self, CALLS_RING_STATE_ERROR);
|
||||||
g_object_ref (self);
|
return;
|
||||||
lfb_event_trigger_feedback_async (self->event,
|
|
||||||
self->cancel_ring,
|
|
||||||
(GAsyncReadyCallback) on_event_triggered,
|
|
||||||
self);
|
|
||||||
change_ring_state (self, CALLS_RING_STATE_REQUEST_PLAY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (event == self->ringing_event)
|
||||||
|
state = CALLS_RING_STATE_RINGING;
|
||||||
|
else
|
||||||
|
state = CALLS_RING_STATE_RINGING_SOFT;
|
||||||
|
|
||||||
|
set_ring_state (self, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,21 +152,29 @@ on_event_feedback_ended (LfbEvent *event,
|
||||||
CallsRinger *self)
|
CallsRinger *self)
|
||||||
{
|
{
|
||||||
g_autoptr (GError) err = NULL;
|
g_autoptr (GError) err = NULL;
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
g_return_if_fail (LFB_IS_EVENT (event));
|
g_assert (LFB_IS_EVENT (event));
|
||||||
g_return_if_fail (CALLS_IS_RINGER (self));
|
|
||||||
|
|
||||||
g_debug ("%s: state: %s", __func__, ring_state_to_string (self->state));
|
ok = lfb_event_end_feedback_finish (event, res, &err);
|
||||||
|
g_debug ("Ended feedback '%s' %ssucessfully",
|
||||||
|
lfb_event_get_event (event),
|
||||||
|
ok ? "" : "un");
|
||||||
|
|
||||||
if (self->state == CALLS_RING_STATE_REQUEST_PLAY ||
|
if (!CALLS_IS_RINGER (self)) {
|
||||||
self->state == CALLS_RING_STATE_PLAYING)
|
g_warning ("Event feedback ended, but ringer is gone");
|
||||||
g_warning ("Feedback ended although it should be playing");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!lfb_event_end_feedback_finish (event, res, &err))
|
if (!ok) {
|
||||||
g_warning ("Failed to end feedback for '%s': %s",
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
lfb_event_get_event (event), err->message);
|
g_debug ("Ending feedback has been cancelled");
|
||||||
|
else
|
||||||
|
g_warning ("Failed to end feedback for '%s': %s",
|
||||||
|
lfb_event_get_event (event), err->message);
|
||||||
|
|
||||||
change_ring_state (self, CALLS_RING_STATE_INACTIVE);
|
set_ring_state (self, CALLS_RING_STATE_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,95 +182,87 @@ static void
|
||||||
on_feedback_ended (LfbEvent *event,
|
on_feedback_ended (LfbEvent *event,
|
||||||
CallsRinger *self)
|
CallsRinger *self)
|
||||||
{
|
{
|
||||||
|
g_assert (LFB_IS_EVENT (event));
|
||||||
|
|
||||||
g_debug ("Feedback ended");
|
g_debug ("Feedback ended");
|
||||||
g_debug ("%s: state: %s", __func__, ring_state_to_string (self->state));
|
|
||||||
change_ring_state (self, CALLS_RING_STATE_INACTIVE);
|
if (!CALLS_IS_RINGER (self)) {
|
||||||
|
g_warning ("Feedback stopped, but ringer is gone");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ring_state (self, CALLS_RING_STATE_INACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static LfbEvent *
|
||||||
|
get_event_for_state (CallsRinger *self,
|
||||||
|
CallsRingState state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case CALLS_RING_STATE_RINGING:
|
||||||
|
return self->ringing_event;
|
||||||
|
case CALLS_RING_STATE_RINGING_SOFT:
|
||||||
|
return self->ringing_soft_event;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stop (CallsRinger *self)
|
target_state_step (CallsRinger *self)
|
||||||
{
|
{
|
||||||
g_debug ("%s: state: %s", __func__, ring_state_to_string (self->state));
|
LfbEvent *event;
|
||||||
if (self->state == CALLS_RING_STATE_INACTIVE ||
|
|
||||||
self->state == CALLS_RING_STATE_REQUEST_STOP)
|
g_assert (CALLS_IS_RINGER (self));
|
||||||
|
|
||||||
|
if (self->state == self->target_state ||
|
||||||
|
self->state == CALLS_RING_STATE_ERROR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_debug ("Stopping ringtone");
|
g_clear_object (&self->cancel);
|
||||||
if (self->state == CALLS_RING_STATE_PLAYING) {
|
self->cancel = g_cancellable_new ();
|
||||||
g_debug ("ending event feedback");
|
|
||||||
lfb_event_end_feedback_async (self->event,
|
if (self->state == CALLS_RING_STATE_INACTIVE) {
|
||||||
NULL,
|
event = get_event_for_state (self, self->target_state);
|
||||||
|
|
||||||
|
lfb_event_trigger_feedback_async (event,
|
||||||
|
self->cancel,
|
||||||
|
(GAsyncReadyCallback) on_event_triggered,
|
||||||
|
self);
|
||||||
|
} else {
|
||||||
|
gboolean needs_restart =
|
||||||
|
self->target_state == CALLS_RING_STATE_RINGING ||
|
||||||
|
self->target_state == CALLS_RING_STATE_RINGING_SOFT;
|
||||||
|
|
||||||
|
if (needs_restart)
|
||||||
|
self->freeze_state_notify = TRUE;
|
||||||
|
|
||||||
|
event = get_event_for_state (self, self->state);
|
||||||
|
|
||||||
|
lfb_event_end_feedback_async (event,
|
||||||
|
self->cancel,
|
||||||
(GAsyncReadyCallback) on_event_feedback_ended,
|
(GAsyncReadyCallback) on_event_feedback_ended,
|
||||||
self);
|
self);
|
||||||
change_ring_state (self, CALLS_RING_STATE_REQUEST_STOP);
|
|
||||||
} else if (self->state == CALLS_RING_STATE_REQUEST_PLAY) {
|
|
||||||
g_debug ("cancelling event feedback");
|
|
||||||
g_cancellable_cancel (self->cancel_ring);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
static void
|
||||||
clean_up_restart_data (gpointer user_data)
|
set_target_state (CallsRinger *self,
|
||||||
|
CallsRingState state)
|
||||||
{
|
{
|
||||||
RestartRingerData *data = user_data;
|
g_assert (CALLS_IS_RINGER (self));
|
||||||
|
g_assert (state >= CALLS_RING_STATE_INACTIVE &&
|
||||||
|
state <= CALLS_RING_STATE_RINGING_SOFT);
|
||||||
|
|
||||||
data->ringer->restart_id = 0;
|
if (self->target_state == state)
|
||||||
|
return;
|
||||||
|
|
||||||
g_free (data);
|
self->target_state = state;
|
||||||
}
|
|
||||||
|
|
||||||
|
target_state_step (self);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -312,7 +288,7 @@ is_active_state (CuiCallState state)
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
has_active_call (CallsRinger *self)
|
have_active_call (CallsRinger *self)
|
||||||
{
|
{
|
||||||
g_assert (CALLS_IS_RINGER (self));
|
g_assert (CALLS_IS_RINGER (self));
|
||||||
|
|
||||||
|
@ -327,7 +303,7 @@ has_active_call (CallsRinger *self)
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
has_incoming_call (CallsRinger *self)
|
have_incoming_call (CallsRinger *self)
|
||||||
{
|
{
|
||||||
g_assert (CALLS_IS_RINGER (self));
|
g_assert (CALLS_IS_RINGER (self));
|
||||||
|
|
||||||
|
@ -346,17 +322,21 @@ has_incoming_call (CallsRinger *self)
|
||||||
static void
|
static void
|
||||||
update_ring (CallsRinger *self)
|
update_ring (CallsRinger *self)
|
||||||
{
|
{
|
||||||
|
CallsRingState target_state;
|
||||||
|
|
||||||
g_assert (CALLS_IS_RINGER (self));
|
g_assert (CALLS_IS_RINGER (self));
|
||||||
|
|
||||||
if (!self->event) {
|
if (self->state == CALLS_RING_STATE_ERROR) {
|
||||||
g_debug ("Can't ring because libfeedback is not initialized");
|
g_debug ("Can't ring because we're in an error state");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_incoming_call (self))
|
if (have_incoming_call (self))
|
||||||
start (self, has_active_call (self));
|
target_state = !have_active_call (self) ? CALLS_RING_STATE_RINGING : CALLS_RING_STATE_RINGING_SOFT;
|
||||||
else
|
else
|
||||||
stop (self);
|
target_state = CALLS_RING_STATE_INACTIVE;
|
||||||
|
|
||||||
|
set_target_state (self, target_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,15 +377,27 @@ calls_ringer_init (CallsRinger *self)
|
||||||
g_autoptr (GError) err = NULL;
|
g_autoptr (GError) err = NULL;
|
||||||
|
|
||||||
if (lfb_init (APP_ID, &err)) {
|
if (lfb_init (APP_ID, &err)) {
|
||||||
self->event = lfb_event_new ("phone-incoming-call");
|
self->ringing_event = lfb_event_new ("phone-incoming-call");
|
||||||
/* Let feedbackd do the loop */
|
/* Let feedbackd do the loop */
|
||||||
lfb_event_set_timeout (self->event, 0);
|
lfb_event_set_timeout (self->ringing_event, 0);
|
||||||
g_signal_connect (self->event,
|
g_signal_connect (self->ringing_event,
|
||||||
|
"feedback-ended",
|
||||||
|
G_CALLBACK (on_feedback_ended),
|
||||||
|
self);
|
||||||
|
|
||||||
|
/* FIXME change event once it's available in feedbackd,
|
||||||
|
* see https://source.puri.sm/Librem5/feedbackd/-/issues/37
|
||||||
|
*/
|
||||||
|
self->ringing_soft_event = lfb_event_new ("phone-incoming-call");
|
||||||
|
lfb_event_set_timeout (self->ringing_soft_event, 15);
|
||||||
|
lfb_event_set_feedback_profile (self->ringing_soft_event, "quiet");
|
||||||
|
g_signal_connect (self->ringing_soft_event,
|
||||||
"feedback-ended",
|
"feedback-ended",
|
||||||
G_CALLBACK (on_feedback_ended),
|
G_CALLBACK (on_feedback_ended),
|
||||||
self);
|
self);
|
||||||
} else {
|
} else {
|
||||||
g_warning ("Failed to init libfeedback: %s", err->message);
|
g_warning ("Failed to init libfeedback: %s", err->message);
|
||||||
|
set_ring_state (self, CALLS_RING_STATE_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,12 +409,8 @@ get_property (GObject *object,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
switch (property_id) {
|
switch (property_id) {
|
||||||
case PROP_IS_RINGING:
|
case PROP_RING_STATE:
|
||||||
g_value_set_boolean (value, calls_ringer_get_is_ringing (CALLS_RINGER (object)));
|
g_value_set_enum (value, calls_ringer_get_state (CALLS_RINGER (object)));
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_RING_IS_QUIET:
|
|
||||||
g_value_set_boolean (value, calls_ringer_get_ring_is_quiet (CALLS_RINGER (object)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -465,10 +453,8 @@ dispose (GObject *object)
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_data (calls_manager_get_default (), self);
|
g_signal_handlers_disconnect_by_data (calls_manager_get_default (), self);
|
||||||
|
|
||||||
g_clear_handle_id (&self->restart_id, g_source_remove);
|
g_cancellable_cancel (self->cancel);
|
||||||
|
g_clear_object (&self->cancel);
|
||||||
g_cancellable_cancel (self->cancel_ring);
|
|
||||||
g_clear_object (&self->cancel_ring);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (calls_ringer_parent_class)->dispose (object);
|
G_OBJECT_CLASS (calls_ringer_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
@ -479,10 +465,11 @@ finalize (GObject *object)
|
||||||
{
|
{
|
||||||
CallsRinger *self = CALLS_RINGER (object);
|
CallsRinger *self = CALLS_RINGER (object);
|
||||||
|
|
||||||
if (self->event)
|
if (lfb_is_initted ())
|
||||||
lfb_uninit ();
|
lfb_uninit ();
|
||||||
|
|
||||||
g_clear_object (&self->event);
|
g_clear_object (&self->ringing_event);
|
||||||
|
g_clear_object (&self->ringing_soft_event);
|
||||||
|
|
||||||
G_OBJECT_CLASS (calls_ringer_parent_class)->finalize (object);
|
G_OBJECT_CLASS (calls_ringer_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -498,19 +485,13 @@ calls_ringer_class_init (CallsRingerClass *klass)
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
|
||||||
props[PROP_IS_RINGING] =
|
props[PROP_RING_STATE] =
|
||||||
g_param_spec_boolean ("ringing",
|
g_param_spec_enum ("state",
|
||||||
"Ringing",
|
"",
|
||||||
"Whether we're currently ringing",
|
"",
|
||||||
FALSE,
|
CALLS_TYPE_RING_STATE,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
CALLS_RING_STATE_INACTIVE,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
props[PROP_RING_IS_QUIET] =
|
|
||||||
g_param_spec_boolean ("is-quiet",
|
|
||||||
"is quiet",
|
|
||||||
"Whether the ringing is of the quiet persuasion",
|
|
||||||
FALSE,
|
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
g_object_class_install_properties (object_class,
|
g_object_class_install_properties (object_class,
|
||||||
PROP_LAST_PROP,
|
PROP_LAST_PROP,
|
||||||
|
@ -525,30 +506,15 @@ calls_ringer_new (void)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calls_ringer_get_ring_is_ringing:
|
* calls_ringer_get_state
|
||||||
* @self: A #CallsRinger
|
* @self: A #CallsRinger
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if currently ringing, %FALSE otherwise.
|
* Returns: The #CallsRingerState
|
||||||
*/
|
*/
|
||||||
gboolean
|
CallsRingState
|
||||||
calls_ringer_get_is_ringing (CallsRinger *self)
|
calls_ringer_get_state (CallsRinger *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CALLS_IS_RINGER (self), FALSE);
|
g_return_val_if_fail (CALLS_IS_RINGER (self), CALLS_RING_STATE_INACTIVE);
|
||||||
|
|
||||||
return self->state == CALLS_RING_STATE_PLAYING ||
|
return self->state;
|
||||||
self->state == CALLS_RING_STATE_REQUEST_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* calls_ringer_get_ring_is_quiet:
|
|
||||||
* @self: A #CallsRinger
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if currently ringing quietly, %FALSE otherwise.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
calls_ringer_get_ring_is_quiet (CallsRinger *self)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (CALLS_IS_RINGER (self), FALSE);
|
|
||||||
|
|
||||||
return calls_ringer_get_is_ringing (self) && self->is_quiet;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,24 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* TODO docstring */
|
||||||
|
typedef enum {
|
||||||
|
CALLS_RING_STATE_INACTIVE,
|
||||||
|
CALLS_RING_STATE_RINGING,
|
||||||
|
CALLS_RING_STATE_RINGING_SOFT,
|
||||||
|
CALLS_RING_STATE_ERROR
|
||||||
|
} CallsRingState;
|
||||||
|
|
||||||
|
|
||||||
#define CALLS_TYPE_RINGER (calls_ringer_get_type ())
|
#define CALLS_TYPE_RINGER (calls_ringer_get_type ())
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (CallsRinger, calls_ringer, CALLS, RINGER, GObject)
|
G_DECLARE_FINAL_TYPE (CallsRinger, calls_ringer, CALLS, RINGER, GObject)
|
||||||
|
|
||||||
|
|
||||||
CallsRinger *calls_ringer_new (void);
|
CallsRinger *calls_ringer_new (void);
|
||||||
gboolean calls_ringer_get_is_ringing (CallsRinger *self);
|
CallsRingState calls_ringer_get_state (CallsRinger *self);
|
||||||
gboolean calls_ringer_get_ring_is_quiet (CallsRinger *self);
|
void calls_ringer_start_ringing (CallsRinger *self,
|
||||||
|
gboolean quiet);
|
||||||
|
void calls_ringer_stop_ringing (CallsRinger *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -65,6 +65,7 @@ calls_enum_headers = files(['calls-call.h',
|
||||||
'calls-ussd.h',
|
'calls-ussd.h',
|
||||||
'calls-manager.h',
|
'calls-manager.h',
|
||||||
'calls-account.h',
|
'calls-account.h',
|
||||||
|
'calls-ringer.h',
|
||||||
])
|
])
|
||||||
calls_enum_sources = gnome.mkenums_simple('enum-types',
|
calls_enum_sources = gnome.mkenums_simple('enum-types',
|
||||||
sources : calls_enum_headers)
|
sources : calls_enum_headers)
|
||||||
|
|
|
@ -96,11 +96,11 @@ t1_on_ringer_call_accepted (CallsRinger *ringer,
|
||||||
|
|
||||||
switch (test_phase++) {
|
switch (test_phase++) {
|
||||||
case 0: /* incoming call */
|
case 0: /* incoming call */
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
calls_call_answer (CALLS_CALL (fixture->call_one));
|
calls_call_answer (CALLS_CALL (fixture->call_one));
|
||||||
break;
|
break;
|
||||||
case 1: /* incoming call accepted */
|
case 1: /* incoming call accepted */
|
||||||
g_assert_false (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -113,21 +113,21 @@ static void
|
||||||
test_ringing_accept_call (RingerFixture *fixture,
|
test_ringing_accept_call (RingerFixture *fixture,
|
||||||
gconstpointer user_data)
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
|
|
||||||
g_signal_connect (fixture->ringer,
|
g_signal_connect (fixture->ringer,
|
||||||
"notify::ringing",
|
"notify::state",
|
||||||
G_CALLBACK (t1_on_ringer_call_accepted),
|
G_CALLBACK (t1_on_ringer_call_accepted),
|
||||||
fixture);
|
fixture);
|
||||||
|
|
||||||
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
||||||
add_call (fixture->manager, fixture->ui_call_one);
|
add_call (fixture->manager, fixture->ui_call_one);
|
||||||
|
|
||||||
/* main loop will quit in callback of notify::ring */
|
/* main loop will quit in callback of notify::state */
|
||||||
g_main_loop_run (fixture->loop);
|
g_main_loop_run (fixture->loop);
|
||||||
|
|
||||||
remove_call (fixture->manager, fixture->ui_call_one);
|
remove_call (fixture->manager, fixture->ui_call_one);
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* t2: test_ringing_hang_up_call */
|
/* t2: test_ringing_hang_up_call */
|
||||||
|
@ -141,11 +141,11 @@ t2_on_ringer_call_hang_up (CallsRinger *ringer,
|
||||||
|
|
||||||
switch (test_phase++) {
|
switch (test_phase++) {
|
||||||
case 0: /* incoming call */
|
case 0: /* incoming call */
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
calls_call_hang_up (CALLS_CALL (fixture->call_one));
|
calls_call_hang_up (CALLS_CALL (fixture->call_one));
|
||||||
break;
|
break;
|
||||||
case 1: /* incoming call hung up */
|
case 1: /* incoming call hung up */
|
||||||
g_assert_false (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -158,21 +158,21 @@ static void
|
||||||
test_ringing_hang_up_call (RingerFixture *fixture,
|
test_ringing_hang_up_call (RingerFixture *fixture,
|
||||||
gconstpointer user_data)
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
|
|
||||||
g_signal_connect (fixture->ringer,
|
g_signal_connect (fixture->ringer,
|
||||||
"notify::ringing",
|
"notify::state",
|
||||||
G_CALLBACK (t2_on_ringer_call_hang_up),
|
G_CALLBACK (t2_on_ringer_call_hang_up),
|
||||||
fixture);
|
fixture);
|
||||||
|
|
||||||
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
||||||
add_call (fixture->manager, fixture->ui_call_one);
|
add_call (fixture->manager, fixture->ui_call_one);
|
||||||
|
|
||||||
/* main loop will quit in callback of notify::ring */
|
/* main loop will quit in callback of notify::state */
|
||||||
g_main_loop_run (fixture->loop);
|
g_main_loop_run (fixture->loop);
|
||||||
|
|
||||||
remove_call (fixture->manager, fixture->ui_call_one);
|
remove_call (fixture->manager, fixture->ui_call_one);
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -187,12 +187,12 @@ t3_on_ringer_call_silence (CallsRinger *ringer,
|
||||||
|
|
||||||
switch (test_phase++) {
|
switch (test_phase++) {
|
||||||
case 0: /* incoming call */
|
case 0: /* incoming call */
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
calls_ui_call_data_silence_ring (fixture->ui_call_one);
|
calls_ui_call_data_silence_ring (fixture->ui_call_one);
|
||||||
g_assert_true (calls_ui_call_data_get_silenced (fixture->ui_call_one));
|
g_assert_true (calls_ui_call_data_get_silenced (fixture->ui_call_one));
|
||||||
break;
|
break;
|
||||||
case 1: /* incoming call hung up */
|
case 1: /* incoming call hung up */
|
||||||
g_assert_false (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -205,21 +205,21 @@ static void
|
||||||
test_ringing_silence_call (RingerFixture *fixture,
|
test_ringing_silence_call (RingerFixture *fixture,
|
||||||
gconstpointer user_data)
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
|
|
||||||
g_signal_connect (fixture->ringer,
|
g_signal_connect (fixture->ringer,
|
||||||
"notify::ringing",
|
"notify::state",
|
||||||
G_CALLBACK (t3_on_ringer_call_silence),
|
G_CALLBACK (t3_on_ringer_call_silence),
|
||||||
fixture);
|
fixture);
|
||||||
|
|
||||||
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
||||||
add_call (fixture->manager, fixture->ui_call_one);
|
add_call (fixture->manager, fixture->ui_call_one);
|
||||||
|
|
||||||
/* main loop will quit in callback of notify::ring */
|
/* main loop will quit in callback of notify::state */
|
||||||
g_main_loop_run (fixture->loop);
|
g_main_loop_run (fixture->loop);
|
||||||
|
|
||||||
remove_call (fixture->manager, fixture->ui_call_one);
|
remove_call (fixture->manager, fixture->ui_call_one);
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ t4_remove_calls (gpointer user_data)
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert_true (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
remove_call (fixture->manager, fixture->ui_call_two);
|
remove_call (fixture->manager, fixture->ui_call_two);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
|
@ -253,12 +253,12 @@ t4_on_ringer_multiple_calls (CallsRinger *ringer,
|
||||||
|
|
||||||
switch (test_phase++) {
|
switch (test_phase++) {
|
||||||
case 0: /* add second call, and schedule call removal */
|
case 0: /* add second call, and schedule call removal */
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
add_call (fixture->manager, fixture->ui_call_two);
|
add_call (fixture->manager, fixture->ui_call_two);
|
||||||
g_timeout_add (25, t4_remove_calls, fixture);
|
g_timeout_add (25, t4_remove_calls, fixture);
|
||||||
break;
|
break;
|
||||||
case 1: /* both calls should be removed now */
|
case 1: /* both calls should be removed now */
|
||||||
g_assert_false (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
g_main_loop_quit ((GMainLoop *) fixture->loop);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -271,20 +271,20 @@ static void
|
||||||
test_ringing_multiple_calls (RingerFixture *fixture,
|
test_ringing_multiple_calls (RingerFixture *fixture,
|
||||||
gconstpointer user_data)
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
|
|
||||||
g_signal_connect (fixture->ringer,
|
g_signal_connect (fixture->ringer,
|
||||||
"notify::ringing",
|
"notify::state",
|
||||||
G_CALLBACK (t4_on_ringer_multiple_calls),
|
G_CALLBACK (t4_on_ringer_multiple_calls),
|
||||||
fixture);
|
fixture);
|
||||||
|
|
||||||
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
calls_call_set_state (CALLS_CALL (fixture->call_one), CALLS_CALL_STATE_INCOMING);
|
||||||
add_call (fixture->manager, fixture->ui_call_one);
|
add_call (fixture->manager, fixture->ui_call_one);
|
||||||
|
|
||||||
/* main loop will quit in callback of notify::ring */
|
/* main loop will quit in callback of notify::state */
|
||||||
g_main_loop_run (fixture->loop);
|
g_main_loop_run (fixture->loop);
|
||||||
|
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,31 +298,27 @@ t5_on_ringer_multiple_calls_with_restart (CallsRinger *ringer,
|
||||||
|
|
||||||
switch (test_phase++) {
|
switch (test_phase++) {
|
||||||
case 0:
|
case 0:
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
g_assert_false (calls_ringer_get_ring_is_quiet (ringer));
|
|
||||||
|
|
||||||
calls_call_answer (CALLS_CALL (fixture->call_one));
|
calls_call_answer (CALLS_CALL (fixture->call_one));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_RINGING_SOFT);
|
||||||
g_assert_true (calls_ringer_get_ring_is_quiet (ringer));
|
|
||||||
|
|
||||||
calls_call_hang_up (CALLS_CALL (fixture->call_one));
|
calls_call_hang_up (CALLS_CALL (fixture->call_one));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
g_assert_true (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_RINGING);
|
||||||
g_assert_false (calls_ringer_get_ring_is_quiet (ringer));
|
|
||||||
|
|
||||||
calls_call_hang_up (CALLS_CALL (fixture->call_two));
|
calls_call_hang_up (CALLS_CALL (fixture->call_two));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
g_assert_false (calls_ringer_get_is_ringing (ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
g_assert_false (calls_ringer_get_ring_is_quiet (ringer));
|
|
||||||
|
|
||||||
g_main_loop_quit (fixture->loop);
|
g_main_loop_quit (fixture->loop);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached (); /* did not find equivalent cmocka assertion */
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,10 +326,10 @@ static void
|
||||||
test_ringing_multiple_calls_with_restart (RingerFixture *fixture,
|
test_ringing_multiple_calls_with_restart (RingerFixture *fixture,
|
||||||
gconstpointer user_data)
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
|
|
||||||
g_signal_connect (fixture->ringer,
|
g_signal_connect (fixture->ringer,
|
||||||
"notify::ringing",
|
"notify::state",
|
||||||
G_CALLBACK (t5_on_ringer_multiple_calls_with_restart),
|
G_CALLBACK (t5_on_ringer_multiple_calls_with_restart),
|
||||||
fixture);
|
fixture);
|
||||||
|
|
||||||
|
@ -342,10 +338,10 @@ test_ringing_multiple_calls_with_restart (RingerFixture *fixture,
|
||||||
calls_call_set_state (CALLS_CALL (fixture->call_two), CALLS_CALL_STATE_INCOMING);
|
calls_call_set_state (CALLS_CALL (fixture->call_two), CALLS_CALL_STATE_INCOMING);
|
||||||
add_call (fixture->manager, fixture->ui_call_two);
|
add_call (fixture->manager, fixture->ui_call_two);
|
||||||
|
|
||||||
/* main loop will quit in callback of notify::ring */
|
/* main loop will quit in callback of notify::state */
|
||||||
g_main_loop_run (fixture->loop);
|
g_main_loop_run (fixture->loop);
|
||||||
|
|
||||||
g_assert_false (calls_ringer_get_is_ringing (fixture->ringer));
|
g_assert_cmpint (calls_ringer_get_state (fixture->ringer), ==, CALLS_RING_STATE_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in a new issue