From 214eb99459311428d3bbdd7c448880b3a7fc8c84 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 1 Jul 2015 12:14:31 +0200 Subject: Bug 751701 - Update ESource's connection status after server connect --- .../backends/google/e-book-backend-google.c | 10 +++++++ addressbook/backends/ldap/e-book-backend-ldap.c | 1 + .../backends/webdav/e-book-backend-webdav.c | 5 ++++ calendar/backends/caldav/e-cal-backend-caldav.c | 3 ++ .../backends/contacts/e-cal-backend-contacts.c | 35 ++++++++++++++++++++++ calendar/backends/gtasks/e-cal-backend-gtasks.c | 14 +++++++++ calendar/backends/weather/e-cal-backend-weather.c | 2 ++ docs/reference/eds/eds-sections.txt | 6 ++++ libebackend/e-backend.c | 32 ++++++++++++++++++++ libebackend/e-backend.h | 2 ++ libebackend/e-collection-backend.c | 20 +++++++++++++ modules/google-backend/module-google-backend.c | 15 ++++++++++ 12 files changed, 145 insertions(+) diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c index d6b5faea9..b3e402254 100644 --- a/addressbook/backends/google/e-book-backend-google.c +++ b/addressbook/backends/google/e-book-backend-google.c @@ -766,6 +766,8 @@ get_new_contacts_cb (GDataService *service, GTimeVal current_time; g_get_current_time (¤t_time); cache_set_last_update (backend, ¤t_time); + + e_backend_ensure_source_status_connected (E_BACKEND (backend)); } /* Thaw the cache again */ @@ -926,6 +928,8 @@ get_groups_cb (GDataService *service, g_rec_mutex_lock (&priv->groups_lock); g_get_current_time (&(priv->groups_last_update)); g_rec_mutex_unlock (&priv->groups_lock); + + e_backend_ensure_source_status_connected (E_BACKEND (backend)); } finish_operation (backend, -2, gdata_error); @@ -1897,6 +1901,8 @@ exit: g_warn_if_fail (success == FALSE); data_book_error_from_gdata_error (error, gdata_error); g_error_free (gdata_error); + } else { + e_backend_ensure_source_status_connected (E_BACKEND (backend)); } return success; @@ -2113,6 +2119,8 @@ exit: g_warn_if_fail (success == FALSE); data_book_error_from_gdata_error (error, gdata_error); g_error_free (gdata_error); + } else { + e_backend_ensure_source_status_connected (E_BACKEND (backend)); } return success; @@ -2188,6 +2196,8 @@ book_backend_google_remove_contacts_sync (EBookBackend *backend, g_warn_if_fail (success == FALSE); data_book_error_from_gdata_error (error, gdata_error); g_error_free (gdata_error); + } else { + e_backend_ensure_source_status_connected (E_BACKEND (backend)); } return success; diff --git a/addressbook/backends/ldap/e-book-backend-ldap.c b/addressbook/backends/ldap/e-book-backend-ldap.c index 559ebbfd5..69b0b3a09 100644 --- a/addressbook/backends/ldap/e-book-backend-ldap.c +++ b/addressbook/backends/ldap/e-book-backend-ldap.c @@ -947,6 +947,7 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl, "e_book_backend_ldap_connect took %ld.%03ld seconds\n", diff / 1000,diff % 1000); } + e_backend_ensure_source_status_connected (E_BACKEND (bl)); return TRUE; } else if (ldap_error == LDAP_UNWILLING_TO_PERFORM) { if (blpriv->ldap) { diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c b/addressbook/backends/webdav/e-book-backend-webdav.c index ce9f8e7e7..438f3f5c5 100644 --- a/addressbook/backends/webdav/e-book-backend-webdav.c +++ b/addressbook/backends/webdav/e-book-backend-webdav.c @@ -224,6 +224,9 @@ send_and_handle_ssl (EBookBackendWebdav *webdav, status_code = soup_session_send_message (webdav->priv->session, message); + if (SOUP_STATUS_IS_SUCCESSFUL (status_code)) + e_backend_ensure_source_status_connected (E_BACKEND (webdav)); + return status_code; } @@ -1423,6 +1426,8 @@ book_backend_webdav_open_sync (EBookBackend *backend, } g_clear_error (&local_error2); + } else { + e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); } g_free (certificate_pem); diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c index bf25551a5..edc8fcad6 100644 --- a/calendar/backends/caldav/e-cal-backend-caldav.c +++ b/calendar/backends/caldav/e-cal-backend-caldav.c @@ -1146,6 +1146,9 @@ send_and_handle_redirection (ECalBackendCalDAV *cbdav, } g_free (old_uri); + + if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) + e_backend_ensure_source_status_connected (E_BACKEND (cbdav)); } static gchar * diff --git a/calendar/backends/contacts/e-cal-backend-contacts.c b/calendar/backends/contacts/e-cal-backend-contacts.c index 2ab4b6b9a..b600f6ec8 100644 --- a/calendar/backends/contacts/e-cal-backend-contacts.c +++ b/calendar/backends/contacts/e-cal-backend-contacts.c @@ -80,6 +80,8 @@ typedef struct _BookRecord { ECalBackendContacts *cbc; EBookClient *book_client; EBookClientView *book_view; + gboolean online; + gulong notify_online_id; } BookRecord; typedef struct _ContactRecord { @@ -171,6 +173,9 @@ book_record_unref (BookRecord *br) remove_by_book, br->book_client); g_rec_mutex_unlock (&br->cbc->priv->tracked_contacts_lock); + if (br->notify_online_id) + g_signal_handler_disconnect (br->book_client, br->notify_online_id); + g_mutex_clear (&br->lock); g_object_unref (br->cbc); g_object_unref (br->book_client); @@ -314,6 +319,34 @@ exit: return NULL; } +static void +book_client_notify_online_cb (EClient *client, + GParamSpec *param, + BookRecord *br) +{ + g_return_if_fail (E_IS_BOOK_CLIENT (client)); + g_return_if_fail (br != NULL); + + if ((br->online ? 1 : 0) == (e_client_is_online (client) ? 1 : 0)) + return; + + br->online = e_client_is_online (client); + + if (br->online) { + ECalBackendContacts *cbc; + ESource *source; + + cbc = g_object_ref (br->cbc); + source = g_object_ref (e_client_get_source (client)); + + cal_backend_contacts_remove_book_record (cbc, source); + create_book_record (cbc, source); + + g_clear_object (&source); + g_clear_object (&cbc); + } +} + static void book_client_connected_cb (GObject *source_object, GAsyncResult *result, @@ -343,6 +376,8 @@ book_client_connected_cb (GObject *source_object, source = e_client_get_source (client); br->book_client = g_object_ref (client); + br->online = e_client_is_online (client); + br->notify_online_id = g_signal_connect (client, "notify::online", G_CALLBACK (book_client_notify_online_cb), br); cal_backend_contacts_insert_book_record (br->cbc, source, br); thread = g_thread_new ( diff --git a/calendar/backends/gtasks/e-cal-backend-gtasks.c b/calendar/backends/gtasks/e-cal-backend-gtasks.c index 23ca79d54..073596702 100644 --- a/calendar/backends/gtasks/e-cal-backend-gtasks.c +++ b/calendar/backends/gtasks/e-cal-backend-gtasks.c @@ -443,6 +443,10 @@ ecb_gtasks_update_thread (gpointer user_data) feed = gdata_tasks_service_query_tasks (gtasks->priv->service, gtasks->priv->tasklist, GDATA_QUERY (tasks_query), cancellable, NULL, NULL, &local_error); + + if (!local_error) + e_backend_ensure_source_status_connected (E_BACKEND (gtasks)); + if (feed) { GList *link; const gchar *uid; @@ -565,6 +569,10 @@ ecb_gtasks_start_update (ECalBackendGTasks *gtasks) /* Check whether the tasklist changed */ feed = gdata_tasks_service_query_all_tasklists (gtasks->priv->service, NULL, cancellable, NULL, NULL, &local_error); + + if (!local_error) + e_backend_ensure_source_status_connected (E_BACKEND (gtasks)); + if (feed) { GList *link; @@ -1098,6 +1106,9 @@ ecb_gtasks_modify_objects (ECalBackend *backend, new_task = gdata_tasks_service_update_task (gtasks->priv->service, comp_task, cancellable, &local_error); g_object_unref (comp_task); + if (!local_error) + e_backend_ensure_source_status_connected (E_BACKEND (backend)); + if (!new_task) { g_object_unref (cached_comp); break; @@ -1185,6 +1196,9 @@ ecb_gtasks_remove_objects (ECalBackend *backend, break; } + if (!local_error) + e_backend_ensure_source_status_connected (E_BACKEND (backend)); + g_clear_error (&local_error); g_object_unref (task); diff --git a/calendar/backends/weather/e-cal-backend-weather.c b/calendar/backends/weather/e-cal-backend-weather.c index 3d1fefc81..6d1a29554 100644 --- a/calendar/backends/weather/e-cal-backend-weather.c +++ b/calendar/backends/weather/e-cal-backend-weather.c @@ -197,6 +197,8 @@ finished_retrieval_cb (GWeatherInfo *info, return; } + e_backend_ensure_source_status_connected (E_BACKEND (cbw)); + source = e_backend_get_source (E_BACKEND (cbw)); weather_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEATHER_BACKEND); diff --git a/docs/reference/eds/eds-sections.txt b/docs/reference/eds/eds-sections.txt index eeea8a177..aff97005f 100644 --- a/docs/reference/eds/eds-sections.txt +++ b/docs/reference/eds/eds-sections.txt @@ -102,6 +102,12 @@ e_backend_trust_prompt_finish e_backend_get_destination_address e_backend_is_destination_reachable e_backend_prepare_shutdown +e_backend_credentials_required_sync +e_backend_credentials_required +e_backend_credentials_required_finish +e_backend_schedule_credentials_required +e_backend_schedule_authenticate +e_backend_ensure_source_status_connected EBackendPrivate E_BACKEND diff --git a/libebackend/e-backend.c b/libebackend/e-backend.c index 2d26a7ee7..e6b5deee2 100644 --- a/libebackend/e-backend.c +++ b/libebackend/e-backend.c @@ -110,6 +110,13 @@ backend_network_monitor_can_reach_cb (GObject *source_object, e_backend_set_online (backend, host_is_reachable); + if (!host_is_reachable) { + ESource *source; + + source = e_backend_get_source (backend); + e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); + } + g_object_unref (backend); } @@ -1145,6 +1152,31 @@ e_backend_schedule_authenticate (EBackend *backend, g_clear_object (&cancellable); } +/** + * e_backend_ensure_source_status_connected: + * @backend: an #EBackend + * + * Makes sure that the associated ESource::connection-status is connected. This is + * useful in cases when the backend can connect to the destination without invoking + * EBackend::authenticate_sync, possibly through e_backend_schedule_authenticate(). + * + * Since: 3.16.4 + **/ +void +e_backend_ensure_source_status_connected (EBackend *backend) +{ + ESource *source; + + g_return_if_fail (E_IS_BACKEND (backend)); + + source = e_backend_get_source (backend); + + g_return_if_fail (E_IS_SOURCE (source)); + + if (e_source_get_connection_status (source) != E_SOURCE_CONNECTION_STATUS_CONNECTED) + e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); +} + /** * e_backend_get_user_prompter: * @backend: an #EBackend diff --git a/libebackend/e-backend.h b/libebackend/e-backend.h index bed359a83..96a57ffef 100644 --- a/libebackend/e-backend.h +++ b/libebackend/e-backend.h @@ -141,6 +141,8 @@ void e_backend_schedule_credentials_required const gchar *who_calls); void e_backend_schedule_authenticate (EBackend *backend, const ENamedParameters *credentials); +void e_backend_ensure_source_status_connected + (EBackend *backend); struct _EUserPrompter * e_backend_get_user_prompter (EBackend *backend); ETrustPromptResponse diff --git a/libebackend/e-collection-backend.c b/libebackend/e-collection-backend.c index d2717255a..e45bc4a03 100644 --- a/libebackend/e-collection-backend.c +++ b/libebackend/e-collection-backend.c @@ -73,6 +73,7 @@ struct _ECollectionBackendPrivate { gulong source_removed_handler_id; gulong notify_enabled_handler_id; gulong notify_collection_handler_id; + gulong notify_online_handler_id; guint scheduled_populate_idle_id; }; @@ -535,6 +536,17 @@ collection_backend_schedule_populate_idle (ECollectionBackend *backend) (GDestroyNotify) g_object_unref); } +static void +collection_backend_online_cb (EBackend *backend, + GParamSpec *spec, + gpointer user_data) +{ + g_return_if_fail (E_IS_COLLECTION_BACKEND (backend)); + + if (e_backend_get_online (backend)) + collection_backend_schedule_populate_idle (E_COLLECTION_BACKEND (backend)); +} + static void collection_backend_notify_collection_cb (ESourceCollection *collection_extension, GParamSpec *param, @@ -715,6 +727,11 @@ collection_backend_dispose (GObject *object) priv->notify_collection_handler_id = 0; } + if (priv->notify_online_handler_id) { + g_signal_handler_disconnect (object, priv->notify_online_handler_id); + priv->notify_online_handler_id = 0; + } + g_mutex_lock (&priv->children_lock); g_hash_table_remove_all (priv->children); g_mutex_unlock (&priv->children_lock); @@ -841,6 +858,9 @@ collection_backend_constructed (GObject *object) /* Populate the newly-added collection from an idle callback * so persistent child sources have a chance to be added first. */ collection_backend_schedule_populate_idle (backend); + + backend->priv->notify_online_handler_id = g_signal_connect (backend, "notify::online", + G_CALLBACK (collection_backend_online_cb), NULL); } static void diff --git a/modules/google-backend/module-google-backend.c b/modules/google-backend/module-google-backend.c index 9bfc57be9..e2857c8b3 100644 --- a/modules/google-backend/module-google-backend.c +++ b/modules/google-backend/module-google-backend.c @@ -736,6 +736,20 @@ google_backend_child_added (ECollectionBackend *backend, } } +static gboolean +google_backend_get_destination_address (EBackend *backend, + gchar **host, + guint16 *port) +{ + g_return_val_if_fail (host != NULL, FALSE); + g_return_val_if_fail (port != NULL, FALSE); + + *host = g_strdup ("www.google.com"); + *port = 443; + + return TRUE; +} + static void e_google_backend_class_init (EGoogleBackendClass *class) { @@ -744,6 +758,7 @@ e_google_backend_class_init (EGoogleBackendClass *class) backend_class = E_BACKEND_CLASS (class); backend_class->authenticate_sync = google_backend_authenticate_sync; + backend_class->get_destination_address = google_backend_get_destination_address; collection_backend_class = E_COLLECTION_BACKEND_CLASS (class); collection_backend_class->populate = google_backend_populate; -- cgit v1.2.1