[evolution-data-server] Replace libgdata dependency with built-in functions



commit 6b62b6e32f56663136242121b709c3606be49a26
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jul 7 18:10:35 2022 +0200

    Replace libgdata dependency with built-in functions
    
    Since the new Google Data Tasks API functions being added, the libgdata
    dependency can be dropped and replaced with it.

 CMakeLists.txt                                     |  35 --
 config.h.in                                        |   6 -
 .../evolution-data-server-docs.sgml.in             |   1 -
 src/calendar/backends/CMakeLists.txt               |   5 +-
 src/calendar/backends/gtasks/CMakeLists.txt        |   3 -
 .../backends/gtasks/e-cal-backend-gtasks.c         | 665 +++++++++------------
 src/libedataserver/CMakeLists.txt                  |   7 +-
 src/libedataserver/e-dataserver-autocleanups.h     |   1 -
 src/libedataserver/e-gdata-oauth2-authorizer.c     | 542 -----------------
 src/libedataserver/e-gdata-oauth2-authorizer.h     |  80 ---
 src/libedataserver/libedataserver.h                |   1 -
 src/modules/google-backend/CMakeLists.txt          |  18 +-
 src/modules/google-backend/module-google-backend.c |  72 +--
 src/vala/CMakeLists.txt                            |   1 -
 14 files changed, 315 insertions(+), 1122 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1ff529b4e..78266fb24 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,7 +118,6 @@ add_definitions(-DSOUP_VERSION_MIN_REQUIRED=${soup_encoded_version})
 
 set(gcr3_minimum_version 3.4)
 set(gcr4_minimum_version 3.90)
-set(libgdata_minimum_version 0.15.1)
 set(libical_glib_minimum_version 3.0.7)
 set(libsecret_minimum_version 0.5)
 set(libxml_minimum_version 2.0.0)
@@ -850,40 +849,6 @@ unset(defval)
 # ******************************
 pkg_check_modules(SQLITE3 REQUIRED sqlite3>=${sqlite_minimum_version})
 
