From 44f2002f8629613f9102d69b73b92d6653e5a3ac Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Tue, 4 May 2021 21:49:07 +0200 Subject: [PATCH] manager: Differentiate the NO_ORIGIN state This avoids confusion when only the SIP plugin is loaded, but no account is being used. For this we introduce two new functions in the abstract CallsProvider class: `is_modem()` to indicate whether the the provider deals with PTSN telephony and `is_operational()` which by default simply checks if there any avalaible origins --- plugins/mm/calls-mm-provider.c | 7 ++++ plugins/ofono/calls-ofono-provider.c | 7 ++++ src/calls-main-window.c | 6 +++- src/calls-manager.c | 16 +++++++-- src/calls-manager.h | 1 + src/calls-provider.c | 52 ++++++++++++++++++++++++++++ src/calls-provider.h | 6 +++- 7 files changed, 90 insertions(+), 5 deletions(-) diff --git a/plugins/mm/calls-mm-provider.c b/plugins/mm/calls-mm-provider.c index c77856d..2156f27 100644 --- a/plugins/mm/calls-mm-provider.c +++ b/plugins/mm/calls-mm-provider.c @@ -365,6 +365,12 @@ calls_mm_provider_get_protocols (CallsProvider *provider) return supported_protocols; } +static gboolean +calls_mm_provider_is_modem (CallsProvider *provider) +{ + return TRUE; +} + static void constructed (GObject *object) { @@ -427,6 +433,7 @@ calls_mm_provider_class_init (CallsMMProviderClass *klass) provider_class->get_status = calls_mm_provider_get_status; provider_class->get_origins = calls_mm_provider_get_origins; provider_class->get_protocols = calls_mm_provider_get_protocols; + provider_class->is_modem = calls_mm_provider_is_modem; } diff --git a/plugins/ofono/calls-ofono-provider.c b/plugins/ofono/calls-ofono-provider.c index 59f75b6..c1d4f8c 100644 --- a/plugins/ofono/calls-ofono-provider.c +++ b/plugins/ofono/calls-ofono-provider.c @@ -306,6 +306,12 @@ calls_ofono_provider_get_protocols (CallsProvider *provider) return supported_protocols; } +static gboolean +calls_ofono_provider_is_modem (CallsProvider *provider) +{ + return TRUE; +} + static void modem_added_cb (GDBOManager *manager, const gchar *path, @@ -535,6 +541,7 @@ calls_ofono_provider_class_init (CallsOfonoProviderClass *klass) provider_class->get_status = calls_ofono_provider_get_status; provider_class->get_origins = calls_ofono_provider_get_origins; provider_class->get_protocols = calls_ofono_provider_get_protocols; + provider_class->is_modem = calls_ofono_provider_is_modem; } diff --git a/src/calls-main-window.c b/src/calls-main-window.c index d973f46..03590fb 100644 --- a/src/calls-main-window.c +++ b/src/calls-main-window.c @@ -315,10 +315,14 @@ state_changed_cb (CallsMainWindow *self, case CALLS_MANAGER_STATE_READY: break; - case CALLS_MANAGER_STATE_NO_ORIGIN: + case CALLS_MANAGER_STATE_NO_VOICE_MODEM: error = _("Can't place calls: No voice-capable modem available"); break; + case CALLS_MANAGER_STATE_NO_ORIGIN: + error = _("Can't place calls: No modem or VoIP account available"); + break; + case CALLS_MANAGER_STATE_UNKNOWN: case CALLS_MANAGER_STATE_NO_PROVIDER: error = _("Can't place calls: No backend service"); diff --git a/src/calls-manager.c b/src/calls-manager.c index 84dbfb8..3b0c871 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -92,6 +92,10 @@ static void update_state (CallsManager *self) { guint n_items; + GHashTableIter iter; + gpointer key; + gpointer value; + g_assert (CALLS_IS_MANAGER (self)); if (g_hash_table_size (self->providers) == 0) { @@ -99,9 +103,15 @@ update_state (CallsManager *self) return; } - if (g_hash_table_contains (self->providers, "dummy")) { - set_state (self, CALLS_MANAGER_STATE_READY); - return; + g_hash_table_iter_init (&iter, self->providers); + + while (g_hash_table_iter_next (&iter, &key, &value)) { + CallsProvider *provider = CALLS_PROVIDER (value); + + if (calls_provider_is_modem (provider) && !calls_provider_is_operational (provider)) { + set_state (self, CALLS_MANAGER_STATE_NO_VOICE_MODEM); + return; + } } n_items = g_list_model_get_n_items (G_LIST_MODEL (self->origins)); diff --git a/src/calls-manager.h b/src/calls-manager.h index fdb0181..2406861 100644 --- a/src/calls-manager.h +++ b/src/calls-manager.h @@ -42,6 +42,7 @@ typedef enum CALLS_MANAGER_STATE_NO_PLUGIN, CALLS_MANAGER_STATE_NO_PROVIDER, CALLS_MANAGER_STATE_NO_ORIGIN, + CALLS_MANAGER_STATE_NO_VOICE_MODEM, CALLS_MANAGER_STATE_READY, } CallsManagerState; diff --git a/src/calls-provider.c b/src/calls-provider.c index f76d157..ce9c439 100644 --- a/src/calls-provider.c +++ b/src/calls-provider.c @@ -78,6 +78,25 @@ calls_provider_real_get_protocols (CallsProvider *self) g_assert_not_reached (); } +static gboolean +calls_provider_real_is_modem (CallsProvider *self) +{ + return FALSE; +} + +static gboolean +calls_provider_real_is_operational (CallsProvider *self) +{ + GListModel *origins; + + origins = calls_provider_get_origins (self); + + if (origins) + return !!g_list_model_get_n_items (origins); + + return FALSE; +} + static void calls_provider_get_property (GObject *object, @@ -108,6 +127,8 @@ calls_provider_class_init (CallsProviderClass *klass) klass->get_status = calls_provider_real_get_status; klass->get_origins = calls_provider_real_get_origins; klass->get_protocols = calls_provider_real_get_protocols; + klass->is_modem = calls_provider_real_is_modem; + klass->is_operational = calls_provider_real_is_operational; props[PROP_STATUS] = g_param_spec_string ("status", @@ -244,3 +265,34 @@ calls_provider_get_protocols (CallsProvider *self) return CALLS_PROVIDER_GET_CLASS (self)->get_protocols (self); } + +/** + * calls_provider_is_modem: + * @self: A #CallsProvider + * + * Returns: %TRUE is this provider handles modems, %FALSE otherwise + */ +gboolean +calls_provider_is_modem (CallsProvider *self) +{ + g_return_val_if_fail (CALLS_IS_PROVIDER (self), FALSE); + + return CALLS_PROVIDER_GET_CLASS (self)->is_modem (self); +} + +/** + * calls_provider_is_operational: + * @self: A #CallsProvider + * + * Returns: %TRUE is this provider is operational, %FALSE otherwise + * + * If not subclassed this method will simply test if there are any + * origins available. + */ +gboolean +calls_provider_is_operational (CallsProvider *self) +{ + g_return_val_if_fail (CALLS_IS_PROVIDER (self), FALSE); + + return CALLS_PROVIDER_GET_CLASS (self)->is_operational (self); +} diff --git a/src/calls-provider.h b/src/calls-provider.h index 7d8a6ce..7c326d9 100644 --- a/src/calls-provider.h +++ b/src/calls-provider.h @@ -48,6 +48,8 @@ struct _CallsProviderClass const char *(*get_status) (CallsProvider *self); GListModel *(*get_origins) (CallsProvider *self); const char * const *(*get_protocols) (CallsProvider *self); + gboolean (*is_modem) (CallsProvider *self); + gboolean (*is_operational) (CallsProvider *self); }; const char *calls_provider_get_name (CallsProvider *self); @@ -55,7 +57,9 @@ const char *calls_provider_get_status (CallsProvider *self); GListModel *calls_provider_get_origins (CallsProvider *self); CallsProvider *calls_provider_load_plugin (const char *name); void calls_provider_unload_plugin (const char *name); -const char * const *calls_provider_get_protocols (CallsProvider *self); +const char * const *calls_provider_get_protocols (CallsProvider *self); +gboolean calls_provider_is_modem (CallsProvider *self); +gboolean calls_provider_is_operational (CallsProvider *self); G_END_DECLS