From d3e42c93cd45dede8ae11fed208992c352989314 Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Mon, 15 May 2023 10:08:55 +0200 Subject: [PATCH] refactor: Switch to CallsPluginManager --- src/calls-account-overview.c | 202 +++++++++----- src/calls-application.c | 89 +++--- src/calls-manager.c | 493 ++++++++-------------------------- src/calls-manager.h | 12 - src/calls-provider.c | 66 ----- src/calls-provider.h | 2 - tests/meson.build | 1 - tests/services/calls-server.c | 12 +- tests/test-manager.c | 83 ++++-- 9 files changed, 371 insertions(+), 589 deletions(-) diff --git a/src/calls-account-overview.c b/src/calls-account-overview.c index 96d783b..ed0ad54 100644 --- a/src/calls-account-overview.c +++ b/src/calls-account-overview.c @@ -32,6 +32,11 @@ #include "calls-account-provider.h" #include "calls-manager.h" #include "calls-in-app-notification.h" +#include "calls-plugin-manager.h" +#include "calls-util.h" + +#include "gtkcustomfilter.h" +#include "gtkfilterlistmodel.h" #include @@ -66,11 +71,16 @@ struct _CallsAccountOverview { GtkWindow *account_window; GtkWidget *current_account_widget; + /* models */ + GtkFilter *account_provider_filter; + GtkFilter *account_filter; + GListModel *providers; + GListModel *accounts; + /* misc */ GtkEventController *key_controller; GtkEventController *key_controller_account; CallsAccountOverviewState state; - GList *providers; CallsInAppNotification *in_app_notification; }; @@ -101,14 +111,25 @@ static void update_state (CallsAccountOverview *self) { guint n_origins = 0; + guint n_providers; g_assert (CALLS_IS_ACCOUNT_OVERVIEW (self)); - for (GList *node = self->providers; node != NULL; node = node->next) { - CallsProvider *provider = CALLS_PROVIDER (node->data); - GListModel *model = calls_provider_get_origins (provider); + n_providers = g_list_model_get_n_items (self->providers); - n_origins += g_list_model_get_n_items (model); + for (guint i = 0; i < n_providers; i++) { + g_autoptr (CallsProvider) provider = g_list_model_get_item (self->providers, i); + GListModel *origins; + + /* we might be in the middle of the lists being updated! */ + if (!provider) { + n_providers--; + break; + } + + origins = calls_provider_get_origins (provider); + + n_origins += g_list_model_get_n_items (origins); } if (n_origins > 0) @@ -116,6 +137,8 @@ update_state (CallsAccountOverview *self) else self->state = SHOW_INTRO; + gtk_widget_set_sensitive (self->add_btn, n_providers > 0); + update_visibility (self); } @@ -145,18 +168,20 @@ on_account_row_activated (GtkListBox *box, GtkListBoxRow *row, CallsAccountOverview *self) { + CallsAccountProvider *provider; CallsAccount *account = NULL; CallsAccountRow *acc_row; - CallsAccountProvider *provider; GtkWidget *widget; g_assert (GTK_IS_LIST_BOX_ROW (row) ); g_assert (CALLS_IS_ACCOUNT_OVERVIEW (self)); + g_assert (g_list_model_get_n_items (self->providers) > 0); if (row == self->add_row) { /* TODO this needs changing if we ever have multiple account providers */ - provider = CALLS_ACCOUNT_PROVIDER (self->providers->data); + provider = g_list_model_get_item (self->providers, 0); widget = calls_account_provider_get_account_widget (provider); + g_object_unref (provider); } else if (CALLS_IS_ACCOUNT_ROW (row)) { acc_row = CALLS_ACCOUNT_ROW (row); @@ -215,84 +240,72 @@ on_account_message (CallsAccount *account, static void -update_account_list (CallsAccountOverview *self) +on_accounts_changed (GListModel *accounts, + guint position, + guint removed, + guint added, + CallsAccountOverview *self) { - gboolean removed_all = FALSE; + guint n_providers = g_list_model_get_n_items (self->providers); - g_assert (CALLS_IS_ACCOUNT_OVERVIEW (self)); + for (guint i = removed; i > 0; i--) { + GtkListBoxRow *row = + gtk_list_box_get_row_at_index (GTK_LIST_BOX (self->overview), position + i - 1); - /* TODO rework with GTK4 FlattenListModel (to flatten a GListModel of GListModels) - * in particular we could then connect to the items-changed signal of the flattened list. - * Always rebuilding the account list is not particularly efficient, but since - * we're not constantly doing this it's fine for now. - */ - while (!removed_all) { - GtkListBoxRow *row = gtk_list_box_get_row_at_index (GTK_LIST_BOX (self->overview), 0); - - if (row == NULL || row == GTK_LIST_BOX_ROW (self->add_row)) - removed_all = TRUE; - else - gtk_container_remove (GTK_CONTAINER (self->overview), GTK_WIDGET (row)); + gtk_container_remove (GTK_CONTAINER (self->overview), GTK_WIDGET (row)); } - for (GList *node = self->providers; node != NULL; node = node->next) { - CallsAccountProvider *provider = CALLS_ACCOUNT_PROVIDER (node->data); - GListModel *model = calls_provider_get_origins (CALLS_PROVIDER (provider)); - guint n_origins = g_list_model_get_n_items (model); + for (guint i = 0; i < added; i++) { + g_autoptr (CallsAccount) account = + CALLS_ACCOUNT (g_list_model_get_item (accounts, position + i)); + CallsAccountProvider *provider = NULL; + CallsAccountRow *account_row; - for (guint i = 0; i < n_origins; i++) { - g_autoptr (CallsAccount) account = CALLS_ACCOUNT (g_list_model_get_item (model, i)); - CallsAccountRow *account_row = calls_account_row_new (provider, account); + /* which provider does this account belong to? */ + for (guint j = 0; j < n_providers; j++) { + g_autoptr (CallsProvider) candidate = g_list_model_get_item (self->providers, j); - g_signal_handlers_disconnect_by_data (account, self); - g_signal_connect_object (account, "message", - G_CALLBACK (on_account_message), - self, - G_CONNECT_AFTER); - - gtk_list_box_insert (GTK_LIST_BOX (self->overview), - GTK_WIDGET (account_row), - 0); + if (calls_find_in_model (calls_provider_get_origins (candidate), account, NULL)) { + provider = CALLS_ACCOUNT_PROVIDER (candidate); + break; + } } + + g_assert (CALLS_IS_ACCOUNT_PROVIDER (provider)); + + account_row = calls_account_row_new (provider, account); + + g_signal_connect_object (account, "message", + G_CALLBACK (on_account_message), + self, + 0); + gtk_list_box_insert (GTK_LIST_BOX (self->overview), + GTK_WIDGET (account_row), + position + i); } + update_state (self); } - static void -on_providers_changed (CallsAccountOverview *self) +on_providers_changed (GListModel *providers, + guint position, + guint removed, + guint added, + CallsAccountOverview *self) { - GList *providers; + for (guint i = 0; i < added; i++) { + g_autoptr (CallsProvider) provider = + g_list_model_get_item (providers, position + i); - g_clear_pointer (&self->providers, g_list_free); - providers = calls_manager_get_providers (calls_manager_get_default ()); - - for (GList *node = providers; node != NULL; node = node->next) { - CallsProvider *provider = node->data; - - if (CALLS_IS_ACCOUNT_PROVIDER (provider)) { - self->providers = g_list_append (self->providers, provider); - g_signal_connect_object (calls_provider_get_origins (provider), - "items-changed", - G_CALLBACK (update_account_list), - self, - G_CONNECT_SWAPPED); - g_signal_connect_object (provider, - "widget-edit-done", - G_CALLBACK (gtk_widget_hide), - self->account_window, - G_CONNECT_SWAPPED); - } + g_signal_connect_swapped (provider, "widget-edit-done", + G_CALLBACK (gtk_widget_hide), self->account_window); } /* Clear any acccount widgets, because they might've gone stale */ attach_account_widget (self, NULL); gtk_widget_hide (GTK_WIDGET (self->account_window)); - - update_account_list (self); - - gtk_widget_set_sensitive (self->add_btn, !!self->providers); } @@ -316,6 +329,12 @@ calls_account_overview_dispose (GObject *object) { CallsAccountOverview *self = CALLS_ACCOUNT_OVERVIEW (object); + g_clear_object (&self->providers); + g_clear_object (&self->account_provider_filter); + + g_clear_object (&self->accounts); + g_clear_object (&self->account_filter); + g_clear_object (&self->key_controller); g_clear_object (&self->key_controller_account); @@ -348,24 +367,65 @@ calls_account_overview_class_init (CallsAccountOverviewClass *klass) } +static gboolean +match_account_provider (gpointer item, + gpointer unused) +{ + g_assert (CALLS_IS_PROVIDER (item)); + + return CALLS_IS_ACCOUNT_PROVIDER (item); +} + + +static gboolean +match_account (gpointer item, + gpointer unused) +{ + g_assert (CALLS_IS_ORIGIN (item)); + + return CALLS_IS_ACCOUNT (item); +} + + static void calls_account_overview_init (CallsAccountOverview *self) { + GListModel *all_providers = + calls_plugin_manager_get_providers (calls_plugin_manager_get_default ()); + GListModel *all_origins = + calls_manager_get_origins (calls_manager_get_default ()); + gtk_widget_init_template (GTK_WIDGET (self)); - g_signal_connect_swapped (calls_manager_get_default (), - "providers-changed", - G_CALLBACK (on_providers_changed), - self); - on_providers_changed (self); + self->account_provider_filter = gtk_custom_filter_new (match_account_provider, NULL, NULL); + self->providers = + G_LIST_MODEL (gtk_filter_list_model_new (all_providers, + self->account_provider_filter)); + + g_signal_connect (self->providers, + "items-changed", + G_CALLBACK (on_providers_changed), + self); + on_providers_changed (self->providers, + 0, 0, g_list_model_get_n_items (self->providers), + self); + + self->account_filter = gtk_custom_filter_new (match_account, NULL, NULL); + self->accounts = + G_LIST_MODEL (gtk_filter_list_model_new (all_origins, + self->account_filter)); + g_signal_connect_object (self->accounts, + "items-changed", + G_CALLBACK (on_accounts_changed), + self, + G_CONNECT_AFTER); + on_accounts_changed (self->accounts, 0, 0, g_list_model_get_n_items (self->accounts), self); gtk_list_box_insert (GTK_LIST_BOX (self->overview), GTK_WIDGET (self->add_row), -1); gtk_window_set_transient_for (self->account_window, GTK_WINDOW (self)); - update_state (self); - self->key_controller = gtk_event_controller_key_new (GTK_WIDGET (self)); g_signal_connect (self->key_controller, "key-pressed", diff --git a/src/calls-application.c b/src/calls-application.c index 88ceb35..ea8a0de 100644 --- a/src/calls-application.c +++ b/src/calls-application.c @@ -39,6 +39,7 @@ #include "calls-message-source.h" #include "calls-new-call-box.h" #include "calls-notifier.h" +#include "calls-plugin-manager.h" #include "calls-record-store.h" #include "calls-ringer.h" #include "version.h" @@ -73,6 +74,8 @@ struct _CallsApplication { guint id_sigint; gboolean shutdown; gboolean db_done; + CallsPluginManager *plugin_manager; + CallsSettings *settings; }; G_DEFINE_TYPE (CallsApplication, calls_application, GTK_TYPE_APPLICATION); @@ -155,60 +158,76 @@ calls_application_dbus_unregister (GApplication *application, static void -set_provider_names_action (GSimpleAction *action, - GVariant *parameter, - gpointer user_data) +set_plugin_names_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { - CallsManager *manager; g_autofree const char **names = NULL; g_autofree const char **loaded = NULL; + CallsApplication *self = user_data; gsize length; guint length_loaded; + g_assert (CALLS_IS_APPLICATION (self)); + names = g_variant_get_strv (parameter, &length); g_return_if_fail (names && *names); - manager = calls_manager_get_default (); - loaded = calls_manager_get_provider_names (manager, &length_loaded); + loaded = calls_plugin_manager_get_plugin_names (self->plugin_manager, &length_loaded); - /* remove unwanted providers */ + /* remove unwanted plugins */ for (guint i = 0; i < length_loaded; i++) { - g_autofree char *provider = g_strdup (loaded[i]); - if (!g_strv_contains (names, provider)) - calls_manager_remove_provider (manager, provider); + g_autofree char *plugin = g_strdup (loaded[i]); + + if (!g_strv_contains (names, plugin)) { + g_autoptr (GError) error = NULL; + gboolean ok = calls_plugin_manager_unload_plugin (self->plugin_manager, plugin, &error); + + g_debug ("Unloading plugin `%s' %ssuccessful", plugin, ok ? "" : "un"); + if (!ok) + g_warning ("Plugin '%s' not unloaded: %s", plugin, error->message); + } } for (guint i = 0; i < length; i++) { + g_autoptr (GError) error = NULL; const char *name = names[i]; + gboolean ok; - if (calls_manager_has_provider (manager, name)) + if (calls_plugin_manager_has_plugin (self->plugin_manager, name)) continue; - g_debug ("Loading provider `%s'", name); - calls_manager_add_provider (manager, name); + ok = calls_plugin_manager_load_plugin (self->plugin_manager, name, &error); + g_debug ("Loading plugin `%s' %ssuccessful", name, ok ? "" : "un"); + if (!ok) + g_warning ("Plugin '%s' not loaded: %s", name, error->message); } } static void -set_default_providers_action (GSimpleAction *action, - GVariant *parameter, - gpointer user_data) +set_default_plugins_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { - CallsManager *manager = calls_manager_get_default (); - CallsSettings *settings = calls_manager_get_settings (manager); + CallsApplication *self = CALLS_APPLICATION (user_data); g_auto (GStrv) plugins = NULL; /** * Only add default providers when there are none added yet, * This makes sure we're not resetting explicitly set providers */ - if (calls_manager_has_any_provider (manager)) + if (calls_plugin_manager_has_any_plugins (self->plugin_manager)) return; - plugins = calls_settings_get_autoload_plugins (settings); + plugins = calls_settings_get_autoload_plugins (self->settings); for (guint i = 0; plugins[i] != NULL; i++) { - calls_manager_add_provider (manager, plugins[i]); + g_autoptr (GError) error = NULL; + + g_debug ("Loading default provider %s", plugins[i]); + + if (!calls_plugin_manager_load_plugin (self->plugin_manager, plugins[i], &error)) + g_warning ("Could not load plugin '%s': %s", plugins[i], error->message); } } @@ -417,8 +436,8 @@ manager_state_changed_cb (GApplication *application) static const GActionEntry actions[] = { - { "set-provider-names", set_provider_names_action, "as" }, - { "set-default-providers", set_default_providers_action, NULL }, + { "set-plugin-names", set_plugin_names_action, "as" }, + { "set-default-plugins", set_default_plugins_action, NULL }, { "set-daemon", set_daemon_action, "b" }, { "dial", dial_action, "s" }, { "copy-number", copy_number, "s" }, @@ -509,7 +528,7 @@ calls_application_command_line (GApplication *application, GVariantDict *options; const char *arg; - g_autoptr (GVariant) providers = NULL; + g_autoptr (GVariant) plugins = NULL; g_auto (GStrv) arguments = NULL; gint argc; guint verbosity; @@ -529,14 +548,14 @@ calls_application_command_line (GApplication *application, start_proper (self); - providers = g_variant_dict_lookup_value (options, "provider", G_VARIANT_TYPE_STRING_ARRAY); - if (providers) { + plugins = g_variant_dict_lookup_value (options, "plugins", G_VARIANT_TYPE_STRING_ARRAY); + if (plugins) { g_action_group_activate_action (G_ACTION_GROUP (application), - "set-provider-names", - providers); + "set-plugin-names", + plugins); } else { g_action_group_activate_action (G_ACTION_GROUP (application), - "set-default-providers", + "set-default-plugins", NULL); } @@ -629,6 +648,12 @@ start_proper (CallsApplication *self) gtk_app = GTK_APPLICATION (self); + self->settings = calls_settings_get_default (); + g_assert (self->settings); + + self->plugin_manager = calls_plugin_manager_get_default (); + g_assert (self->plugin_manager); + self->manager = calls_manager_get_default (); g_assert (self->manager); @@ -746,6 +771,8 @@ finalize (GObject *object) g_clear_object (&self->ringer); g_clear_object (&self->notifier); g_clear_object (&self->manager); + g_clear_object (&self->plugin_manager); + g_clear_object (&self->settings); g_free (self->uri); @@ -780,9 +807,9 @@ calls_application_init (CallsApplication *self) { const GOptionEntry options[] = { { - "provider", 'p', G_OPTION_FLAG_NONE, + "plugins", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING_ARRAY, NULL, - _("The name of the plugin to use as a call provider"), + _("The name of the plugins to load"), _("PLUGIN") }, { diff --git a/src/calls-manager.c b/src/calls-manager.c index c89c06b..d33a164 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -31,6 +31,7 @@ #include "calls-contacts-provider.h" #include "calls-manager.h" #include "calls-message-source.h" +#include "calls-plugin-manager.h" #include "calls-provider.h" #include "calls-settings.h" #include "calls-ui-call-data.h" @@ -39,6 +40,10 @@ #include "enum-types.h" +#include "gtkcustomfilter.h" +#include "gtkfilterlistmodel.h" +#include "gtkflattenlistmodel.h" + #include #include @@ -59,12 +64,23 @@ static const char * const protocols[] = { "sips" }; + +static gboolean +match_origin_supports_protocol (gpointer item, + gpointer protocol) +{ + g_assert (CALLS_IS_ORIGIN (item)); + + return calls_origin_supports_protocol (CALLS_ORIGIN (item), (char *) protocol); +} + + struct _CallsManager { GObject parent_instance; - GHashTable *providers; - GListStore *origins; + GtkFlattenListModel *origins_flat; + /* origins_by_protocol maps protocol names to GListStore's of suitable origins */ GHashTable *origins_by_protocol; /* dial_actions_by_protocol maps protocol names to GSimpleActions */ @@ -123,16 +139,17 @@ set_state_flags (CallsManager *self, CallsManagerFlags state_flags) static void update_state_flags (CallsManager *self) { - GHashTableIter iter; - gpointer value; CallsManagerFlags state_flags = CALLS_MANAGER_FLAGS_UNKNOWN; + GListModel *providers; + guint n_providers; g_assert (CALLS_IS_MANAGER (self)); - g_hash_table_iter_init (&iter, self->providers); + providers = calls_plugin_manager_get_providers (calls_plugin_manager_get_default ()); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - CallsProvider *provider = CALLS_PROVIDER (value); + n_providers = g_list_model_get_n_items (providers); + for (guint i = 0; i < n_providers; i++) { + g_autoptr (CallsProvider) provider = g_list_model_get_item (providers, i); if (calls_provider_is_modem (provider)) { state_flags |= CALLS_MANAGER_FLAGS_HAS_CELLULAR_PROVIDER; @@ -242,6 +259,8 @@ add_call (CallsManager *self, CallsCall *call, CallsOrigin *origin) call_data = calls_ui_call_data_new (call, origin_id); g_hash_table_insert (self->calls, call, call_data); + g_object_set_data (G_OBJECT (call), "call-origin", origin); + g_signal_emit (self, signals[UI_CALL_ADDDED], 0, call_data); } @@ -363,8 +382,6 @@ add_origin (CallsManager *self, CallsOrigin *origin) name = calls_origin_get_name (origin); g_debug ("Adding origin %s (%p)", name, origin); - g_list_store_append (self->origins, origin); - g_signal_connect_object (origin, "message", G_CALLBACK (on_message), @@ -388,238 +405,27 @@ add_origin (CallsManager *self, CallsOrigin *origin) calls_origin_foreach_call (origin, (CallsOriginForeachCallFunc) add_call, self); } - static void -remove_call_cb (gpointer self, CallsCall *call, CallsOrigin *origin) +on_origins_changed (GListModel *model, + guint position, + guint removed, + guint added, + CallsManager *self) { - remove_call (self, call, NULL, origin); -} - - -static void -remove_origin (CallsManager *self, CallsOrigin *origin) -{ - g_autofree const char *name = NULL; - guint position; - g_assert (CALLS_IS_MANAGER (self)); - g_assert (CALLS_IS_ORIGIN (origin)); + g_assert (model == G_LIST_MODEL (self->origins_flat)); - name = calls_origin_get_name (origin); - g_debug ("Removing origin %s (%p)", name, origin); + for (guint i = 0; i < added; i++) { + g_autoptr (CallsOrigin) origin = g_list_model_get_item (model, position + i); - g_signal_handlers_disconnect_by_data (origin, self); - - calls_origin_foreach_call (origin, remove_call_cb, self); - - if (!g_list_store_find (self->origins, origin, &position)) - g_warning ("Origin %p not found in list store while trying to remove it", - origin); - else - g_list_store_remove (self->origins, position); -} - -/* rebuild_origins_by_protocols() when any origins were added or removed */ -static void -rebuild_origins_by_protocols (CallsManager *self) -{ - GHashTableIter iter; - gpointer value; - guint n_origins; - - g_assert (CALLS_IS_MANAGER (self)); - - /* Remove everything */ - g_hash_table_iter_init (&iter, self->origins_by_protocol); - - while (g_hash_table_iter_next (&iter, NULL, &value)) { - GListStore *store = G_LIST_STORE (value); - g_list_store_remove_all (store); - } - - /* Iterate over all origins and check which protocols they support */ - n_origins = g_list_model_get_n_items (G_LIST_MODEL (self->origins)); - - for (guint i = 0; i < n_origins; i++) { - g_autoptr (CallsOrigin) origin = - g_list_model_get_item (G_LIST_MODEL (self->origins), i); - - for (guint j = 0; j < G_N_ELEMENTS (protocols); j++) { - GListStore *store = - G_LIST_STORE (g_hash_table_lookup (self->origins_by_protocol, protocols[j])); - - g_assert (store); - - if (calls_origin_supports_protocol (origin, protocols[j])) - g_list_store_append (store, origin); - } + add_origin (self, origin); } + update_state_flags (self); update_protocol_dial_actions (self); } -static void -remove_provider (CallsManager *self, - const char *name) -{ - g_autoptr (CallsProvider) provider = NULL; - - GListModel *origins; - guint n_items; - - g_assert (CALLS_IS_MANAGER (self)); - g_assert (name); - - provider = g_hash_table_lookup (self->providers, name); - if (provider) { - /* Hold a ref since g_hash_table_remove () might drop the last one */ - g_object_ref (provider); - } else { - g_warning ("Trying to remove provider %s which has not been found", name); - return; - } - - g_debug ("Remove provider: %s", name); - g_signal_handlers_disconnect_by_data (provider, self); - - origins = calls_provider_get_origins (provider); - g_signal_handlers_disconnect_by_data (origins, self); - n_items = g_list_model_get_n_items (origins); - - for (guint i = 0; i < n_items; i++) { - g_autoptr (CallsOrigin) origin = NULL; - - origin = g_list_model_get_item (origins, i); - remove_origin (self, origin); - } - - g_hash_table_remove (self->providers, name); - calls_provider_unload_plugin (name); - - rebuild_origins_by_protocols (self); - update_state_flags (self); - - g_signal_emit (self, signals[PROVIDERS_CHANGED], 0); -} - - -static gboolean -origin_found_in_any_provider (CallsManager *self, - CallsOrigin *origin) -{ - GHashTableIter iter; - gpointer value; - - g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); - g_return_val_if_fail (CALLS_IS_ORIGIN (origin), FALSE); - - g_hash_table_iter_init (&iter, self->providers); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - guint position; - CallsProvider *provider = CALLS_PROVIDER (value); - GListModel *origins = calls_provider_get_origins (provider); - - if (origins && calls_find_in_model (origins, - origin, - &position)) - return TRUE; - } - - return FALSE; -} - - -static void -origin_items_changed_cb (GListModel *model, - guint position, - guint removed, - guint added, - CallsManager *self) -{ - guint i; - CallsOrigin *origin; - guint purged = 0; - guint total_origins; - - g_assert (CALLS_IS_MANAGER (self)); - - total_origins = g_list_model_get_n_items (G_LIST_MODEL (self->origins)); - g_debug ("origins changed: pos=%d rem=%d added=%d total=%d", - position, removed, added, g_list_model_get_n_items (model)); - - /* Check stale/removed origins: We need to look up */ - if (removed == 0) - goto skip_remove; - - for (i = 0; i < total_origins - purged; i++) { - origin = g_list_model_get_item (G_LIST_MODEL (self->origins), i - purged); - - if (!origin_found_in_any_provider (self, origin)) { - remove_origin (self, origin); - purged++; - } - } - - /** The number of purged entries from self->origins must be equal to removed - * origins from the providers list - */ - if (purged != removed) { - g_warning ("Managed origins are not in sync anymore!"); - } - -skip_remove: - for (i = 0; i < added; i++) { - g_debug ("before adding: %d", - g_list_model_get_n_items (G_LIST_MODEL (self->origins))); - - origin = g_list_model_get_item (model, position + i); - add_origin (self, origin); // add to list store - g_object_unref (origin); - - g_debug ("after adding: %d", - g_list_model_get_n_items (G_LIST_MODEL (self->origins))); - } - - rebuild_origins_by_protocols (self); - update_state_flags (self); -} - - -static void -add_provider (CallsManager *self, const gchar *name) -{ - GListModel *origins; - CallsProvider *provider; - guint n_items; - - g_assert (CALLS_IS_MANAGER (self)); - g_assert (name); - - if (g_hash_table_lookup (self->providers, name)) - return; - - provider = calls_provider_load_plugin (name); - if (provider == NULL) { - g_warning ("Could not load a plugin with name `%s'", name); - return; - } - - g_hash_table_insert (self->providers, g_strdup (name), provider); - - origins = calls_provider_get_origins (provider); - - g_signal_connect_object (origins, "items-changed", - G_CALLBACK (origin_items_changed_cb), self, - G_CONNECT_AFTER); - - n_items = g_list_model_get_n_items (origins); - origin_items_changed_cb (origins, 0, 0, n_items, self); - - g_signal_emit (self, signals[PROVIDERS_CHANGED], 0); -} - - static void calls_manager_get_property (GObject *object, guint property_id, @@ -649,7 +455,6 @@ calls_manager_finalize (GObject *object) g_clear_object (&self->contacts_provider); g_clear_pointer (&self->origins_by_protocol, g_hash_table_unref); - g_clear_pointer (&self->providers, g_hash_table_unref); g_clear_pointer (&self->dial_actions_by_protocol, g_hash_table_unref); G_OBJECT_CLASS (calls_manager_parent_class)->finalize (object); @@ -736,36 +541,101 @@ calls_manager_class_init (CallsManagerClass *klass) } +static void +on_providers_changed (GListModel *model, + guint position, + guint removed, + guint added, + CallsManager *self) +{ + g_autoptr (GPtrArray) origins_add = g_ptr_array_sized_new (added); + + g_assert (CALLS_IS_MANAGER (self)); + + g_debug ("Provider changed at pos %u; removed %u; added %u", + position, removed, added); + + for (guint i = 0; i < added; i++) { + g_autoptr (CallsProvider) provider = + g_list_model_get_item (model, position + i); + + g_ptr_array_add (origins_add, calls_provider_get_origins (provider)); + g_debug ("Adding provider %s with %u items", + calls_provider_get_name (provider), + g_list_model_get_n_items (calls_provider_get_origins (provider))); + } + + g_list_store_splice (self->origins, + position, + removed, + origins_add->pdata, + added); + + if (removed > 0) { + GHashTableIter calls_iter; + gpointer key; + + g_hash_table_iter_init (&calls_iter, self->calls); + while (g_hash_table_iter_next (&calls_iter, &key, NULL)) { + gpointer origin = g_object_get_data (G_OBJECT (key), "call-origin"); + + if (!calls_find_in_model (G_LIST_MODEL (self->origins_flat), origin, NULL)) + calls_call_hang_up (CALLS_CALL (key)); + } + } + + update_state_flags (self); +} + + static void calls_manager_init (CallsManager *self) { g_autoptr (GVariantType) variant_type = NULL; GApplication *application; - PeasEngine *peas; - const gchar *dir; - g_autofree char *default_plugin_dir_provider = NULL; + CallsPluginManager *plugin_manager = calls_plugin_manager_get_default (); + GListModel *providers; self->state_flags = CALLS_MANAGER_FLAGS_UNKNOWN; - self->providers = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); + + self->origins = g_list_store_new (G_TYPE_LIST_MODEL); /* list of lists */ + self->origins_flat = gtk_flatten_list_model_new (CALLS_TYPE_ORIGIN, G_LIST_MODEL (self->origins)); + + g_signal_connect_object (self->origins_flat, + "items-changed", + G_CALLBACK (on_origins_changed), + self, + 0); + + providers = calls_plugin_manager_get_providers (plugin_manager); + g_signal_connect_object (providers, + "items-changed", + G_CALLBACK (on_providers_changed), + self, + 0); /* G_CONNECT_DEFAULT */ + if (g_list_model_get_n_items (providers) > 0) + on_providers_changed (providers, 0, 0, g_list_model_get_n_items (providers), self); self->origins_by_protocol = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, + NULL, g_object_unref); for (guint i = 0; i < G_N_ELEMENTS (protocols); i++) { - GListStore *origin_store = g_list_store_new (calls_origin_get_type ()); + g_autoptr (GtkFilter) filter = + gtk_custom_filter_new (match_origin_supports_protocol, (gpointer) protocols[i], NULL); + GtkFilterListModel *f_list = + gtk_filter_list_model_new (G_LIST_MODEL (self->origins_flat), filter); + + g_debug ("Adding filter list model for protocol '%s'", protocols[i]); g_hash_table_insert (self->origins_by_protocol, - g_strdup (protocols[i]), - origin_store); + (gpointer) protocols[i], + f_list); } self->dial_actions_by_protocol = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, + NULL, g_object_unref); application = g_application_get_default (); @@ -780,7 +650,7 @@ calls_manager_init (CallsManager *self) self); g_hash_table_insert (self->dial_actions_by_protocol, - g_strdup (protocols[i]), + (gpointer) protocols[i], g_object_ref (action)); /* Enable action if there are suitable origins */ @@ -791,36 +661,12 @@ calls_manager_init (CallsManager *self) g_action_map_add_action (G_ACTION_MAP (application), G_ACTION (action)); } - self->origins = g_list_store_new (calls_origin_get_type ()); - /* This hash table only owns the value, not the key */ self->calls = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref); self->settings = calls_settings_get_default (); - // Load the contacts provider + /* Load the contacts provider */ self->contacts_provider = calls_contacts_provider_new (); - - peas = peas_engine_get_default (); - - dir = g_getenv ("CALLS_PLUGIN_DIR"); - if (dir && dir[0] != '\0') { - g_autofree char *plugin_dir_provider = NULL; - - plugin_dir_provider = g_build_filename (dir, "provider", NULL); - - if (g_file_test (plugin_dir_provider, G_FILE_TEST_EXISTS)) { - g_debug ("Adding %s to plugin search path", plugin_dir_provider); - peas_engine_prepend_search_path (peas, plugin_dir_provider, NULL); - } else { - g_warning ("Not adding %s to plugin search path, because the directory doesn't exist. Check if env CALLS_PLUGIN_DIR is set correctly", plugin_dir_provider); - } - } - - default_plugin_dir_provider = g_build_filename(PLUGIN_LIBDIR, "provider", NULL); - peas_engine_add_search_path (peas, default_plugin_dir_provider, NULL); - g_debug ("Scanning for plugins in `%s'", default_plugin_dir_provider); - - peas_engine_rescan_plugins (peas); } @@ -853,55 +699,6 @@ calls_manager_get_contacts_provider (CallsManager *self) } -void -calls_manager_add_provider (CallsManager *self, - const char *name) -{ - g_return_if_fail (CALLS_IS_MANAGER (self)); - g_return_if_fail (name); - - add_provider (self, name); -} - - -void -calls_manager_remove_provider (CallsManager *self, - const char *name) -{ - g_return_if_fail (CALLS_IS_MANAGER (self)); - g_return_if_fail (name); - - remove_provider (self, name); -} - - -gboolean -calls_manager_has_provider (CallsManager *self, - const char *name) -{ - g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); - g_return_val_if_fail (name, FALSE); - - return !!g_hash_table_lookup (self->providers, name); -} - - -gboolean -calls_manager_is_modem_provider (CallsManager *self, - const char *name) -{ - CallsProvider *provider; - - g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); - g_return_val_if_fail (name, FALSE); - - provider = g_hash_table_lookup (self->providers, name); - g_return_val_if_fail (provider, FALSE); - - return calls_provider_is_modem (provider); -} - - CallsManagerFlags calls_manager_get_state_flags (CallsManager *self) { @@ -916,7 +713,7 @@ calls_manager_get_origins (CallsManager *self) { g_return_val_if_fail (CALLS_IS_MANAGER (self), NULL); - return G_LIST_MODEL (self->origins); + return G_LIST_MODEL (self->origins_flat); } @@ -952,7 +749,7 @@ calls_manager_hang_up_all_calls (CallsManager *self) g_return_if_fail (CALLS_IS_MANAGER (self)); - origins = G_LIST_MODEL (self->origins); + origins = G_LIST_MODEL (self->origins_flat); n_items = g_list_model_get_n_items (origins); for (uint i = 0; i < n_items; i++) { @@ -996,58 +793,6 @@ calls_manager_get_suitable_origins (CallsManager *self, return NULL; } -/** - * calls_manager_has_any_provider: - * @self: The #CallsManager - * - * Returns: %TRUE if any provider is loaded, %FALSE otherwise - */ -gboolean -calls_manager_has_any_provider (CallsManager *self) -{ - g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); - - return !!g_hash_table_size (self->providers); -} - -/** - * calls_manager_get_provider_names: - * @self: The #CallsManager - * @length: (optional) (out): the length of the returned array - * - * Retrieves the names of all providers loaded by @self, as an array. - * - * You should free the return value with g_free(). - * - * Returns: (array length=length) (transfer container): a - * %NULL-terminated array containing the names of providers. - */ -const char ** -calls_manager_get_provider_names (CallsManager *self, - guint *length) -{ - g_return_val_if_fail (CALLS_IS_MANAGER (self), NULL); - - return (const char **) g_hash_table_get_keys_as_array (self->providers, length); -} - -/** - * calls_manager_get_providers: - * @self: A #CallsManager - * - * Get the currently loaded providers - * - * Returns: (transfer container): A #GList of #CallsProvider. - * Use g_list_free() when done using the list. - */ -GList * -calls_manager_get_providers (CallsManager *self) -{ - g_return_val_if_fail (CALLS_IS_MANAGER (self), NULL); - - return g_hash_table_get_values (self->providers); -} - CallsSettings * calls_manager_get_settings (CallsManager *self) @@ -1076,10 +821,10 @@ calls_manager_get_origin_by_id (CallsManager *self, if (STR_IS_NULL_OR_EMPTY (origin_id)) return NULL; - n_origins = g_list_model_get_n_items (G_LIST_MODEL (self->origins)); + n_origins = g_list_model_get_n_items (G_LIST_MODEL (self->origins_flat)); for (uint i = 0; i < n_origins; i++) { g_autoptr (CallsOrigin) origin = - g_list_model_get_item (G_LIST_MODEL (self->origins), i); + g_list_model_get_item (G_LIST_MODEL (self->origins_flat), i); g_autofree char *id = calls_origin_get_id (origin); if (g_strcmp0 (id, origin_id) == 0) diff --git a/src/calls-manager.h b/src/calls-manager.h index b42e970..61f544d 100644 --- a/src/calls-manager.h +++ b/src/calls-manager.h @@ -51,14 +51,6 @@ CallsManager *calls_manager_new (void); CallsManager *calls_manager_get_default (void); CallsContactsProvider *calls_manager_get_contacts_provider (CallsManager *self); CallsSettings *calls_manager_get_settings (CallsManager *self); -void calls_manager_add_provider (CallsManager *self, - const char *name); -void calls_manager_remove_provider (CallsManager *self, - const char *name); -gboolean calls_manager_has_provider (CallsManager *self, - const char *name); -gboolean calls_manager_is_modem_provider (CallsManager *self, - const char *name); CallsManagerFlags calls_manager_get_state_flags (CallsManager *self); GListModel *calls_manager_get_origins (CallsManager *self); GList *calls_manager_get_calls (CallsManager *self); @@ -67,9 +59,5 @@ GListModel *calls_manager_get_suitable_origins (CallsManager *sel CallsOrigin *calls_manager_get_origin_by_id (CallsManager *self, const char *origin_id); void calls_manager_hang_up_all_calls (CallsManager *self); -gboolean calls_manager_has_any_provider (CallsManager *self); -const char **calls_manager_get_provider_names (CallsManager *self, - guint *length); -GList *calls_manager_get_providers (CallsManager *self); G_END_DECLS diff --git a/src/calls-provider.c b/src/calls-provider.c index a8d3de1..cac7be2 100644 --- a/src/calls-provider.c +++ b/src/calls-provider.c @@ -187,72 +187,6 @@ calls_provider_get_origins (CallsProvider *self) return CALLS_PROVIDER_GET_CLASS (self)->get_origins (self); } -/** - * calls_provider_load_plugin: - * @name: The name of the provider plugin to load - * - * Get a #CallsProvider plugin by name - * - * Returns: (transfer full): A #CallsProvider - */ -CallsProvider * -calls_provider_load_plugin (const char *name) -{ - g_autoptr (GError) error = NULL; - PeasEngine *plugins; - PeasPluginInfo *info; - PeasExtension *extension; - - plugins = peas_engine_get_default (); - - // Find the plugin - info = peas_engine_get_plugin_info (plugins, name); - if (!info) { - g_debug ("Could not find plugin `%s'", name); - return NULL; - } - - // Possibly load the plugin - if (!peas_plugin_info_is_loaded (info)) { - peas_engine_load_plugin (plugins, info); - - if (!peas_plugin_info_is_available (info, &error)) { - g_debug ("Error loading plugin `%s': %s", name, error->message); - return NULL; - } - - g_debug ("Loaded plugin `%s'", name); - } - - // Check the plugin provides CallsProvider - if (!peas_engine_provides_extension (plugins, info, CALLS_TYPE_PROVIDER)) { - g_debug ("Plugin `%s' does not have a provider extension", name); - return NULL; - } - - // Get the extension - extension = peas_engine_create_extensionv (plugins, info, CALLS_TYPE_PROVIDER, 0, NULL); - if (!extension) { - g_debug ("Could not create provider from plugin `%s'", name); - return NULL; - } - - g_debug ("Created provider from plugin `%s'", name); - return CALLS_PROVIDER (extension); -} - -void -calls_provider_unload_plugin (const char *name) -{ - PeasEngine *engine = peas_engine_get_default (); - PeasPluginInfo *plugin = peas_engine_get_plugin_info (engine, name); - - if (plugin) - peas_engine_unload_plugin (engine, plugin); - else - g_warning ("Can't unload plugin: No plugin with name %s found", name); -} - /** * calls_provider_get_protocols: * @self: A #CallsProvider diff --git a/src/calls-provider.h b/src/calls-provider.h index b161de1..f6a8464 100644 --- a/src/calls-provider.h +++ b/src/calls-provider.h @@ -53,8 +53,6 @@ struct _CallsProviderClass { const char *calls_provider_get_name (CallsProvider *self); 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); gboolean calls_provider_is_modem (CallsProvider *self); gboolean calls_provider_is_operational (CallsProvider *self); diff --git a/tests/meson.build b/tests/meson.build index aeaacf4..c9bdc3d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -52,7 +52,6 @@ t = executable('emergency-call-types', test_sources, ) test('emergency-call-types', t, env: test_env) - test_sources = [ 'test-manager.c' ] t = executable('manager', test_sources, diff --git a/tests/services/calls-server.c b/tests/services/calls-server.c index ac33374..e6c339b 100644 --- a/tests/services/calls-server.c +++ b/tests/services/calls-server.c @@ -11,6 +11,7 @@ #include "calls-manager.h" #include "calls-dbus-manager.h" +#include "calls-plugin-manager.h" #include @@ -51,8 +52,10 @@ int main (int argc, char *argv[]) { g_autoptr (CallsManager) manager = NULL; - CallsDBusManager *dbus_manager = NULL; + g_autoptr (CallsPluginManager) plugin_manager = NULL; g_autoptr (GMainLoop) loop = g_main_loop_new (NULL, FALSE); + g_autoptr (GError) error = NULL; + CallsDBusManager *dbus_manager = NULL; guint bus_id; /* Setup environment */ @@ -62,9 +65,11 @@ main (int argc, char *argv[]) g_print ("Starting up DBus service\n"); + plugin_manager = calls_plugin_manager_get_default (); manager = calls_manager_get_default (); dbus_manager = calls_dbus_manager_new (); - calls_manager_add_provider (manager, "dummy"); + g_assert_true (calls_plugin_manager_load_plugin (plugin_manager, "dummy", &error)); + g_assert_no_error (error); bus_id = g_bus_own_name (G_BUS_TYPE_SESSION, CALLS_DBUS_NAME, @@ -79,7 +84,8 @@ main (int argc, char *argv[]) g_print ("Shutting down DBus service\n"); - calls_manager_remove_provider (manager, "dummy"); + g_assert_true (calls_plugin_manager_unload_plugin (plugin_manager, "dummy", &error)); + g_assert_no_error (error); /* The DBus manager unexports any objects it may still have. * Do this before releasing the DBus name ownership */ diff --git a/tests/test-manager.c b/tests/test-manager.c index a4d2256..ffac885 100644 --- a/tests/test-manager.c +++ b/tests/test-manager.c @@ -5,6 +5,8 @@ */ #include "calls-manager.h" +#include "calls-plugin-manager.h" +#include "calls-util.h" #include #include @@ -12,6 +14,7 @@ struct TestData { GMainLoop *loop; CallsManager *manager; + CallsPluginManager *plugin_manager; GListModel *origins; GListModel *origins_tel; CallsOrigin *origin; @@ -24,6 +27,7 @@ call_add_cb (CallsManager *manager, struct TestData *data) { static guint phase = 0; + g_autoptr (GError) error = NULL; data->call = call; switch (phase++) { @@ -33,9 +37,11 @@ call_add_cb (CallsManager *manager, case 1: /* Unload the provider */ - calls_manager_remove_provider (data->manager, "dummy"); - g_assert_false (calls_manager_has_provider (data->manager, "dummy")); - g_assert_false (calls_manager_has_any_provider (data->manager)); + calls_plugin_manager_unload_plugin (data->plugin_manager, "dummy", &error); + g_assert_false (calls_plugin_manager_has_plugin (data->plugin_manager, "dummy")); + g_assert_false (calls_plugin_manager_has_any_plugins (data->plugin_manager)); + g_assert_cmpuint (g_list_model_get_n_items (calls_manager_get_origins (data->manager)), + ==, 0); break; @@ -72,19 +78,20 @@ call_remove_cb (CallsManager *manager, static void test_calls_manager_without_provider (void) { - guint no_origins; GListModel *origins; - g_autoptr (CallsManager) manager = calls_manager_new (); + CallsManager *manager = calls_manager_get_default (); + CallsPluginManager *plugin_manager = calls_plugin_manager_get_default (); + g_assert_true (CALLS_IS_MANAGER (manager)); + g_assert_true (CALLS_IS_PLUGIN_MANAGER (plugin_manager)); g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_UNKNOWN); origins = calls_manager_get_origins (manager); - no_origins = g_list_model_get_n_items (origins); - g_assert_cmpuint (no_origins, ==, 0); + g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0); g_assert_null (calls_manager_get_calls (manager)); - g_assert_false (calls_manager_has_any_provider (manager)); + g_assert_false (calls_plugin_manager_has_any_plugins (plugin_manager)); origins = calls_manager_get_suitable_origins (manager, "tel:+123456789"); g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0); @@ -94,11 +101,16 @@ test_calls_manager_without_provider (void) origins = calls_manager_get_suitable_origins (manager, "sips:bob@example.org"); g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0); + + g_assert_finalize_object (manager); + g_assert_finalize_object (plugin_manager); } + static void test_calls_manager_dummy_provider (void) { + g_autoptr (GError) error = NULL; CallsManager *manager; GListModel *origins; GListModel *origins_tel; @@ -106,7 +118,9 @@ test_calls_manager_dummy_provider (void) struct TestData *test_data; test_data = g_new0 (struct TestData, 1); - test_data->manager = calls_manager_new (); + test_data->manager = calls_manager_get_default (); + test_data->plugin_manager = calls_plugin_manager_get_default (); + manager = test_data->manager; g_assert_true (CALLS_IS_MANAGER (manager)); g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_UNKNOWN); @@ -117,9 +131,11 @@ test_calls_manager_dummy_provider (void) g_assert_true (origins); g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0); - calls_manager_add_provider (manager, "dummy"); - g_assert_true (calls_manager_has_any_provider (manager)); - g_assert_true (calls_manager_has_provider (manager, "dummy")); + g_assert_true (calls_plugin_manager_load_plugin (test_data->plugin_manager, "dummy", &error)); + g_assert_no_error (error); + + g_assert_true (calls_plugin_manager_has_any_plugins (test_data->plugin_manager)); + g_assert_true (calls_plugin_manager_has_plugin (test_data->plugin_manager, "dummy")); /* Dummy plugin fakes being a modem */ g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_HAS_CELLULAR_PROVIDER | @@ -134,8 +150,7 @@ test_calls_manager_dummy_provider (void) test_data->origins_tel = calls_manager_get_suitable_origins (manager, "tel:+393422342"); origins_tel = test_data->origins_tel; g_assert_true (G_IS_LIST_MODEL (origins_tel)); - g_assert_true (G_IS_LIST_STORE (origins_tel)); - g_assert_true (g_list_store_find (G_LIST_STORE (origins_tel), test_data->origin, &position)); + g_assert_true (calls_find_in_model (origins_tel, test_data->origin, &position)); g_signal_connect (manager, "ui-call-added", G_CALLBACK (call_add_cb), test_data); g_signal_connect (manager, "ui-call-removed", G_CALLBACK (call_remove_cb), test_data); @@ -155,22 +170,29 @@ test_calls_manager_dummy_provider (void) g_assert_finalize_object (test_data->origin); g_assert_finalize_object (test_data->manager); + g_assert_finalize_object (test_data->plugin_manager); g_free (test_data); } + static void test_calls_manager_mm_provider (void) { GListModel *origins_tel; - g_autoptr (CallsManager) manager = calls_manager_new (); + CallsManager *manager = calls_manager_get_default (); + CallsPluginManager *plugin_manager = calls_plugin_manager_get_default (); + g_autoptr (GError) error = NULL; + g_assert_true (CALLS_IS_MANAGER (manager)); + g_assert_true (CALLS_IS_PLUGIN_MANAGER (plugin_manager)); g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_UNKNOWN); - calls_manager_add_provider (manager, "mm"); - g_assert_true (calls_manager_has_any_provider (manager)); - g_assert_true (calls_manager_has_provider (manager, "mm")); + g_assert_true (calls_plugin_manager_load_plugin (plugin_manager, "mm", &error)); + g_assert_no_error (error); + g_assert_true (calls_plugin_manager_has_any_plugins (plugin_manager)); + g_assert_true (calls_plugin_manager_has_plugin (plugin_manager, "mm")); g_assert_cmpuint (calls_manager_get_state_flags (manager), >, CALLS_MANAGER_FLAGS_UNKNOWN); @@ -180,22 +202,28 @@ test_calls_manager_mm_provider (void) g_assert_nonnull (origins_tel); g_assert_cmpuint (g_list_model_get_n_items (origins_tel), ==, 0); - calls_manager_remove_provider (manager, "mm"); + g_assert_true (calls_plugin_manager_unload_plugin (plugin_manager, "mm", &error)); + g_assert_no_error (error); g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_UNKNOWN); + + g_assert_finalize_object (manager); + g_assert_finalize_object (plugin_manager); } + static void test_calls_manager_multiple_providers_mm_sip (void) { - g_autoptr (CallsOrigin) origin_alice = NULL; - g_autoptr (CallsOrigin) origin_bob = NULL; - g_autoptr (CallsManager) manager = calls_manager_new (); + CallsManager *manager = calls_manager_get_default (); + CallsPluginManager *plugin_manager = calls_plugin_manager_get_default (); GListModel *origins; GListModel *origins_tel; GListModel *origins_sip; GListModel *origins_sips; + g_autoptr (GError) error = NULL; g_assert_true (CALLS_IS_MANAGER (manager)); + g_assert_true (CALLS_IS_PLUGIN_MANAGER (plugin_manager)); origins = calls_manager_get_origins (manager); g_assert_true (G_IS_LIST_MODEL (origins)); @@ -215,10 +243,7 @@ test_calls_manager_multiple_providers_mm_sip (void) g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0); /* First add the SIP provider, MM provider later */ - calls_manager_add_provider (manager, "sip"); - g_assert_true (calls_manager_has_any_provider (manager)); - g_assert_true (calls_manager_has_provider (manager, "sip")); - g_assert_true (calls_manager_is_modem_provider (manager, "sip") == FALSE); + g_assert_true (calls_plugin_manager_load_plugin (plugin_manager, "sip", &error)); g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_HAS_VOIP_PROVIDER); /* Still no origins */ @@ -237,13 +262,13 @@ test_calls_manager_multiple_providers_mm_sip (void) * see https://source.puri.sm/Librem5/calls/-/issues/280 * and https://source.puri.sm/Librem5/calls/-/issues/178 */ - calls_manager_add_provider (manager, "mm"); - g_assert_true (calls_manager_has_any_provider (manager)); - g_assert_true (calls_manager_has_provider (manager, "mm")); + g_assert_true (calls_plugin_manager_load_plugin (plugin_manager, "mm", &error)); g_assert_cmpuint (calls_manager_get_state_flags (manager), ==, CALLS_MANAGER_FLAGS_HAS_VOIP_PROVIDER | CALLS_MANAGER_FLAGS_HAS_CELLULAR_PROVIDER); + g_assert_finalize_object (manager); + g_assert_finalize_object (plugin_manager); } gint