-# ******************************
-# Google flags
-# ******************************
-
-add_printable_option(ENABLE_GOOGLE "Enable Google support" OFF)
-if(ENABLE_GOOGLE)
-       pkg_check_modules_for_option(ENABLE_GOOGLE "Google" LIBGDATA libgdata>=${libgdata_minimum_version})
-       set(HAVE_LIBGDATA ON)
-       set(LIBGDATA_GIR GData-1.0)
-       set(LIBGDATA_VAPI libgdata)
-
-       # compatibility check
-       pkg_check_variable(libgdata_soupapiversion libgdata soupapiversion)
-       if(NOT "${libgdata_soupapiversion}" STREQUAL "3.0")
-               message(FATAL_ERROR "Requires libgdata compiled with libsoup 3.0 API, but found version 
'${libgdata_soupapiversion}' instead. If you want to disable Google tasks support, please use 
-DENABLE_GOOGLE=OFF argument to cmake command.")
-       endif(NOT "${libgdata_soupapiversion}" STREQUAL "3.0")
-       unset(libgdata_soupapiversion)
-
-       set(CMAKE_REQUIRED_DEFINITIONS ${LIBGDATA_CFLAGS_OTHER})
-       set(CMAKE_REQUIRED_INCLUDES ${LIBGDATA_INCLUDE_DIRS})
-       set(CMAKE_REQUIRED_LIBRARIES ${LIBGDATA_LDFLAGS})
-
-       CHECK_C_SOURCE_COMPILES("#include <gdata/gdata.h>
-                               int main(void) {
-                                       gdata_feed_get_next_page_token (NULL);
-                                       gdata_query_next_page (NULL);
-                                       return 0;
-                               }" HAVE_LIBGDATA_TASKS_PAGINATION_FUNCTIONS)
-
-       unset(CMAKE_REQUIRED_DEFINITIONS)
-       unset(CMAKE_REQUIRED_INCLUDES)
-       unset(CMAKE_REQUIRED_LIBRARIES)
-endif(ENABLE_GOOGLE)
-
 # ******************************
 # Checks for large file support
 # ******************************
diff --git a/config.h.in b/config.h.in
index 17d51a6c5..fbb74c50c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -183,12 +183,6 @@
 /* Have <et/com_err.h> */
 #cmakedefine HAVE_ET_COM_ERR_H 1
 
-/* Define to 1 if you have the libgdata package */
-#cmakedefine HAVE_LIBGDATA 1
-
-/* Define to 1 when the libgdata provides GTasks pagination functions */
-#cmakedefine HAVE_LIBGDATA_TASKS_PAGINATION_FUNCTIONS 1
-
 /* Define to 1 when have O_LARGEFILE open flag */
 #cmakedefine HAVE_O_LARGEFILE 1
 
diff --git a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in 
b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
index 1e4121b36..9f551ab0a 100644
--- a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
+++ b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
@@ -243,7 +243,6 @@
       <xi:include href="xml/e-error.xml"/>
       <xi:include href="xml/e-flag.xml"/>
       <xi:include href="xml/e-free-form-exp.xml"/>
-      <xi:include href="xml/e-gdata-oauth2-authorizer.xml"/>
       <xi:include href="xml/e-gdata-query.xml"/>
       <xi:include href="xml/e-gdata-session.xml"/>
       <xi:include href="xml/e-json-utils.xml"/>
diff --git a/src/calendar/backends/CMakeLists.txt b/src/calendar/backends/CMakeLists.txt
index 0de3a6d18..68faf79fc 100644
--- a/src/calendar/backends/CMakeLists.txt
+++ b/src/calendar/backends/CMakeLists.txt
@@ -1,13 +1,10 @@
 add_subdirectory(caldav)
 add_subdirectory(contacts)
 add_subdirectory(file)
+add_subdirectory(gtasks)
 add_subdirectory(http)
 add_subdirectory(webdav-notes)
 
-if(HAVE_LIBGDATA)
-       add_subdirectory(gtasks)
-endif(HAVE_LIBGDATA)
-
 if(ENABLE_WEATHER)
        add_subdirectory(weather)
 endif(ENABLE_WEATHER)
diff --git a/src/calendar/backends/gtasks/CMakeLists.txt b/src/calendar/backends/gtasks/CMakeLists.txt
index 4664980b0..ef1749e0b 100644
--- a/src/calendar/backends/gtasks/CMakeLists.txt
+++ b/src/calendar/backends/gtasks/CMakeLists.txt
@@ -26,7 +26,6 @@ target_compile_definitions(ecalbackendgtasks PRIVATE
 
 target_compile_options(ecalbackendgtasks PUBLIC
        ${CALENDAR_CFLAGS}
-       ${LIBGDATA_CFLAGS}
 )
 
 target_include_directories(ecalbackendgtasks PUBLIC
@@ -36,13 +35,11 @@ target_include_directories(ecalbackendgtasks PUBLIC
        ${CMAKE_BINARY_DIR}/src/calendar
        ${CMAKE_SOURCE_DIR}/src/calendar
        ${CALENDAR_INCLUDE_DIRS}
-       ${LIBGDATA_INCLUDE_DIRS}
 )
 
 target_link_libraries(ecalbackendgtasks
        ${DEPENDENCIES}
        ${CALENDAR_LDFLAGS}
-       ${LIBGDATA_LDFLAGS}
 )
 
 install(TARGETS ecalbackendgtasks
diff --git a/src/calendar/backends/gtasks/e-cal-backend-gtasks.c 
b/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
index 553705ba4..971d825ca 100644
--- a/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
+++ b/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
@@ -18,9 +18,6 @@
 
 #include "evolution-data-server-config.h"
 
-#include <glib/gi18n-lib.h>
-#include <gdata/gdata.h>
-
 #include "libedataserver/libedataserver.h"
 
 #include "e-cal-backend-gtasks.h"
@@ -31,18 +28,16 @@
 #define ECC_ERROR_EX(_code, _msg) e_cal_client_error_create (_code, _msg)
 
 #define GTASKS_DEFAULT_TASKLIST_NAME "@default"
-#define X_EVO_GTASKS_SELF_LINK "X-EVOLUTION-GTASKS-SELF-LINK"
 #define X_EVO_GTASKS_POSITION  "X-EVOLUTION-GTASKS-POSITION"
 
 /* Current data version; when doesn't match with the stored,
    then fetches everything again. */
-#define GTASKS_DATA_VERSION    1
+#define GTASKS_DATA_VERSION    2
 #define GTASKS_DATA_VERSION_KEY        "gtasks-data-version"
 
 struct _ECalBackendGTasksPrivate {
-       GDataAuthorizer *authorizer;
-       GDataTasksService *service;
-       GDataTasksTasklist *tasklist;
+       EGDataSession *gdata;
+       gchar *tasklist_id;
        GRecMutex conn_lock;
        GHashTable *preloaded; /* gchar *uid ~> ECalComponent * */
        gboolean bad_request_for_timed_query;
@@ -53,19 +48,14 @@ G_DEFINE_TYPE_WITH_PRIVATE (ECalBackendGTasks, e_cal_backend_gtasks, E_TYPE_CAL_
 static gboolean
 ecb_gtasks_check_data_version (ECalCache *cal_cache)
 {
-#ifdef HAVE_LIBGDATA_TASKS_PAGINATION_FUNCTIONS
        g_return_val_if_fail (E_IS_CAL_CACHE (cal_cache), FALSE);
 
        return GTASKS_DATA_VERSION == e_cache_get_key_int (E_CACHE (cal_cache), GTASKS_DATA_VERSION_KEY, 
NULL);
-#else
-       return TRUE;
-#endif
 }
 
 static void
 ecb_gtasks_store_data_version (ECalCache *cal_cache)
 {
-#ifdef HAVE_LIBGDATA_TASKS_PAGINATION_FUNCTIONS
        GError *local_error = NULL;
 
        g_return_if_fail (E_IS_CAL_CACHE (cal_cache));
@@ -73,7 +63,6 @@ ecb_gtasks_store_data_version (ECalCache *cal_cache)
        if (!e_cache_set_key_int (E_CACHE (cal_cache), GTASKS_DATA_VERSION_KEY, GTASKS_DATA_VERSION, 
&local_error)) {
                g_warning ("%s: Failed to store data version: %s\n", G_STRFUNC, local_error ? 
local_error->message : "Unknown error");
        }
-#endif
 }
 
 static void
@@ -96,10 +85,8 @@ ecb_gtasks_update_ical_time_property (ICalComponent *icomp,
 }
 
 static ECalComponent *
-ecb_gtasks_gdata_to_comp (GDataTasksTask *task)
+ecb_gtasks_gdata_to_comp (JsonObject *task)
 {
-       GDataEntry *entry;
-       GDataLink *data_link;
        ECalComponent *comp;
        ICalComponent *icomp;
        ICalTime *tt;
@@ -108,20 +95,15 @@ ecb_gtasks_gdata_to_comp (GDataTasksTask *task)
        const gchar *parent;
        const gchar *text;
 
-       g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+       g_return_val_if_fail (task, NULL);
 
-       entry = GDATA_ENTRY (task);
        icomp = i_cal_component_new (I_CAL_VTODO_COMPONENT);
 
-       i_cal_component_set_uid (icomp, gdata_entry_get_id (entry));
+       i_cal_component_set_uid (icomp, e_gdata_task_get_id (task));
 
        utc_zone = i_cal_timezone_get_utc_timezone ();
 
-       tt = i_cal_time_new_from_timet_with_zone (gdata_entry_get_published (entry), 0, utc_zone);
-       if (!tt || !i_cal_time_is_valid_time (tt) || i_cal_time_is_null_time (tt)) {
-               g_clear_object (&tt);
-               tt = i_cal_time_new_from_timet_with_zone (gdata_entry_get_updated (entry), 0, utc_zone);
-       }
+       tt = i_cal_time_new_from_timet_with_zone (e_gdata_task_get_updated (task), 0, utc_zone);
        if (!tt || !i_cal_time_is_valid_time (tt) || i_cal_time_is_null_time (tt)) {
                g_clear_object (&tt);
                tt = i_cal_time_new_current_with_zone (utc_zone);
@@ -132,31 +114,24 @@ ecb_gtasks_gdata_to_comp (GDataTasksTask *task)
                i_cal_property_set_created,
                tt);
 
-       g_clear_object (&tt);
-
-       tt = i_cal_time_new_from_timet_with_zone (gdata_entry_get_updated (entry), 0, utc_zone);
-       if (!tt || !i_cal_time_is_valid_time (tt) || i_cal_time_is_null_time (tt)) {
-               g_clear_object (&tt);
-               tt = i_cal_time_new_current_with_zone (utc_zone);
-       }
-       i_cal_component_set_dtstamp (icomp, tt);
-
        ecb_gtasks_update_ical_time_property (icomp, I_CAL_LASTMODIFIED_PROPERTY,
                i_cal_property_new_lastmodified,
                i_cal_property_set_lastmodified,
                tt);
 
+       i_cal_component_set_dtstamp (icomp, tt);
+
        g_clear_object (&tt);
 
-       if (gdata_tasks_task_get_due (task) > 0) {
-               tt = i_cal_time_new_from_timet_with_zone (gdata_tasks_task_get_due (task), 1, NULL);
+       if (e_gdata_task_get_due (task) > 0) {
+               tt = i_cal_time_new_from_timet_with_zone (e_gdata_task_get_due (task), 1, NULL);
                if (tt && i_cal_time_is_valid_time (tt) && !i_cal_time_is_null_time (tt))
                        i_cal_component_set_due (icomp, tt);
                g_clear_object (&tt);
        }
 
-       if (gdata_tasks_task_get_completed (task) > 0) {
-               tt = i_cal_time_new_from_timet_with_zone (gdata_tasks_task_get_completed (task), 0, utc_zone);
+       if (e_gdata_task_get_completed (task) > 0) {
+               tt = i_cal_time_new_from_timet_with_zone (e_gdata_task_get_completed (task), 0, utc_zone);
                if (tt && i_cal_time_is_valid_time (tt) && !i_cal_time_is_null_time (tt)) {
                        ecb_gtasks_update_ical_time_property (icomp, I_CAL_COMPLETED_PROPERTY,
                                i_cal_property_new_completed,
@@ -166,30 +141,30 @@ ecb_gtasks_gdata_to_comp (GDataTasksTask *task)
                g_clear_object (&tt);
        }
 
-       text = gdata_entry_get_title (entry);
+       text = e_gdata_task_get_title (task);
        if (text && *text)
                i_cal_component_set_summary (icomp, text);
 
-       text = gdata_tasks_task_get_notes (task);
+       text = e_gdata_task_get_notes (task);
        if (text && *text)
                i_cal_component_set_description (icomp, text);
 
-       /* "needsAction" or "completed" */
-       text = gdata_tasks_task_get_status (task);
-       if (g_strcmp0 (text, "completed") == 0)
+       switch (e_gdata_task_get_status (task)) {
+       case E_GDATA_TASK_STATUS_COMPLETED:
                i_cal_component_set_status (icomp, I_CAL_STATUS_COMPLETED);
-       else if (g_strcmp0 (text, "needsAction") == 0)
+               break;
+       case E_GDATA_TASK_STATUS_NEEDS_ACTION:
                i_cal_component_set_status (icomp, I_CAL_STATUS_NEEDSACTION);
+               break;
+       default:
+               break;
+       }
 
-       data_link = gdata_entry_look_up_link (entry, GDATA_LINK_SELF);
-       if (data_link)
-               e_cal_util_component_set_x_property (icomp, X_EVO_GTASKS_SELF_LINK, gdata_link_get_uri 
(data_link));
-
-       position = gdata_tasks_task_get_position (task);
+       position = e_gdata_task_get_position (task);
        if (position)
                e_cal_util_component_set_x_property (icomp, X_EVO_GTASKS_POSITION, position);
 
-       parent = gdata_tasks_task_get_parent (task);
+       parent = e_gdata_task_get_parent (task);
        if (parent)
                i_cal_component_take_property (icomp, i_cal_property_new_relatedto (parent));
 
@@ -199,31 +174,35 @@ ecb_gtasks_gdata_to_comp (GDataTasksTask *task)
        return comp;
 }
 
-static GDataTasksTask *
+static JsonBuilder *
 ecb_gtasks_comp_to_gdata (ECalComponent *comp,
                          ECalComponent *cached_comp,
-                         gboolean ignore_uid)
+                         gboolean ignore_uid,
+                         gchar **out_parent,
+                         gchar **out_position)
 {
-       GDataEntry *entry;
-       GDataTasksTask *task;
+       JsonBuilder *task_builder;
        ICalComponent *icomp;
        ICalProperty *prop;
        ICalTime *tt;
        ICalTimezone *utc_zone;
        const gchar *text;
-       gchar *tmp;
-#if GDATA_CHECK_VERSION(0, 17, 10)
        gchar *position;
-#endif
+       gboolean has_status = FALSE;
 
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), NULL);
 
        icomp = e_cal_component_get_icalcomponent (comp);
        g_return_val_if_fail (icomp != NULL, NULL);
 
-       text = i_cal_component_get_uid (icomp);
-       task = gdata_tasks_task_new ((!ignore_uid && text && *text) ? text : NULL);
-       entry = GDATA_ENTRY (task);
+       task_builder = json_builder_new_immutable ();
+       e_json_begin_object_member (task_builder, NULL);
+
+       if (!ignore_uid) {
+               text = i_cal_component_get_uid (icomp);
+               if (text && *text)
+                       e_gdata_task_add_id (task_builder, text);
+       }
 
        utc_zone = i_cal_timezone_get_utc_timezone ();
 
@@ -232,7 +211,7 @@ ecb_gtasks_comp_to_gdata (ECalComponent *comp,
                gint64 due;
 
                due = (gint64) i_cal_time_as_timet_with_zone (tt, utc_zone);
-               gdata_tasks_task_set_due (task, due);
+               e_gdata_task_add_due (task_builder, due);
        }
        g_clear_object (&tt);
 
@@ -244,8 +223,9 @@ ecb_gtasks_comp_to_gdata (ECalComponent *comp,
                        gint64 completed;
 
                        completed = (gint64) i_cal_time_as_timet_with_zone (tt, utc_zone);
-                       gdata_tasks_task_set_completed (task, completed);
-                       gdata_tasks_task_set_status (task, "completed");
+                       e_gdata_task_add_completed (task_builder, completed);
+                       e_gdata_task_add_status (task_builder, E_GDATA_TASK_STATUS_COMPLETED);
+                       has_status = TRUE;
                }
                g_clear_object (&tt);
                g_object_unref (prop);
@@ -253,50 +233,26 @@ ecb_gtasks_comp_to_gdata (ECalComponent *comp,
 
        text = i_cal_component_get_summary (icomp);
        if (text && *text)
-               gdata_entry_set_title (entry, text);
+               e_gdata_task_add_title (task_builder, text);
 
        text = i_cal_component_get_description (icomp);
        if (text && *text)
-               gdata_tasks_task_set_notes (task, text);
-
-       /* "needsAction" or "completed" */
-       if (i_cal_component_get_status (icomp) == I_CAL_STATUS_COMPLETED)
-               gdata_tasks_task_set_status (task, "completed");
-       else if (i_cal_component_get_status (icomp) == I_CAL_STATUS_NEEDSACTION)
-               gdata_tasks_task_set_status (task, "needsAction");
+               e_gdata_task_add_notes (task_builder, text);
 
-       tmp = e_cal_util_component_dup_x_property (icomp, X_EVO_GTASKS_SELF_LINK);
-       if (!tmp || !*tmp) {
-               g_free (tmp);
-               tmp = NULL;
-
-               /* If the passed-in component doesn't contain the libgdata self link,
-                  then get it from the cached comp */
-               if (cached_comp) {
-                       tmp = e_cal_util_component_dup_x_property (
-                               e_cal_component_get_icalcomponent (cached_comp),
-                               X_EVO_GTASKS_SELF_LINK);
-               }
+       if (!has_status) {
+               if (i_cal_component_get_status (icomp) == I_CAL_STATUS_COMPLETED)
+                       e_gdata_task_add_status (task_builder, E_GDATA_TASK_STATUS_COMPLETED);
+               else if (i_cal_component_get_status (icomp) == I_CAL_STATUS_NEEDSACTION)
+                       e_gdata_task_add_status (task_builder, E_GDATA_TASK_STATUS_NEEDS_ACTION);
        }
 
-       if (tmp && *tmp) {
-               GDataLink *data_link;
-
-               data_link = gdata_link_new (tmp, GDATA_LINK_SELF);
-               gdata_entry_add_link (entry, data_link);
-               g_object_unref (data_link);
-       }
-
-       g_free (tmp);
-
-#if GDATA_CHECK_VERSION(0, 17, 10)
        /* Position */
        position = e_cal_util_component_dup_x_property (icomp, X_EVO_GTASKS_POSITION);
        if (!position || !*position) {
                g_free (position);
                position = NULL;
 
-               /* If the passed-in component doesn't contain the libgdata position,
+               /* If the passed-in component doesn't contain the GData position,
                   then get it from the cached comp */
                if (cached_comp) {
                        position = e_cal_util_component_dup_x_property (
@@ -306,7 +262,7 @@ ecb_gtasks_comp_to_gdata (ECalComponent *comp,
        }
 
        if (position && *position)
-               gdata_tasks_task_set_position (task, position);
+               *out_position = g_steal_pointer (&position);
 
        g_free (position);
 
@@ -319,67 +275,31 @@ ecb_gtasks_comp_to_gdata (ECalComponent *comp,
        }
 
        if (prop) {
-               gdata_tasks_task_set_parent (task, i_cal_property_get_relatedto (prop));
-               g_object_unref (prop);
-       }
-#endif
-
-       return task;
-}
+               const gchar *parent;
 
-static gboolean
-ecb_gtasks_is_authorized_locked (ECalBackendGTasks *cbgtasks)
-{
-       gboolean res;
+               parent = i_cal_property_get_relatedto (prop);
 
-       g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (cbgtasks), FALSE);
+               if (parent && *parent)
+                       *out_parent = g_strdup (parent);
 
-       if (!cbgtasks->priv->service ||
-           !cbgtasks->priv->tasklist)
-               return FALSE;
+               g_object_unref (prop);
+       }
 
-       res = gdata_service_is_authorized (GDATA_SERVICE (cbgtasks->priv->service));
+       e_json_end_object_member (task_builder);
 
-       return res;
+       return task_builder;
 }
 
 static gboolean
-ecb_gtasks_request_authorization_locked (ECalBackendGTasks *cbgtasks,
-                                        const ENamedParameters *credentials,
-                                        GCancellable *cancellable,
-                                        GError **error)
+ecb_gtasks_get_first_tasklist_cb (EGDataSession *gdata,
+                                 JsonObject *object,
+                                 gpointer user_data)
 {
-       /* Make sure we have the GDataService configured
-        * before requesting authorization. */
-
-       if (!cbgtasks->priv->authorizer) {
-               ESource *source;
-               EGDataOAuth2Authorizer *authorizer;
-
-               source = e_backend_get_source (E_BACKEND (cbgtasks));
-
-               /* Only OAuth2 is supported with Google Tasks */
-               authorizer = e_gdata_oauth2_authorizer_new (source, GDATA_TYPE_TASKS_SERVICE);
-               cbgtasks->priv->authorizer = GDATA_AUTHORIZER (authorizer);
-       }
-
-       if (E_IS_GDATA_OAUTH2_AUTHORIZER (cbgtasks->priv->authorizer)) {
-               e_gdata_oauth2_authorizer_set_credentials (E_GDATA_OAUTH2_AUTHORIZER 
(cbgtasks->priv->authorizer), credentials);
-       }
-
-       if (!cbgtasks->priv->service) {
-               GDataTasksService *tasks_service;
+       JsonObject **ptasklist = user_data;
 
-               tasks_service = gdata_tasks_service_new (cbgtasks->priv->authorizer);
-               cbgtasks->priv->service = tasks_service;
+       *ptasklist = json_object_ref (object);
 
-               e_binding_bind_property (
-                       cbgtasks, "proxy-resolver",
-                       cbgtasks->priv->service, "proxy-resolver",
-                       G_BINDING_SYNC_CREATE);
-       }
-
-       return TRUE;
+       return FALSE;
 }
 
 static gboolean
@@ -389,40 +309,32 @@ ecb_gtasks_prepare_tasklist_locked (ECalBackendGTasks *cbgtasks,
 {
        ESourceResource *resource;
        ESource *source;
-       GDataFeed *feed;
-       GDataQuery *query;
+       EGDataQuery *query;
+       JsonObject *tasklist = NULL;
        gchar *id;
        GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (cbgtasks), FALSE);
-       g_return_val_if_fail (cbgtasks->priv->service != NULL, FALSE);
-       g_return_val_if_fail (gdata_service_is_authorized (GDATA_SERVICE (cbgtasks->priv->service)), FALSE);
+       g_return_val_if_fail (cbgtasks->priv->gdata != NULL, FALSE);
 
        source = e_backend_get_source (E_BACKEND (cbgtasks));
        resource = e_source_get_extension (source, E_SOURCE_EXTENSION_RESOURCE);
        id = e_source_resource_dup_identity (resource);
 
-       query = gdata_query_new_with_limits (NULL, 0, 1);
+       query = e_gdata_query_new ();
+       e_gdata_query_set_max_results (query, 1);
 
        /* This also verifies that the service can connect to the server with given credentials */
-       feed = gdata_tasks_service_query_all_tasklists (cbgtasks->priv->service, query, cancellable, NULL, 
NULL, &local_error);
-       if (feed) {
+       if (e_gdata_session_tasklists_list_sync (cbgtasks->priv->gdata, query, 
ecb_gtasks_get_first_tasklist_cb, &tasklist, cancellable, &local_error)) {
                /* If the tasklist ID is not set, then pick the first from the list, most likely the "Default 
List" */
                if (!id || !*id) {
-                       GList *entries;
-
-                       entries = gdata_feed_get_entries (feed);
-                       if (entries) {
-                               GDataEntry *entry = entries->data;
-                               if (entry) {
-                                       g_free (id);
-                                       id = g_strdup (gdata_entry_get_id (entry));
-                               }
-                       }
+                       g_free (id);
+                       id = g_strdup (e_gdata_tasklist_get_id (tasklist));
                }
        }
-       g_clear_object (&feed);
-       g_object_unref (query);
+
+       g_clear_pointer (&tasklist, json_object_unref);
+       e_gdata_query_unref (query);
 
        if (!id || !*id) {
                /* But the tests for change will not work */
@@ -430,11 +342,11 @@ ecb_gtasks_prepare_tasklist_locked (ECalBackendGTasks *cbgtasks,
                id = g_strdup (GTASKS_DEFAULT_TASKLIST_NAME);
        }
 
-       g_clear_object (&cbgtasks->priv->tasklist);
+       g_clear_pointer (&cbgtasks->priv->tasklist_id, g_free);
        if (g_str_has_prefix (id, "gtasks::"))
-               cbgtasks->priv->tasklist = gdata_tasks_tasklist_new (id + 8);
+               cbgtasks->priv->tasklist_id = g_strdup (id + 8);
        else
-               cbgtasks->priv->tasklist = gdata_tasks_tasklist_new (id);
+               cbgtasks->priv->tasklist_id = g_steal_pointer (&id);
 
        g_free (id);
 
@@ -503,33 +415,64 @@ ecb_gtasks_connect_sync (ECalMetaBackend *meta_backend,
 
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       if (ecb_gtasks_is_authorized_locked (cbgtasks)) {
+       if (cbgtasks->priv->gdata &&
+           cbgtasks->priv->tasklist_id) {
                g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
                return TRUE;
        }
 
-       success = ecb_gtasks_request_authorization_locked (cbgtasks, credentials, cancellable, &local_error);
-       if (success)
-               success = gdata_authorizer_refresh_authorization (cbgtasks->priv->authorizer, cancellable, 
&local_error);
-       if (success)
-               success = ecb_gtasks_prepare_tasklist_locked (cbgtasks, cancellable, &local_error);
+       g_clear_object (&cbgtasks->priv->gdata);
+       g_clear_pointer (&cbgtasks->priv->tasklist_id, g_free);
 
-       g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
+       cbgtasks->priv->gdata = e_gdata_session_new (e_backend_get_source (E_BACKEND (cbgtasks)));
+
+       e_binding_bind_property (
+               cbgtasks, "proxy-resolver",
+               cbgtasks->priv->gdata, "proxy-resolver",
+               G_BINDING_SYNC_CREATE);
+
+       success = ecb_gtasks_prepare_tasklist_locked (cbgtasks, cancellable, &local_error);
 
        if (!success) {
-               if (g_error_matches (local_error, GDATA_SERVICE_ERROR, 
GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED)) {
-                       *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
-                       g_clear_error (&local_error);
+               gboolean credentials_empty;
+               gboolean is_tls_error;
+
+               credentials_empty = (!credentials || !e_named_parameters_count (credentials) ||
+                       (e_named_parameters_count (credentials) == 1 && e_named_parameters_exists 
(credentials, E_SOURCE_CREDENTIAL_SSL_TRUST))) &&
+                       e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION 
(cbgtasks->priv->gdata));
+               is_tls_error = g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+
+               *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
+
+               if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_FORBIDDEN) && 
credentials_empty) {
+                       *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
+               } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+                       if (credentials_empty)
+                               *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
+                       else
+                               *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
                } else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
-                          g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+                          (!e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION 
(cbgtasks->priv->gdata)) &&
+                          g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))) {
                        *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
+               } else if (!local_error) {
+                       g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error");
+               }
+
+               if (local_error) {
                        g_propagate_error (error, local_error);
-               } else {
-                       *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
-                       g_propagate_error (error, local_error);
+                       local_error = NULL;
+               }
+
+               if (is_tls_error) {
+                       *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
+
+                       e_soup_session_get_ssl_error_details (E_SOUP_SESSION (cbgtasks->priv->gdata), 
out_certificate_pem, out_certificate_errors);
                }
        }
 
+       g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
+
        return success;
 }
 
@@ -546,9 +489,8 @@ ecb_gtasks_disconnect_sync (ECalMetaBackend *meta_backend,
 
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       g_clear_object (&cbgtasks->priv->service);
-       g_clear_object (&cbgtasks->priv->authorizer);
-       g_clear_object (&cbgtasks->priv->tasklist);
+       g_clear_object (&cbgtasks->priv->gdata);
+       g_clear_pointer (&cbgtasks->priv->tasklist_id, g_free);
 
        g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
 
@@ -559,64 +501,105 @@ static gboolean
 ecb_gtasks_check_tasklist_changed_locked_sync (ECalBackendGTasks *cbgtasks,
                                               const gchar *last_sync_tag,
                                               gboolean *out_changed,
-                                              gint64 *out_taskslist_time,
+                                              gint64 *out_tasklist_time,
                                               GCancellable *cancellable,
                                               GError **error)
 {
-       GDataFeed *feed;
-       gchar *id = NULL;
-       gint64 taskslist_time = 0;
-       GError *local_error = NULL;
+       JsonObject *tasklist = NULL;
+       ECalCache *cal_cache;
+       gint64 tasklist_time;
 
        g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (cbgtasks), FALSE);
        g_return_val_if_fail (out_changed != NULL, FALSE);
-       g_return_val_if_fail (out_taskslist_time != NULL, FALSE);
+       g_return_val_if_fail (out_tasklist_time != NULL, FALSE);
 
        *out_changed = TRUE;
-       *out_taskslist_time = 0;
+       *out_tasklist_time = 0;
 
-       g_object_get (cbgtasks->priv->tasklist, "id", &id, NULL);
-       g_return_val_if_fail (id != NULL, FALSE);
+       if (!e_gdata_session_tasklists_get_sync (cbgtasks->priv->gdata, cbgtasks->priv->tasklist_id, 
&tasklist, cancellable, error))
+               return FALSE;
 
-       /* Check whether the tasklist changed */
-       feed = gdata_tasks_service_query_all_tasklists (cbgtasks->priv->service, NULL, cancellable, NULL, 
NULL, &local_error);
+       cal_cache = e_cal_meta_backend_ref_cache (E_CAL_META_BACKEND (cbgtasks));
+       tasklist_time = e_gdata_tasklist_get_updated (tasklist);
 
-       if (local_error) {
-               g_propagate_error (error, local_error);
-               return FALSE;
+       if (tasklist_time > 0 && last_sync_tag && ecb_gtasks_check_data_version (cal_cache)) {
+                       *out_changed = tasklist_time != e_json_util_decode_iso8601 (last_sync_tag, 0);
+                       *out_tasklist_time = tasklist_time;
        }
 
-       if (feed) {
-               GList *link;
+       g_clear_object (&cal_cache);
+       g_clear_pointer (&tasklist, json_object_unref);
+
+       return TRUE;
+}
+
+typedef struct _TasklistChangesData {
+       ECalCache *cal_cache;
+       GSList **out_created_objects; /* ECalMetaBackendInfo * */
+       GSList **out_modified_objects; /* ECalMetaBackendInfo * */
+       GSList **out_removed_objects; /* ECalMetaBackendInfo * */
+       GCancellable *cancellable;
+} TasklistChangesData;
+
+static gboolean
+ecb_gtasks_list_tasks_cb (EGDataSession *gdata,
+                         JsonObject *task,
+                         gpointer user_data)
+{
+       TasklistChangesData *tcd = user_data;
+       ECalComponent *cached_comp = NULL;
+       const gchar *uid;
+
+       uid = e_gdata_task_get_id (task);
 
-               for (link = gdata_feed_get_entries (feed); link; link = g_list_next (link)) {
-                       GDataEntry *entry = link->data;
+       if (!e_cal_cache_get_component (tcd->cal_cache, uid, NULL, &cached_comp, tcd->cancellable, NULL))
+               cached_comp = NULL;
 
-                       if (entry && g_strcmp0 (id, gdata_entry_get_id (entry)) == 0) {
-                               ECalCache *cal_cache;
+       if (e_gdata_task_get_deleted (task)) {
+               *tcd->out_removed_objects = g_slist_prepend (*tcd->out_removed_objects,
+                       e_cal_meta_backend_info_new (uid, NULL, NULL, NULL));
+       } else {
+               ECalComponent *new_comp;
 
-                               cal_cache = e_cal_meta_backend_ref_cache (E_CAL_META_BACKEND (cbgtasks));
-                               taskslist_time = gdata_entry_get_updated (entry);
+               new_comp = ecb_gtasks_gdata_to_comp (task);
+               if (new_comp) {
+                       gchar *revision, *object;
 
-                               if (taskslist_time > 0 && last_sync_tag && ecb_gtasks_check_data_version 
(cal_cache)) {
-                                       GTimeVal stored;
+                       revision = e_cal_cache_dup_component_revision (tcd->cal_cache, 
e_cal_component_get_icalcomponent (new_comp));
+                       object = e_cal_component_get_as_string (new_comp);
 
-                                       if (g_time_val_from_iso8601 (last_sync_tag, &stored))
-                                               *out_changed = taskslist_time != stored.tv_sec;
-                               }
+                       if (cached_comp) {
+                               ICalTime *cached_tt, *new_tt;
+
+                               cached_tt = e_cal_component_get_last_modified (cached_comp);
+                               new_tt = e_cal_component_get_last_modified (new_comp);
+
+                               if (!cached_tt || !new_tt ||
+                                   i_cal_time_compare (cached_tt, new_tt) != 0) {
+                                       /* Google doesn't store/provide 'created', thus use 'created,
+                                          as first seen by the backend' */
+                                       if (cached_tt)
+                                               e_cal_component_set_created (new_comp, cached_tt);
 
-                               g_clear_object (&cal_cache);
+                                       *tcd->out_modified_objects = g_slist_prepend 
(*tcd->out_modified_objects,
+                                               e_cal_meta_backend_info_new (uid, revision, object, NULL));
+                               }
 
-                               break;
+                               g_clear_object (&cached_tt);
+                               g_clear_object (&new_tt);
+                       } else {
+                               *tcd->out_created_objects = g_slist_prepend (*tcd->out_created_objects,
+                                       e_cal_meta_backend_info_new (uid, revision, object, NULL));
                        }
+
+                       g_free (revision);
+                       g_free (object);
                }
 
-               g_clear_object (&feed);
+               g_clear_object (&new_comp);
        }
 
-       g_free (id);
-
-       *out_taskslist_time = taskslist_time;
+       g_clear_object (&cached_comp);
 
        return TRUE;
 }
@@ -635,11 +618,11 @@ ecb_gtasks_get_changes_sync (ECalMetaBackend *meta_backend,
 {
        ECalBackendGTasks *cbgtasks;
        ECalCache *cal_cache;
-       gint64 taskslist_time = 0;
-       GTimeVal last_updated;
-       GDataFeed *feed;
-       GDataTasksQuery *tasks_query;
+       EGDataQuery *query;
+       TasklistChangesData tcd;
+       gint64 tasklist_time = 0, last_updated;
        gboolean changed = TRUE;
+       gboolean success;
        GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (meta_backend), FALSE);
@@ -656,7 +639,7 @@ ecb_gtasks_get_changes_sync (ECalMetaBackend *meta_backend,
 
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       if (!ecb_gtasks_check_tasklist_changed_locked_sync (cbgtasks, last_sync_tag, &changed, 
&taskslist_time, cancellable, error)) {
+       if (!ecb_gtasks_check_tasklist_changed_locked_sync (cbgtasks, last_sync_tag, &changed, 
&tasklist_time, cancellable, error)) {
                g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
                return FALSE;
        }
@@ -668,146 +651,65 @@ ecb_gtasks_get_changes_sync (ECalMetaBackend *meta_backend,
 
        cal_cache = e_cal_meta_backend_ref_cache (meta_backend);
 
-       if (!ecb_gtasks_check_data_version (cal_cache) ||
-           !last_sync_tag || cbgtasks->priv->bad_request_for_timed_query ||
-           !g_time_val_from_iso8601 (last_sync_tag, &last_updated)) {
-               last_updated.tv_sec = 0;
-       }
+       if (ecb_gtasks_check_data_version (cal_cache) &&
+           last_sync_tag && !cbgtasks->priv->bad_request_for_timed_query)
+               last_updated = e_json_util_decode_iso8601 (last_sync_tag, 0);
+       else
+               last_updated = 0;
 
-       tasks_query = gdata_tasks_query_new (NULL);
-       gdata_query_set_max_results (GDATA_QUERY (tasks_query), 100);
-       gdata_tasks_query_set_show_completed (tasks_query, TRUE);
-       gdata_tasks_query_set_show_hidden (tasks_query, TRUE);
+       query = e_gdata_query_new ();
+       e_gdata_query_set_max_results (query, 100);
+       e_gdata_query_set_show_completed (query, TRUE);
+       e_gdata_query_set_show_hidden (query, TRUE);
 
-       if (last_updated.tv_sec > 0) {
-               gdata_query_set_updated_min (GDATA_QUERY (tasks_query), last_updated.tv_sec);
-               gdata_tasks_query_set_show_deleted (tasks_query, TRUE);
+       if (last_updated > 0) {
+               e_gdata_query_set_updated_min (query, last_updated);
+               e_gdata_query_set_show_deleted (query, TRUE);
        }
 
-       feed = gdata_tasks_service_query_tasks (cbgtasks->priv->service, cbgtasks->priv->tasklist,
-               GDATA_QUERY (tasks_query), cancellable, NULL, NULL, &local_error);
+       tcd.cal_cache = cal_cache;
+       tcd.out_created_objects = out_created_objects;
+       tcd.out_modified_objects = out_modified_objects;
+       tcd.out_removed_objects = out_removed_objects;
+       tcd.cancellable = cancellable;
+
+       success = e_gdata_session_tasks_list_sync (cbgtasks->priv->gdata, cbgtasks->priv->tasklist_id, query,
+               ecb_gtasks_list_tasks_cb, &tcd, cancellable, &local_error);
 
-       if (last_updated.tv_sec > 0 && (
-           g_error_matches (local_error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_BAD_QUERY_PARAMETER) ||
-           g_error_matches (local_error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR))) {
+       if (last_updated > 0 && (
+           g_error_matches (local_error, G_URI_ERROR, G_URI_ERROR_BAD_QUERY) ||
+           g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_BAD_REQUEST))) {
                g_clear_error (&local_error);
 
                /* To not repeat with broken time format ad infinity;
-                  it changes only with updated libgdata, or change on the server. */
+                  it changes only with updated GData, or change on the server. */
                cbgtasks->priv->bad_request_for_timed_query = TRUE;
 
-               gdata_query_set_updated_min (GDATA_QUERY (tasks_query), -1);
-
-               feed = gdata_tasks_service_query_tasks (cbgtasks->priv->service, cbgtasks->priv->tasklist,
-                       GDATA_QUERY (tasks_query), cancellable, NULL, NULL, &local_error);
-       }
-
-#ifdef HAVE_LIBGDATA_TASKS_PAGINATION_FUNCTIONS
-       while (feed && !g_cancellable_is_cancelled (cancellable) && !local_error) {
-#else
-       if (feed) {
-#endif
-               GList *link;
-
-               for (link = gdata_feed_get_entries (feed); link && !g_cancellable_is_cancelled (cancellable); 
link = g_list_next (link)) {
-                       GDataTasksTask *task = link->data;
-                       ECalComponent *cached_comp = NULL;
-                       gchar *uid;
-
-                       if (!GDATA_IS_TASKS_TASK (task))
-                               continue;
-
-                       uid = g_strdup (gdata_entry_get_id (GDATA_ENTRY (task)));
-                       if (!uid || !*uid) {
-                               g_free (uid);
-                               continue;
-                       }
-
-                       if (!e_cal_cache_get_component (cal_cache, uid, NULL, &cached_comp, cancellable, 
NULL))
-                               cached_comp = NULL;
-
-                       if (gdata_tasks_task_is_deleted (task)) {
-                               *out_removed_objects = g_slist_prepend (*out_removed_objects,
-                                       e_cal_meta_backend_info_new (uid, NULL, NULL, NULL));
-                       } else {
-                               ECalComponent *new_comp;
-
-                               new_comp = ecb_gtasks_gdata_to_comp (task);
-                               if (new_comp) {
-                                       gchar *revision, *object;
-
-                                       revision = e_cal_cache_dup_component_revision (cal_cache, 
e_cal_component_get_icalcomponent (new_comp));
-                                       object = e_cal_component_get_as_string (new_comp);
-
-                                       if (cached_comp) {
-                                               ICalTime *cached_tt, *new_tt;
-
-                                               cached_tt = e_cal_component_get_last_modified (cached_comp);
-                                               new_tt = e_cal_component_get_last_modified (new_comp);
-
-                                               if (!cached_tt || !new_tt ||
-                                                   i_cal_time_compare (cached_tt, new_tt) != 0) {
-                                                       /* Google doesn't store/provide 'created', thus use 
'created,
-                                                          as first seen by the backend' */
-                                                       if (cached_tt)
-                                                               e_cal_component_set_created (new_comp, 
cached_tt);
-
-                                                       *out_modified_objects = g_slist_prepend 
(*out_modified_objects,
-                                                               e_cal_meta_backend_info_new (uid, revision, 
object, NULL));
-                                               }
-
-                                               g_clear_object (&cached_tt);
-                                               g_clear_object (&new_tt);
-                                       } else {
-                                               *out_created_objects = g_slist_prepend (*out_created_objects,
-                                                       e_cal_meta_backend_info_new (uid, revision, object, 
NULL));
-                                       }
-
-                                       g_free (revision);
-                                       g_free (object);
-                               }
-
-                               g_clear_object (&new_comp);
-                       }
-
-                       g_clear_object (&cached_comp);
-                       g_free (uid);
-               }
-
-#ifdef HAVE_LIBGDATA_TASKS_PAGINATION_FUNCTIONS
-               if (!gdata_feed_get_entries (feed))
-                       break;
-
-               gdata_query_next_page (GDATA_QUERY (tasks_query));
+               e_gdata_query_unref (query);
 
-               g_clear_object (&feed);
+               query = e_gdata_query_new ();
+               e_gdata_query_set_max_results (query, 100);
+               e_gdata_query_set_show_completed (query, TRUE);
+               e_gdata_query_set_show_hidden (query, TRUE);
 
-               feed = gdata_tasks_service_query_tasks (cbgtasks->priv->service, cbgtasks->priv->tasklist,
-                       GDATA_QUERY (tasks_query), cancellable, NULL, NULL, &local_error);
-#endif
+               success = e_gdata_session_tasks_list_sync (cbgtasks->priv->gdata, 
cbgtasks->priv->tasklist_id, query,
+                       ecb_gtasks_list_tasks_cb, &tcd, cancellable, &local_error);
        }
 
        g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
-       g_clear_object (&tasks_query);
-       g_clear_object (&feed);
+       g_clear_pointer (&query, e_gdata_query_unref);
 
        if (!g_cancellable_is_cancelled (cancellable) && !local_error) {
-               last_updated.tv_sec = taskslist_time;
-               last_updated.tv_usec = 0;
-
-               *out_new_sync_tag = g_time_val_to_iso8601 (&last_updated);
-
+               *out_new_sync_tag = e_json_util_encode_iso8601 (tasklist_time);
                ecb_gtasks_store_data_version (cal_cache);
        }
 
        g_clear_object (&cal_cache);
 
-       if (local_error) {
+       if (local_error)
                g_propagate_error (error, local_error);
-               return FALSE;
-       }
 
-       return TRUE;
+       return success;
 }
 
 static gboolean
@@ -867,9 +769,12 @@ ecb_gtasks_save_component_sync (ECalMetaBackend *meta_backend,
 {
        ECalBackendGTasks *cbgtasks;
        ECalCache *cal_cache;
-       GDataTasksTask *new_task, *comp_task;
+       JsonBuilder *comp_task;
+       JsonObject *new_task = NULL;
        ECalComponent *comp, *cached_comp = NULL;
+       gchar *parent = NULL, *position = NULL;
        const gchar *uid;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (meta_backend), FALSE);
        g_return_val_if_fail (out_new_uid != NULL, FALSE);
@@ -893,12 +798,14 @@ ecb_gtasks_save_component_sync (ECalMetaBackend *meta_backend,
                return FALSE;
        }
 
+       uid = e_cal_component_get_uid (comp);
+
        if (!overwrite_existing ||
-           !e_cal_cache_get_component (cal_cache, e_cal_component_get_uid (comp), NULL, &cached_comp, 
cancellable, NULL)) {
+           !e_cal_cache_get_component (cal_cache, uid, NULL, &cached_comp, cancellable, NULL)) {
                cached_comp = NULL;
        }
 
-       comp_task = ecb_gtasks_comp_to_gdata (comp, cached_comp, !overwrite_existing);
+       comp_task = ecb_gtasks_comp_to_gdata (comp, cached_comp, !overwrite_existing, &parent, &position);
 
        g_clear_object (&cached_comp);
        g_clear_object (&cal_cache);
@@ -910,20 +817,35 @@ ecb_gtasks_save_component_sync (ECalMetaBackend *meta_backend,
 
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       if (overwrite_existing)
-               new_task = gdata_tasks_service_update_task (cbgtasks->priv->service, comp_task, cancellable, 
error);
-       else
-               new_task = gdata_tasks_service_insert_task (cbgtasks->priv->service, comp_task, 
cbgtasks->priv->tasklist, cancellable, error);
+       if (overwrite_existing) {
+               success = e_gdata_session_tasks_update_sync (cbgtasks->priv->gdata, 
cbgtasks->priv->tasklist_id, uid,
+                       comp_task, &new_task, cancellable, error);
+
+               if (success && (
+                   (parent && g_strcmp0 (e_gdata_task_get_parent (new_task), parent) != 0) /*||
+                   (position && g_strcmp0 (e_gdata_task_get_position (new_task), position) != 0)*/)) {
+                       /* TODO: Position is an ordering string, not a task id */
+                       success = e_gdata_session_tasks_move_sync (cbgtasks->priv->gdata, 
cbgtasks->priv->tasklist_id,
+                               e_gdata_task_get_id (new_task), parent, NULL /*position*/, cancellable, 
error);
+               }
+       } else {
+               success = e_gdata_session_tasks_insert_sync (cbgtasks->priv->gdata, 
cbgtasks->priv->tasklist_id, comp_task,
+                       parent, position, &new_task, cancellable, error);
+       }
 
        g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
 
+       g_free (parent);
+       g_free (position);
        g_object_unref (comp_task);
 
-       if (!new_task)
+       if (!new_task || !success) {
+               g_clear_pointer (&new_task, json_object_unref);
                return FALSE;
+       }
 
        comp = ecb_gtasks_gdata_to_comp (new_task);
-       g_object_unref (new_task);
+       g_clear_pointer (&new_task, json_object_unref);
 
        if (!comp) {
                g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT));
@@ -959,51 +881,21 @@ ecb_gtasks_remove_component_sync (ECalMetaBackend *meta_backend,
                                  GError **error)
 {
        ECalBackendGTasks *cbgtasks;
-       GDataTasksTask *task;
-       ECalComponent *cached_comp = NULL;
-       GError *local_error = NULL;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (meta_backend), FALSE);
        g_return_val_if_fail (uid != NULL, FALSE);
        g_return_val_if_fail (object != NULL, FALSE);
 
-       cached_comp = e_cal_component_new_from_string (object);
-       if (!cached_comp) {
-               g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT));
-               return FALSE;
-       }
-
        cbgtasks = E_CAL_BACKEND_GTASKS (meta_backend);
 
-       task = ecb_gtasks_comp_to_gdata (cached_comp, NULL, FALSE);
-       if (!task) {
-               g_object_unref (cached_comp);
-               g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT));
-
-               return FALSE;
-       }
-
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       /* Ignore protocol errors here, libgdata 0.15.1 results with "Error code 204 when deleting an entry: 
No Content",
-          while the delete succeeded */
-       if (!gdata_tasks_service_delete_task (cbgtasks->priv->service, task, cancellable, &local_error) &&
-           !g_error_matches (local_error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR)) {
-               g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
-               g_object_unref (cached_comp);
-               g_object_unref (task);
-               g_propagate_error (error, local_error);
-
-               return FALSE;
-       } else {
-               g_clear_error (&local_error);
-       }
+       success = e_gdata_session_tasks_delete_sync (cbgtasks->priv->gdata, cbgtasks->priv->tasklist_id, uid, 
cancellable, error);
 
        g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
-       g_object_unref (cached_comp);
-       g_object_unref (task);
 
-       return TRUE;
+       return success;
 }
 
 static gboolean
@@ -1021,7 +913,7 @@ ecb_gtasks_requires_reconnect (ECalMetaBackend *meta_backend)
 
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       if (!cbgtasks->priv->tasklist) {
+       if (!cbgtasks->priv->gdata) {
                g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
                return TRUE;
        }
@@ -1030,8 +922,8 @@ ecb_gtasks_requires_reconnect (ECalMetaBackend *meta_backend)
        resource = e_source_get_extension (source, E_SOURCE_EXTENSION_RESOURCE);
        id = e_source_resource_dup_identity (resource);
 
-       changed = id && *id && g_strcmp0 (id, gdata_entry_get_id (GDATA_ENTRY (cbgtasks->priv->tasklist))) != 
0 &&
-               g_strcmp0 (GTASKS_DEFAULT_TASKLIST_NAME, gdata_entry_get_id (GDATA_ENTRY 
(cbgtasks->priv->tasklist))) != 0;
+       changed = id && *id && g_strcmp0 (id, cbgtasks->priv->tasklist_id) != 0 &&
+               g_strcmp0 (GTASKS_DEFAULT_TASKLIST_NAME, cbgtasks->priv->tasklist_id) != 0;
 
        g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
        g_free (id);
@@ -1099,9 +991,8 @@ ecb_gtasks_dispose (GObject *object)
 
        g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
 
-       g_clear_object (&cbgtasks->priv->service);
-       g_clear_object (&cbgtasks->priv->authorizer);
-       g_clear_object (&cbgtasks->priv->tasklist);
+       g_clear_object (&cbgtasks->priv->gdata);
+       g_clear_pointer (&cbgtasks->priv->tasklist_id, g_free);
 
        g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
 
diff --git a/src/libedataserver/CMakeLists.txt b/src/libedataserver/CMakeLists.txt
index 88759ec0b..2dfc1bde4 100644
--- a/src/libedataserver/CMakeLists.txt
+++ b/src/libedataserver/CMakeLists.txt
@@ -57,7 +57,6 @@ set(SOURCES
        e-extension.c
        e-flag.c
        e-free-form-exp.c
-       e-gdata-oauth2-authorizer.c
        e-gdata-query.c
        e-gdata-session.c
        e-iterator.c
@@ -151,7 +150,6 @@ set(HEADERS
        e-extension.h
        e-flag.h
        e-free-form-exp.h
-       e-gdata-oauth2-authorizer.h
        e-gdata-query.h
        e-gdata-session.h
        e-iterator.h
@@ -263,7 +261,6 @@ target_compile_options(edataserver PUBLIC
        ${GIO_UNIX_CFLAGS}
        ${ICU_CFLAGS}
        ${JSON_GLIB_CFLAGS}
-       ${LIBGDATA_CFLAGS}
 )
 
 target_include_directories(edataserver PUBLIC
@@ -278,7 +275,6 @@ target_include_directories(edataserver PUBLIC
        ${GIO_UNIX_INCLUDE_DIRS}
        ${ICU_INCLUDE_DIRS}
        ${JSON_GLIB_INCLUDE_DIRS}
-       ${LIBGDATA_INCLUDE_DIRS}
 )
 
 target_link_libraries(edataserver
@@ -287,7 +283,6 @@ target_link_libraries(edataserver
        ${GIO_UNIX_LDFLAGS}
        ${ICU_LDFLAGS}
        ${JSON_GLIB_LDFLAGS}
-       ${LIBGDATA_LDFLAGS}
 )
 
 install(TARGETS edataserver
@@ -300,7 +295,7 @@ install(FILES ${HEADERS}
 
 set(gir_sources ${SOURCES} ${HEADERS})
 set(gir_identifies_prefixes E)
-set(gir_includes GObject-2.0 Gio-2.0 Soup-3.0 libxml2-2.0 ${LIBGDATA_GIR})
+set(gir_includes GObject-2.0 Gio-2.0 Soup-3.0 libxml2-2.0)
 set(gir_cflags
        -DLIBEDATASERVER_COMPILATION
 )
diff --git a/src/libedataserver/e-dataserver-autocleanups.h b/src/libedataserver/e-dataserver-autocleanups.h
index 4339656fe..f43298422 100644
--- a/src/libedataserver/e-dataserver-autocleanups.h
+++ b/src/libedataserver/e-dataserver-autocleanups.h
@@ -32,7 +32,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(ENamedParameters, e_named_parameters_free)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(EExtensible, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(EExtension, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(EFlag, e_flag_free)
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(EGDataOAuth2Authorizer, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(EGDataQuery, e_gdata_query_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(EGDataSession, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(EMemChunk, e_memchunk_destroy)
diff --git a/src/libedataserver/libedataserver.h b/src/libedataserver/libedataserver.h
index 2051d38a5..f526ee338 100644
--- a/src/libedataserver/libedataserver.h
+++ b/src/libedataserver/libedataserver.h
@@ -31,7 +31,6 @@
 #include <libedataserver/e-extension.h>
 #include <libedataserver/e-flag.h>
 #include <libedataserver/e-free-form-exp.h>
-#include <libedataserver/e-gdata-oauth2-authorizer.h>
 #include <libedataserver/e-gdata-query.h>
 #include <libedataserver/e-gdata-session.h>
 #include <libedataserver/e-iterator.h>
diff --git a/src/modules/google-backend/CMakeLists.txt b/src/modules/google-backend/CMakeLists.txt
index 7f6250528..857222ce0 100644
--- a/src/modules/google-backend/CMakeLists.txt
+++ b/src/modules/google-backend/CMakeLists.txt
@@ -1,17 +1,11 @@
 set(extra_deps)
-if(HAVE_LIBGDATA)
-       set(sources
-               module-google-backend.c
-       )
-else(HAVE_LIBGDATA)
-       set(sources
-               module-google-backend.c
-       )
-endif(HAVE_LIBGDATA)
+set(sources
+       module-google-backend.c
+)
 set(extra_defines)
-set(extra_cflags ${LIBGDATA_CFLAGS})
-set(extra_incdirs ${LIBGDATA_INCLUDE_DIRS})
-set(extra_ldflags ${LIBGDATA_LDFLAGS})
+set(extra_cflags)
+set(extra_incdirs)
+set(extra_ldflags)
 
 add_source_registry_module(module-google-backend
        sources
diff --git a/src/modules/google-backend/module-google-backend.c 
b/src/modules/google-backend/module-google-backend.c
index 01fc05b9b..d82f0f311 100644
--- a/src/modules/google-backend/module-google-backend.c
+++ b/src/modules/google-backend/module-google-backend.c
@@ -22,10 +22,6 @@
 #include <libebackend/libebackend.h>
 #include <libedataserver/libedataserver.h>
 
-#ifdef HAVE_LIBGDATA
-#include <gdata/gdata.h>
-#endif
-
 /* Standard GObject macros */
 #define E_TYPE_GOOGLE_BACKEND \
        (e_google_backend_get_type ())
@@ -386,7 +382,6 @@ google_remove_unknown_sources_cb (gpointer resource_id,
        }
 }
 
-#ifdef HAVE_LIBGDATA
 static void
 google_add_task_list (ECollectionBackend *collection,
                      const gchar *resource_id,
@@ -464,7 +459,26 @@ google_add_task_list (ECollectionBackend *collection,
        g_object_unref (server);
        g_free (identity);
 }
-#endif /* HAVE_LIBGDATA */
+
+typedef struct _TaskListsData {
+       ECollectionBackend *collection;
+       GHashTable *known_sources;
+} TaskListsData;
+
+static gboolean
+google_backend_list_task_lists_cb (EGDataSession *gdata,
+                                  JsonObject *tasklist,
+                                  gpointer user_data)
+{
+       TaskListsData *tld = user_data;
+
+       google_add_task_list (tld->collection,
+               e_gdata_tasklist_get_id (tasklist),
+               e_gdata_tasklist_get_title (tasklist),
+               tld->known_sources);
+
+       return TRUE;
+}
 
 static ESourceAuthenticationResult
 google_backend_authenticate_sync (EBackend *backend,
@@ -547,57 +561,29 @@ google_backend_authenticate_sync (EBackend *backend,
                result = E_SOURCE_AUTHENTICATION_ACCEPTED;
        }
 
-#ifdef HAVE_LIBGDATA
        if (result == E_SOURCE_AUTHENTICATION_ACCEPTED &&
            e_source_collection_get_calendar_enabled (collection_extension) &&
            (goa_extension || e_oauth2_services_is_supported ())) {
-               EGDataOAuth2Authorizer *authorizer;
-               GDataTasksService *tasks_service;
+               EGDataSession *gdata;
+               TaskListsData tld;
                GError *local_error = NULL;
 
-               authorizer = e_gdata_oauth2_authorizer_new (e_backend_get_source (backend), 
GDATA_TYPE_TASKS_SERVICE);
-               e_gdata_oauth2_authorizer_set_credentials (authorizer, credentials);
-
-               tasks_service = gdata_tasks_service_new (GDATA_AUTHORIZER (authorizer));
+               gdata = e_gdata_session_new (e_backend_get_source (backend));
 
                e_binding_bind_property (
                        backend, "proxy-resolver",
-                       tasks_service, "proxy-resolver",
+                       gdata, "proxy-resolver",
                        G_BINDING_SYNC_CREATE);
 
-               if (gdata_authorizer_refresh_authorization (GDATA_AUTHORIZER (authorizer), cancellable, 
&local_error)) {
-                       GDataQuery *query;
-                       GDataFeed *feed;
-
-                       query = gdata_query_new (NULL);
-                       feed = gdata_tasks_service_query_all_tasklists (tasks_service, query, cancellable, 
NULL, NULL, &local_error);
-                       if (feed) {
-                               GList *link;
-
-                               for (link = gdata_feed_get_entries (feed); link; link = g_list_next (link)) {
-                                       GDataEntry *entry = link->data;
-
-                                       if (entry) {
-                                               google_add_task_list (collection,
-                                                       gdata_entry_get_id (entry),
-                                                       gdata_entry_get_title (entry),
-                                                       known_sources);
-                                       }
-                               }
-                       }
-
-                       g_clear_object (&feed);
-                       g_object_unref (query);
-               }
+               tld.collection = collection;
+               tld.known_sources = known_sources;
 
-               if (local_error)
-                       g_debug ("%s: Failed to get tasks list: %s", G_STRFUNC, local_error->message);
+               if (!e_gdata_session_tasklists_list_sync (gdata, NULL, google_backend_list_task_lists_cb, 
&tld, cancellable, &local_error))
+                       e_source_registry_debug_print ("%s: Failed to get tasks list: %s\n", G_STRFUNC, 
local_error ? local_error->message : "Unknown error");
 
-               g_clear_object (&tasks_service);
-               g_clear_object (&authorizer);
+               g_clear_object (&gdata);
                g_clear_error (&local_error);
        }
-#endif /* HAVE_LIBGDATA */
 
        if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
                ESourceRegistryServer *server;
diff --git a/src/vala/CMakeLists.txt b/src/vala/CMakeLists.txt
index 38170aa04..2f88c3925 100644
--- a/src/vala/CMakeLists.txt
+++ b/src/vala/CMakeLists.txt
@@ -108,7 +108,6 @@ set(vala_deps
        libsoup-3.0
        libxml-2.0
        posix
-       ${LIBGDATA_VAPI}
 )
 
 set(extra_vapigen_files)


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