diff --git a/src/calls-manager.c b/src/calls-manager.c index 3b0c871..2b185ac 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -23,9 +23,13 @@ */ #include "config.h" -#include "calls-ussd.h" -#include "calls-manager.h" + +#include "calls-account-provider.h" #include "calls-contacts-provider.h" +#include "calls-manager.h" +#include "calls-provider.h" +#include "calls-ussd.h" + #include "enum-types.h" #include @@ -742,6 +746,74 @@ calls_manager_has_provider (CallsManager *self, 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); +} + +/** + * calls_manager_provder_add_accounts: + * @self: A #CallsManager + * @name: The name of the provider to add the account to + * @credentials: A #CallsCredentials storing the credentials of the account + * + * Returns: %TRUE if account successfully added, %FALSE otherwise + */ +gboolean +calls_manager_provider_add_account (CallsManager *self, + const char *name, + CallsCredentials *credentials) +{ + CallsProvider *provider = NULL; + + g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); + g_return_val_if_fail (name, FALSE); + g_return_val_if_fail (CALLS_IS_CREDENTIALS (credentials), FALSE); + + provider = g_hash_table_lookup (self->providers, name); + g_return_val_if_fail (CALLS_IS_PROVIDER (provider), FALSE); + g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (provider), FALSE); + + return calls_account_provider_add_account (CALLS_ACCOUNT_PROVIDER (provider), + credentials); +} +/** + * calls_manager_provder_remove_accounts: + * @self: A #CallsManager + * @name: The name of the provider to add the account to + * @credentials: A #CallsCredentials storing the credentials of the account + * + * Returns: %TRUE if account successfully removed, %FALSE otherwise + */ +gboolean +calls_manager_provider_remove_account (CallsManager *self, + const char *name, + CallsCredentials *credentials) +{ + CallsProvider *provider = NULL; + + g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); + g_return_val_if_fail (name, FALSE); + g_return_val_if_fail (CALLS_IS_CREDENTIALS (credentials), FALSE); + + provider = g_hash_table_lookup (self->providers, name); + g_return_val_if_fail (CALLS_IS_PROVIDER (provider), FALSE); + g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (provider), FALSE); + + return calls_account_provider_remove_account (CALLS_ACCOUNT_PROVIDER (provider), + credentials); +} + CallsManagerState calls_manager_get_state (CallsManager *self) { diff --git a/src/calls-manager.h b/src/calls-manager.h index 2406861..73d4141 100644 --- a/src/calls-manager.h +++ b/src/calls-manager.h @@ -25,8 +25,8 @@ #pragma once #include "calls-contacts-provider.h" -#include "calls-provider.h" #include "calls-origin.h" +#include "calls-credentials.h" #include @@ -56,6 +56,14 @@ void calls_manager_remove_provider (CallsManager const char *name); gboolean calls_manager_has_provider (CallsManager *self, const char *name); +gboolean calls_manager_is_modem_provider (CallsManager *self, + const char *name); +gboolean calls_manager_provider_add_account (CallsManager *self, + const char *provider, + CallsCredentials *credentials); +gboolean calls_manager_provider_remove_account (CallsManager *self, + const char *provider, + CallsCredentials *credentials); CallsManagerState calls_manager_get_state (CallsManager *self); GListModel *calls_manager_get_origins (CallsManager *self); GList *calls_manager_get_calls (CallsManager *self); diff --git a/tests/test-manager.c b/tests/test-manager.c index 8c1fb18..22e102d 100644 --- a/tests/test-manager.c +++ b/tests/test-manager.c @@ -5,6 +5,7 @@ */ #include "calls-manager.h" +#include "calls-credentials.h" #include #include @@ -52,8 +53,8 @@ test_calls_manager_dummy_provider () GListModel *origins_tel; guint position; g_autoptr (CallsOrigin) origin = NULL; - g_assert_true (CALLS_IS_MANAGER (manager)); + g_assert_true (CALLS_IS_MANAGER (manager)); g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_PROVIDER); origins = calls_manager_get_origins (manager); @@ -92,6 +93,7 @@ test_calls_manager_dummy_provider () g_assert_null (test_call); g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0); + g_assert_cmpuint (g_list_model_get_n_items (origins_tel), ==, 0); g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_PROVIDER); } @@ -99,6 +101,7 @@ test_calls_manager_dummy_provider () static void test_calls_manager_mm_provider () { + GListModel *origins_tel; g_autoptr (CallsManager) manager = calls_manager_new (); g_assert_true (CALLS_IS_MANAGER (manager)); @@ -106,12 +109,118 @@ test_calls_manager_mm_provider () calls_manager_add_provider (manager, "mm"); g_assert_cmpuint (calls_manager_get_state (manager), >, CALLS_MANAGER_STATE_NO_PROVIDER); + g_assert_null (calls_manager_get_calls (manager)); + origins_tel = calls_manager_get_suitable_origins (manager, "tel:+123456789"); + 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_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_PROVIDER); } +static void +test_calls_manager_multiple_providers_mm_sip () +{ + g_autoptr (CallsCredentials) alice = NULL; + g_autoptr (CallsCredentials) bob = NULL; + g_autoptr (CallsOrigin) origin_alice = NULL; + g_autoptr (CallsOrigin) origin_bob = NULL; + g_autoptr (CallsManager) manager = calls_manager_new (); + GListModel *origins; + GListModel *origins_tel; + GListModel *origins_sip; + GListModel *origins_sips; + + g_assert_true (CALLS_IS_MANAGER (manager)); + + origins = calls_manager_get_origins (manager); + g_assert_true (G_IS_LIST_MODEL (origins)); + + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_PROVIDER); + g_assert_null (calls_manager_get_suitable_origins (manager, "tel:+123456789")); + g_assert_null (calls_manager_get_suitable_origins (manager, "sip:alice@example.org")); + g_assert_null (calls_manager_get_suitable_origins (manager, "sips:bob@example.org")); + + /* First add the SIP provider, MM provider later */ + calls_manager_add_provider (manager, "sip"); + g_assert_true (calls_manager_has_provider (manager, "sip")); + g_assert_true (calls_manager_is_modem_provider (manager, "sip") == FALSE); + + /* Now we should have (empty) GListModels for the suitable origins for our protocols */ + origins_tel = calls_manager_get_suitable_origins (manager, "tel:+123456789"); + g_assert_nonnull (origins_tel); + g_assert_cmpuint (g_list_model_get_n_items (origins_tel), ==, 0); + + origins_sip = calls_manager_get_suitable_origins (manager, "sip:alice@example.org"); + g_assert_nonnull (origins_sip); + g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 0); + + origins_sips = calls_manager_get_suitable_origins (manager, "sips:bob@example.org"); + g_assert_nonnull (origins_sips); + g_assert_cmpuint (g_list_model_get_n_items (origins_sips), ==, 0); + + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_ORIGIN); + + /* Add Alice SIP account */ + alice = calls_credentials_new (); + g_object_set (alice, + "name", "Alice", + "user", "alice", + "host", "example.org", + "password", "password123", + NULL); + g_assert_true (calls_manager_provider_add_account (manager, "sip", alice)); + g_assert_false (calls_manager_provider_add_account (manager, "sip", alice)); + + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_READY); + g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 1); + + /** + * Add a second SIP origin to mix things up. + * TODO We can expand on this later to test the call routing + * starting with a simple "default" mechanism for now + * needs https://source.puri.sm/Librem5/calls/-/issues/259 first though + */ + bob = calls_credentials_new (); + g_object_set (bob, + "name", "Bob", + "user", "bob", + "host", "example.org", + "password", "password123", + NULL); + + g_assert_true (calls_manager_provider_add_account (manager, "sip", bob)); + + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_READY); + g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 2); + + /** + * If we now load the MM plugin, the manager state should be *_STATE_NO_VOICE_MODEM + * (unless run on a phone I guess?) + * TODO DBus mock to add modems + * 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_provider (manager, "mm")); + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_VOICE_MODEM); + + /* Remove alice */ + g_assert_true (calls_manager_provider_remove_account (manager, "sip", alice)); + g_assert_false (calls_manager_provider_remove_account (manager, "sip", alice)); + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_VOICE_MODEM); + g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 1); + + /* Unload MM plugin, since we still have Bob we should be ready (and bob should be the default sip origin) */ + calls_manager_remove_provider (manager, "mm"); + g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_READY); + + g_assert_true (calls_manager_provider_remove_account (manager, "sip", bob)); + g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 0); +} + gint main (gint argc, gchar *argv[]) @@ -126,6 +235,7 @@ main (gint argc, g_test_add_func("/Calls/Manager/without_provider", test_calls_manager_without_provider); g_test_add_func("/Calls/Manager/dummy_provider", test_calls_manager_dummy_provider); g_test_add_func("/Calls/Manager/mm_provider", test_calls_manager_mm_provider); + g_test_add_func("/Calls/Manager/multiple_provider_mm_sip", test_calls_manager_multiple_providers_mm_sip); return g_test_run(); }