[calls] ui-call-data: Add property to delay showing call display and ringing



commit 1d5c8952ad22085816100becb3f26e3fe1f969ac
Author: Evangelos Ribeiro Tzaras <devrtz fortysixandtwo eu>
Date:   Tue Feb 1 08:12:40 2022 +0100

    ui-call-data: Add property to delay showing call display and ringing
    
    This "ui-active" property should be set to FALSE for new incoming calls and set
    to TRUE after a short delay of 20ms. This property is used to delay showing the
    call display and starting to ring.
    
    This delay gives DBus clients like
    phosh-antispam (https://gitlab.com/kop316/phosh-antispam)
    some time to make a decision whether a call should be hung up or not and defer
    starting to ring and showing the display only afterwards.

 src/calls-ui-call-data.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/calls-ui-call-data.h |  1 +
 2 files changed, 83 insertions(+)
---
diff --git a/src/calls-ui-call-data.c b/src/calls-ui-call-data.c
index 3da5d134..52417199 100644
--- a/src/calls-ui-call-data.c
+++ b/src/calls-ui-call-data.c
@@ -42,6 +42,7 @@ enum {
   PROP_AVATAR_ICON,
   PROP_ACTIVE_TIME,
   PROP_SILENCED,
+  PROP_UI_ACTIVE,
   PROP_LAST_PROP
 };
 
@@ -66,6 +67,9 @@ struct _CallsUiCallData
 
   CuiCallState state;
   gboolean silenced;
+
+  gboolean ui_active; /* whether a UI should be shown (or the ringer should ring) */
+  guint set_active_id;
 };
 
 static void calls_ui_call_data_cui_call_interface_init (CuiCallInterface *iface);
@@ -260,6 +264,7 @@ set_state (CallsUiCallData *self,
   } else if (new_state == CUI_CALL_STATE_DISCONNECTED) {
     g_clear_handle_id (&self->timer_id, g_source_remove);
     g_clear_pointer (&self->timer, g_timer_destroy);
+    g_clear_handle_id (&self->set_active_id, g_source_remove);
   }
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_STATE]);
@@ -345,6 +350,56 @@ set_call_data (CallsUiCallData *self,
 
 }
 
+
+static void
+set_ui_active (CallsUiCallData *self,
+               gboolean         active)
+{
+  g_assert (CALLS_IS_UI_CALL_DATA (self));
+
+  if (self->ui_active == active)
+    return;
+
+  self->ui_active = active;
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_UI_ACTIVE]);
+}
+
+
+static gboolean
+on_delay_set_active (CallsUiCallData *self)
+{
+  g_assert (CALLS_IS_UI_CALL_DATA (self));
+
+  set_ui_active (self, TRUE);
+
+  self->set_active_id = 0;
+  g_object_unref (self);
+
+  return G_SOURCE_REMOVE;
+}
+
+
+#define DELAY_UI_MS 15
+static void
+calls_ui_call_data_constructed (GObject *object)
+{
+  CallsUiCallData *self = CALLS_UI_CALL_DATA (object);
+
+  G_OBJECT_CLASS (calls_ui_call_data_parent_class)->constructed (object);
+
+  if (!calls_call_get_inbound (self->call) || self->state != CUI_CALL_STATE_INCOMING) {
+    set_ui_active (self, TRUE);
+    return;
+  }
+
+  set_ui_active (self, FALSE);
+  self->set_active_id = g_timeout_add (DELAY_UI_MS,
+                                       G_SOURCE_FUNC (on_delay_set_active),
+                                       g_object_ref (self));
+}
+#undef DELAY_UI_MS
+
+
 static void
 calls_ui_call_data_set_property (GObject      *object,
                                  guint         property_id,
@@ -419,6 +474,10 @@ calls_ui_call_data_get_property (GObject    *object,
     g_value_set_boolean (value, calls_ui_call_data_get_silenced (self));
     break;
 
+  case PROP_UI_ACTIVE:
+    g_value_set_boolean (value, calls_ui_call_data_get_ui_active (self));
+    break;
+
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     break;
@@ -449,6 +508,7 @@ calls_ui_call_data_class_init (CallsUiCallDataClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->constructed = calls_ui_call_data_constructed;
   object_class->set_property = calls_ui_call_data_set_property;
   object_class->get_property = calls_ui_call_data_get_property;
   object_class->dispose = calls_ui_call_data_dispose;
@@ -490,6 +550,15 @@ calls_ui_call_data_class_init (CallsUiCallDataClass *klass)
 
   g_object_class_install_property (object_class, PROP_SILENCED, props[PROP_SILENCED]);
 
+  props[PROP_UI_ACTIVE] =
+    g_param_spec_boolean ("ui-active",
+                          "UI active",
+                          "Whether the UI should be shown",
+                          FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+  g_object_class_install_property (object_class, PROP_UI_ACTIVE, props[PROP_UI_ACTIVE]);
+
   g_object_class_override_property (object_class, PROP_ID, "id");
   props[PROP_ID] = g_object_class_find_property (object_class, "id");
 
@@ -569,6 +638,19 @@ calls_ui_call_data_get_silenced (CallsUiCallData *self)
   return self->silenced;
 }
 
+/**
+ * calls_ui_call_data_get_ui_active:
+ * @self: a #CallsUiCallData
+ *
+ * Returns: %TRUE if the UI should be shown, %FALSE otherwise
+ */
+gboolean
+calls_ui_call_data_get_ui_active (CallsUiCallData *self)
+{
+  g_return_val_if_fail (CALLS_UI_CALL_DATA (self), FALSE);
+
+  return self->ui_active;
+}
 
 /**
  * calls_call_state_to_cui_call_state:
diff --git a/src/calls-ui-call-data.h b/src/calls-ui-call-data.h
index 411258b3..a67a3a53 100644
--- a/src/calls-ui-call-data.h
+++ b/src/calls-ui-call-data.h
@@ -38,6 +38,7 @@ G_DECLARE_FINAL_TYPE (CallsUiCallData, calls_ui_call_data, CALLS, UI_CALL_DATA,
 CallsUiCallData         *calls_ui_call_data_new               (CallsCall       *call);
 void                     calls_ui_call_data_silence_ring      (CallsUiCallData *self);
 gboolean                 calls_ui_call_data_get_silenced      (CallsUiCallData *self);
+gboolean                 calls_ui_call_data_get_ui_active     (CallsUiCallData *self);
 CuiCallState             calls_call_state_to_cui_call_state   (CallsCallState   state);
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]