~ubuntu-branches/ubuntu/saucy/evolution-data-server/saucy

« back to all changes in this revision

Viewing changes to addressbook/backends/google/e-book-backend-google.c

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-10-08 12:58:16 UTC
  • mfrom: (181.1.7 quantal)
  • Revision ID: package-import@ubuntu.com-20121008125816-i3n76e8c0m64e7xp
Tags: 3.6.0-0ubuntu2
* Fix LP: #1038047 part 1 - Don't abort in e_source_registry_new* when a
  problem occurs connecting to the Dbus service
  - add debian/patches/dont-abort-in-e_source_registry_new.patch
  - update debian/patches/series
* Fix LP: #1038047 part 2 - libedataserver depends on
  evolution-data-server-common to ensure that the GSettings schemas are
  present
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
                E_TYPE_SOURCE_AUTHENTICATOR,
59
59
                e_book_backend_google_source_authenticator_init))
60
60
 
61
 
typedef enum {
62
 
        NO_CACHE,
63
 
        ON_DISK_CACHE,
64
 
        IN_MEMORY_CACHE
65
 
} CacheType;
66
 
 
67
61
struct _EBookBackendGooglePrivate {
68
62
        GList *bookviews;
69
63
 
70
 
        CacheType cache_type;
71
 
        union {
72
 
                EBookBackendCache *on_disk;
73
 
                struct {
74
 
                        GHashTable *contacts;
75
 
                        GHashTable *gdata_entries;
76
 
                        GTimeVal last_updated;
77
 
                } in_memory;
78
 
        } cache;
 
64
        EBookBackendCache *cache;
79
65
 
80
66
        /* Mapping from group ID to (human readable) group name */
81
67
        GHashTable *groups_by_id;
91
77
        GDataAuthorizer *authorizer;
92
78
        GDataService *service;
93
79
        EProxy *proxy;
94
 
        guint refresh_interval;
95
 
 
96
 
        /* If views are open we will send out signals in an idle_handler */
97
 
        guint idle_id;
98
80
 
99
81
        guint refresh_id;
100
82
 
124
106
}
125
107
 
126
108
static void
127
 
cache_init (EBookBackend *backend,
128
 
            gboolean on_disk)
 
109
cache_init (EBookBackend *backend)
129
110
{
130
111
        EBookBackendGooglePrivate *priv;
131
112
        const gchar *cache_dir;
 
113
        gchar *filename;
132
114
 
133
115
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
134
116
 
135
117
        cache_dir = e_book_backend_get_cache_dir (backend);
136
 
 
137
 
        if (on_disk) {
138
 
                gchar *filename;
139
 
 
140
 
                filename = g_build_filename (cache_dir, "cache.xml", NULL);
141
 
                priv->cache_type = ON_DISK_CACHE;
142
 
                priv->cache.on_disk = e_book_backend_cache_new (filename);
143
 
                g_free (filename);
144
 
 
145
 
                migrate_cache (priv->cache.on_disk);
146
 
        } else {
147
 
                priv->cache_type = IN_MEMORY_CACHE;
148
 
                priv->cache.in_memory.contacts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
149
 
                priv->cache.in_memory.gdata_entries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
150
 
                memset (&priv->cache.in_memory.last_updated, 0, sizeof (GTimeVal));
151
 
        }
 
118
        filename = g_build_filename (cache_dir, "cache.xml", NULL);
 
119
        priv->cache = e_book_backend_cache_new (filename);
 
120
        g_free (filename);
 
121
 
 
122
        migrate_cache (priv->cache);
152
123
}
153
124
 
154
125
static EContact *
157
128
{
158
129
        EBookBackendGooglePrivate *priv;
159
130
        EContact *contact;
160
 
        const gchar *uid;
161
131
 
162
132
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
163
133
 
164
 
        switch (priv->cache_type) {
165
 
        case ON_DISK_CACHE:
166
 
                contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id, priv->system_groups_by_entry_id);
167
 
                e_contact_add_gdata_entry_xml (contact, entry);
168
 
                e_book_backend_cache_add_contact (priv->cache.on_disk, contact);
169
 
                e_contact_remove_gdata_entry_xml (contact);
170
 
                return contact;
171
 
        case IN_MEMORY_CACHE:
172
 
                contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id, priv->system_groups_by_entry_id);
173
 
                uid = e_contact_get_const (contact, E_CONTACT_UID);
174
 
                g_hash_table_insert (priv->cache.in_memory.contacts, g_strdup (uid), g_object_ref (contact));
175
 
                g_hash_table_insert (priv->cache.in_memory.gdata_entries, g_strdup (uid), g_object_ref (entry));
176
 
                return contact;
177
 
        case NO_CACHE:
178
 
        default:
179
 
                break;
180
 
        }
 
134
        contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id, priv->system_groups_by_entry_id);
 
135
        e_contact_add_gdata_entry_xml (contact, entry);
 
136
        e_book_backend_cache_add_contact (priv->cache, contact);
 
137
        e_contact_remove_gdata_entry_xml (contact);
181
138
 
182
 
        return NULL;
 
139
        return contact;
183
140
}
184
141
 
185
142
static gboolean
187
144
                      const gchar *uid)
188
145
{
189
146
        EBookBackendGooglePrivate *priv;
190
 
        gboolean success = TRUE;
191
147
 
192
148
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
193
149
 
194
 
        switch (priv->cache_type) {
195
 
        case ON_DISK_CACHE:
196
 
                return e_book_backend_cache_remove_contact (priv->cache.on_disk, uid);
197
 
        case IN_MEMORY_CACHE:
198
 
                success = g_hash_table_remove (priv->cache.in_memory.contacts, uid);
199
 
                return success && g_hash_table_remove (priv->cache.in_memory.gdata_entries, uid);
200
 
        case NO_CACHE:
201
 
        default:
202
 
                break;
203
 
        }
204
 
 
205
 
        return FALSE;
 
150
        return e_book_backend_cache_remove_contact (priv->cache, uid);
206
151
}
207
152
 
208
153
static gboolean
213
158
 
214
159
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
215
160
 
216
 
        switch (priv->cache_type) {
217
 
        case ON_DISK_CACHE:
218
 
                return e_book_backend_cache_check_contact (priv->cache.on_disk, uid);
219
 
        case IN_MEMORY_CACHE:
220
 
                return g_hash_table_lookup (priv->cache.in_memory.contacts, uid) ? TRUE : FALSE;
221
 
        case NO_CACHE:
222
 
        default:
223
 
                break;
224
 
        }
225
 
 
226
 
        return FALSE;
 
161
        return e_book_backend_cache_check_contact (priv->cache, uid);
227
162
}
228
163
 
229
164
static EContact *
236
171
 
237
172
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
238
173
 
239
 
        switch (priv->cache_type) {
240
 
        case ON_DISK_CACHE:
241
 
                contact = e_book_backend_cache_get_contact (priv->cache.on_disk, uid);
242
 
                if (contact) {
243
 
                        if (entry) {
244
 
                                const gchar *entry_xml, *edit_uri = NULL;
245
 
 
246
 
                                entry_xml = e_contact_get_gdata_entry_xml (contact, &edit_uri);
247
 
                                *entry = GDATA_ENTRY (gdata_parsable_new_from_xml (GDATA_TYPE_CONTACTS_CONTACT, entry_xml, -1, NULL));
248
 
 
249
 
                                if (*entry) {
250
 
                                        GDataLink *edit_link = gdata_link_new (edit_uri, GDATA_LINK_EDIT);
251
 
                                        gdata_entry_add_link (*entry, edit_link);
252
 
                                        g_object_unref (edit_link);
253
 
                                }
254
 
                        }
255
 
 
256
 
                        e_contact_remove_gdata_entry_xml (contact);
257
 
                }
258
 
                return contact;
259
 
        case IN_MEMORY_CACHE:
260
 
                contact = g_hash_table_lookup (priv->cache.in_memory.contacts, uid);
 
174
        contact = e_book_backend_cache_get_contact (priv->cache, uid);
 
175
        if (contact) {
261
176
                if (entry) {
262
 
                        *entry = g_hash_table_lookup (priv->cache.in_memory.gdata_entries, uid);
263
 
                        if (*entry)
264
 
                                g_object_ref (*entry);
 
177
                        const gchar *entry_xml, *edit_uri = NULL;
 
178
 
 
179
                        entry_xml = e_contact_get_gdata_entry_xml (contact, &edit_uri);
 
180
                        *entry = GDATA_ENTRY (gdata_parsable_new_from_xml (GDATA_TYPE_CONTACTS_CONTACT, entry_xml, -1, NULL));
 
181
 
 
182
                        if (*entry) {
 
183
                                GDataLink *edit_link = gdata_link_new (edit_uri, GDATA_LINK_EDIT);
 
184
                                gdata_entry_add_link (*entry, edit_link);
 
185
                                g_object_unref (edit_link);
 
186
                        }
265
187
                }
266
188
 
267
 
                if (contact)
268
 
                        g_object_ref (contact);
269
 
 
270
 
                return contact;
271
 
        case NO_CACHE:
272
 
        default:
273
 
                break;
 
189
                e_contact_remove_gdata_entry_xml (contact);
274
190
        }
275
191
 
276
 
        return NULL;
277
 
}
278
 
 
279
 
static GList *
280
 
_g_hash_table_to_list (GHashTable *ht)
281
 
{
282
 
        GList *l = NULL;
283
 
        GHashTableIter iter;
284
 
        gpointer key, value;
285
 
 
286
 
        g_hash_table_iter_init (&iter, ht);
287
 
        while (g_hash_table_iter_next (&iter, &key, &value))
288
 
                l = g_list_prepend (l, g_object_ref (G_OBJECT (value)));
289
 
 
290
 
        l = g_list_reverse (l);
291
 
 
292
 
        return l;
 
192
        return contact;
293
193
}
294
194
 
295
195
static GList *
300
200
 
301
201
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
302
202
 
303
 
        switch (priv->cache_type) {
304
 
        case ON_DISK_CACHE:
305
 
                contacts = e_book_backend_cache_get_contacts (priv->cache.on_disk, "(contains \"x-evolution-any-field\" \"\")");
306
 
                for (iter = contacts; iter; iter = iter->next)
307
 
                        e_contact_remove_gdata_entry_xml (iter->data);
308
 
 
309
 
                return contacts;
310
 
        case IN_MEMORY_CACHE:
311
 
                return _g_hash_table_to_list (priv->cache.in_memory.contacts);
312
 
        case NO_CACHE:
313
 
        default:
314
 
                break;
315
 
        }
316
 
 
317
 
        return NULL;
 
203
        contacts = e_book_backend_cache_get_contacts (priv->cache, "(contains \"x-evolution-any-field\" \"\")");
 
204
        for (iter = contacts; iter; iter = iter->next)
 
205
                e_contact_remove_gdata_entry_xml (iter->data);
 
206
 
 
207
        return contacts;
318
208
}
319
209
 
320
210
static void
324
214
 
325
215
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
326
216
 
327
 
        if (priv->cache_type == ON_DISK_CACHE)
328
 
                e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache.on_disk));
 
217
        e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
329
218
}
330
219
 
331
220
static void
335
224
 
336
225
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
337
226
 
338
 
        if (priv->cache_type == ON_DISK_CACHE)
339
 
                e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache.on_disk));
 
227
        e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache));
340
228
}
341
229
 
342
230
static gchar *
346
234
 
347
235
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
348
236
 
349
 
        switch (priv->cache_type) {
350
 
        case ON_DISK_CACHE:
351
 
                return e_book_backend_cache_get_time (priv->cache.on_disk);
352
 
        case IN_MEMORY_CACHE:
353
 
                if (priv->cache.in_memory.contacts)
354
 
                        return g_time_val_to_iso8601 (&priv->cache.in_memory.last_updated);
355
 
                break;
356
 
        case NO_CACHE:
357
 
        default:
358
 
                break;
359
 
        }
360
 
 
361
 
        return NULL;
362
 
}
363
 
 
364
 
static gboolean
365
 
cache_get_last_update_tv (EBookBackend *backend,
366
 
                          GTimeVal *tv)
367
 
{
368
 
        EBookBackendGooglePrivate *priv;
369
 
        gchar *last_update;
370
 
        gint rv;
371
 
 
372
 
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
373
 
 
374
 
        switch (priv->cache_type) {
375
 
        case ON_DISK_CACHE:
376
 
                last_update = e_book_backend_cache_get_time (priv->cache.on_disk);
377
 
                rv = last_update ? g_time_val_from_iso8601 (last_update, tv) : FALSE;
378
 
                g_free (last_update);
379
 
                return rv;
380
 
        case IN_MEMORY_CACHE:
381
 
                memcpy (tv, &priv->cache.in_memory.last_updated, sizeof (GTimeVal));
382
 
                return priv->cache.in_memory.contacts != NULL;
383
 
        case NO_CACHE:
384
 
        default:
385
 
                break;
386
 
        }
387
 
 
388
 
        return FALSE;
 
237
        return e_book_backend_cache_get_time (priv->cache);
389
238
}
390
239
 
391
240
static void
397
246
 
398
247
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
399
248
 
400
 
        switch (priv->cache_type) {
401
 
        case ON_DISK_CACHE:
402
 
                _time = g_time_val_to_iso8601 (tv);
403
 
                /* Work around a bug in EBookBackendCache */
404
 
                e_file_cache_remove_object (E_FILE_CACHE (priv->cache.on_disk), "last_update_time");
405
 
                e_book_backend_cache_set_time (priv->cache.on_disk, _time);
406
 
                g_free (_time);
407
 
                return;
408
 
        case IN_MEMORY_CACHE:
409
 
                memcpy (&priv->cache.in_memory.last_updated, tv, sizeof (GTimeVal));
410
 
        case NO_CACHE:
411
 
        default:
412
 
                break;
413
 
        }
414
 
}
415
 
 
416
 
static gboolean
417
 
cache_needs_update (EBookBackend *backend,
418
 
                    guint *remaining_secs)
419
 
{
420
 
        EBookBackendGooglePrivate *priv;
421
 
        GTimeVal last, current;
422
 
        guint diff;
423
 
        gboolean rv;
424
 
 
425
 
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
426
 
 
427
 
        if (remaining_secs)
428
 
                *remaining_secs = G_MAXUINT;
429
 
 
430
 
        /* We never want to update in offline mode */
431
 
        if (!e_backend_get_online (E_BACKEND (backend)))
432
 
                return FALSE;
433
 
 
434
 
        rv = cache_get_last_update_tv (backend, &last);
435
 
 
436
 
        if (!rv)
437
 
                return TRUE;
438
 
 
439
 
        g_get_current_time (&current);
440
 
        if (last.tv_sec > current.tv_sec) {
441
 
                g_warning ("last update is in the feature?");
442
 
 
443
 
                /* Do an update so we can fix this */
444
 
                return TRUE;
445
 
        }
446
 
        diff = current.tv_sec - last.tv_sec;
447
 
 
448
 
        if (diff >= priv->refresh_interval)
449
 
                return TRUE;
450
 
 
451
 
        if (remaining_secs)
452
 
                *remaining_secs = priv->refresh_interval - diff;
453
 
 
454
 
        __debug__ ("No update needed. Next update needed in %d secs", priv->refresh_interval - diff);
455
 
 
456
 
        return FALSE;
 
249
        _time = g_time_val_to_iso8601 (tv);
 
250
        e_book_backend_cache_set_time (priv->cache, _time);
 
251
        g_free (_time);
457
252
}
458
253
 
459
254
static gboolean
957
752
        }
958
753
 
959
754
        finish_operation (backend, -2, gdata_error);
 
755
        g_object_unref (backend);
960
756
 
961
757
        g_clear_error (&gdata_error);
962
758
}
980
776
                gdata_contacts_query_set_show_deleted (GDATA_CONTACTS_QUERY (query), TRUE);
981
777
        }
982
778
 
 
779
        g_object_ref (backend);
 
780
 
983
781
        /* Run the query asynchronously */
984
782
        cancellable = start_operation (backend, -2, NULL, _("Querying for updated groups…"));
985
783
        gdata_contacts_service_query_groups_async (
1080
878
        return create_group (E_BOOK_BACKEND (user_data), category_name, error);
1081
879
}
1082
880
 
1083
 
static gboolean cache_refresh_if_needed (EBookBackend *backend);
1084
 
 
1085
 
static gboolean
1086
 
on_refresh_timeout (EBookBackend *backend)
 
881
static void
 
882
refresh_local_cache_cb (ESource *source,
 
883
                        gpointer user_data)
1087
884
{
1088
 
        EBookBackendGooglePrivate *priv;
1089
 
 
1090
 
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
1091
 
 
1092
 
        __debug__ (G_STRFUNC);
1093
 
 
1094
 
        priv->refresh_id = 0;
1095
 
        if (priv->bookviews != NULL)
1096
 
                cache_refresh_if_needed (backend);
1097
 
 
1098
 
        return FALSE;
 
885
        EBookBackend *backend = user_data;
 
886
 
 
887
        __debug__ ("Invoking cache refresh");
 
888
 
 
889
        get_groups (backend);
 
890
        get_new_contacts (backend);
1099
891
}
1100
892
 
1101
 
static gboolean
 
893
static void
1102
894
cache_refresh_if_needed (EBookBackend *backend)
1103
895
{
1104
896
        EBookBackendGooglePrivate *priv;
1105
 
        guint remaining_secs;
1106
 
        gboolean install_timeout;
1107
897
        gboolean is_online;
1108
898
 
1109
899
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
1114
904
 
1115
905
        if (!is_online || !backend_is_authorized (backend)) {
1116
906
                __debug__ ("We are not connected to Google%s.", (!is_online) ? " (offline mode)" : "");
1117
 
                return TRUE;
1118
 
        }
1119
 
 
1120
 
        install_timeout = (priv->bookviews != NULL && priv->refresh_interval > 0 && 0 == priv->refresh_id);
1121
 
 
1122
 
        if (cache_needs_update (backend, &remaining_secs)) {
1123
 
                /* Update the cache asynchronously and schedule a new timeout */
1124
 
                get_groups (backend);
1125
 
                get_new_contacts (backend);
1126
 
                remaining_secs = priv->refresh_interval;
1127
 
        } else if (g_hash_table_size (priv->system_groups_by_id) == 0)
1128
 
                get_groups (backend);
1129
 
 
1130
 
        if (install_timeout) {
1131
 
                __debug__ ("Installing timeout with %d seconds", remaining_secs);
1132
 
                priv->refresh_id = g_timeout_add_seconds (remaining_secs, (GSourceFunc) on_refresh_timeout, backend);
1133
 
        }
1134
 
 
1135
 
        return TRUE;
1136
 
}
1137
 
 
1138
 
static void
1139
 
cache_destroy (EBookBackend *backend)
1140
 
{
1141
 
        EBookBackendGooglePrivate *priv;
1142
 
 
1143
 
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
1144
 
 
1145
 
        switch (priv->cache_type) {
1146
 
        case ON_DISK_CACHE:
1147
 
                g_object_unref (priv->cache.on_disk);
1148
 
                break;
1149
 
        case IN_MEMORY_CACHE:
1150
 
                g_hash_table_destroy (priv->cache.in_memory.contacts);
1151
 
                g_hash_table_destroy (priv->cache.in_memory.gdata_entries);
1152
 
                break;
1153
 
        case NO_CACHE:
1154
 
        default:
1155
 
                break;
1156
 
        }
1157
 
 
1158
 
        priv->cache_type = NO_CACHE;
 
907
                return;
 
908
        }
 
909
 
 
910
        if (!priv->refresh_id) {
 
911
                /* Update the cache asynchronously */
 
912
                refresh_local_cache_cb (NULL, backend);
 
913
 
 
914
                priv->refresh_id = e_source_refresh_add_timeout (
 
915
                        e_backend_get_source (E_BACKEND (backend)),
 
916
                        NULL,
 
917
                        refresh_local_cache_cb,
 
918
                        backend,
 
919
                        NULL);
 
920
        } else if (g_hash_table_size (priv->system_groups_by_id) == 0) {
 
921
                get_groups (backend);
 
922
        }
 
923
 
 
924
        return;
1159
925
}
1160
926
 
1161
927
static void
1182
948
                       GError **error)
1183
949
{
1184
950
        EBookBackendGooglePrivate *priv;
1185
 
        ESourceRegistry *registry;
1186
 
        ESource *source;
1187
951
 
1188
952
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
1189
 
        source = e_backend_get_source (E_BACKEND (backend));
1190
 
        registry = e_book_backend_get_registry (backend);
1191
953
 
1192
954
        /* Make sure we have the GDataService configured
1193
955
         * before requesting authorization. */
1234
996
#endif
1235
997
 
1236
998
        /* Otherwise it's up to us to obtain a login secret. */
1237
 
        return e_source_registry_authenticate_sync (
1238
 
                registry, source, E_SOURCE_AUTHENTICATOR (backend),
 
999
        return e_backend_authenticate_sync (
 
1000
                E_BACKEND (backend),
 
1001
                E_SOURCE_AUTHENTICATOR (backend),
1239
1002
                cancellable, error);
1240
1003
}
1241
1004
 
1436
1199
        if (vcards->next != NULL) {
1437
1200
                e_data_book_respond_create_contacts (book, opid,
1438
1201
                                                     EDB_ERROR_EX (NOT_SUPPORTED,
1439
 
                                                     _("The backend does not support bulk additions")),
 
1202
                                                     _("The backend does not support bulk additions")),
1440
1203
                                                     NULL);
1441
1204
                return;
1442
1205
        }
1557
1320
        if (id_list->next != NULL) {
1558
1321
                e_data_book_respond_remove_contacts (book, opid,
1559
1322
                                                     EDB_ERROR_EX (NOT_SUPPORTED,
1560
 
                                                     _("The backend does not support bulk removals")),
 
1323
                                                     _("The backend does not support bulk removals")),
1561
1324
                                                     NULL);
1562
1325
                return;
1563
1326
        }
1835
1598
        if (vcards->next != NULL) {
1836
1599
                e_data_book_respond_modify_contacts (book, opid,
1837
1600
                                                     EDB_ERROR_EX (NOT_SUPPORTED,
1838
 
                                                     _("The backend does not support bulk modifications")),
 
1601
                                                     _("The backend does not support bulk modifications")),
1839
1602
                                                     NULL);
1840
1603
                return;
1841
1604
        }
2025
1788
        g_slist_free (filtered_uids);
2026
1789
}
2027
1790
 
2028
 
static gboolean
2029
 
on_refresh_idle (EBookBackend *backend)
2030
 
{
2031
 
        EBookBackendGooglePrivate *priv;
2032
 
 
2033
 
        priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
2034
 
 
2035
 
        priv->idle_id = 0;
2036
 
        cache_refresh_if_needed (backend);
2037
 
 
2038
 
        return FALSE;
2039
 
}
2040
 
 
2041
1791
static void
2042
1792
e_book_backend_google_start_book_view (EBookBackend *backend,
2043
1793
                                       EDataBookView *bookview)
2061
1811
        /* Ensure that we're ready to support a view */
2062
1812
        cache_refresh_if_needed (backend);
2063
1813
 
2064
 
        /* Update the cache if necessary */
2065
 
        if (cache_needs_update (backend, NULL)) {
2066
 
                /* XXX We ought to be authorized by now, I would think.
2067
 
                 *     Not sure when we wouldn't be or how to handle it. */
2068
 
                if (!backend_is_authorized (backend)) {
2069
 
                        error = EDB_ERROR (AUTHENTICATION_REQUIRED);
2070
 
                        goto exit;
2071
 
                } else {
2072
 
                        /* Update in an idle function, so that this call doesn't block */
2073
 
                        priv->idle_id = g_idle_add ((GSourceFunc) on_refresh_idle, backend);
2074
 
                }
2075
 
        }
2076
 
 
2077
1814
        /* Get the contacts */
2078
1815
        cached_contacts = cache_get_contacts (backend);
2079
1816
        __debug__ ("%d contacts found in cache", g_list_length (cached_contacts));
2085
1822
                g_object_unref (contact);
2086
1823
        }
2087
1824
 
2088
 
exit:
2089
1825
        /* This function frees the GError passed to it. */
2090
1826
        e_data_book_view_notify_complete (bookview, error);
2091
1827
}
2106
1842
                priv->bookviews = g_list_delete_link (priv->bookviews, view);
2107
1843
                e_data_book_view_unref (bookview);
2108
1844
        }
2109
 
 
2110
 
        /* If there are no book views left, we can stop doing certain things, like refreshes */
2111
 
        if (!priv->bookviews && priv->refresh_id != 0) {
2112
 
                g_source_remove (priv->refresh_id);
2113
 
                priv->refresh_id = 0;
2114
 
        }
2115
 
}
2116
 
 
2117
 
static void
2118
 
e_book_backend_google_remove (EBookBackend *backend,
2119
 
                              EDataBook *book,
2120
 
                              guint32 opid,
2121
 
                              GCancellable *cancellable)
2122
 
{
2123
 
        __debug__ (G_STRFUNC);
2124
 
        e_data_book_respond_remove (book, opid, NULL);
2125
1845
}
2126
1846
 
2127
1847
static void
2132
1852
                            gboolean only_if_exists)
2133
1853
{
2134
1854
        EBookBackendGooglePrivate *priv;
2135
 
        ESourceOffline *offline_extension;
2136
 
        ESourceRefresh *refresh_extension;
2137
 
        ESource *source;
2138
 
        guint interval_in_minutes;
2139
 
        gboolean use_cache;
2140
 
        const gchar *extension_name;
2141
1855
        gboolean is_online;
2142
1856
        GError *error = NULL;
2143
1857
 
2150
1864
                return;
2151
1865
        }
2152
1866
 
2153
 
        source = e_backend_get_source (E_BACKEND (backend));
2154
 
 
2155
 
        extension_name = E_SOURCE_EXTENSION_OFFLINE;
2156
 
        offline_extension = e_source_get_extension (source, extension_name);
2157
 
 
2158
 
        extension_name = E_SOURCE_EXTENSION_REFRESH;
2159
 
        refresh_extension = e_source_get_extension (source, extension_name);
2160
 
 
2161
 
        interval_in_minutes =
2162
 
                e_source_refresh_get_enabled (refresh_extension) ?
2163
 
                e_source_refresh_get_interval_minutes (refresh_extension) : 0;
2164
 
 
2165
 
        use_cache = e_source_offline_get_stay_synchronized (offline_extension);
2166
 
 
2167
1867
        /* Set up our object */
2168
1868
        if (!priv->cancellables) {
2169
1869
                priv->groups_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2173
1873
                priv->cancellables = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
2174
1874
        }
2175
1875
 
2176
 
        cache_init (backend, use_cache);
2177
 
        priv->refresh_interval = interval_in_minutes * 60;
2178
 
 
2179
 
        /* Remove and re-add the timeout */
2180
 
        if (priv->refresh_id != 0 && priv->refresh_interval > 0) {
2181
 
                g_source_remove (priv->refresh_id);
2182
 
                priv->refresh_id = g_timeout_add_seconds (priv->refresh_interval, (GSourceFunc) on_refresh_timeout, backend);
2183
 
        }
 
1876
        cache_init (backend);
2184
1877
 
2185
1878
        /* Set up ready to be interacted with */
2186
1879
        is_online = e_backend_get_online (E_BACKEND (backend));
2196
1889
        }
2197
1890
 
2198
1891
        if (!is_online || backend_is_authorized (backend)) {
2199
 
                if (is_online)
 
1892
                if (is_online) {
2200
1893
                        e_book_backend_notify_readonly (backend, FALSE);
 
1894
                        cache_refresh_if_needed (backend);
 
1895
                }
 
1896
 
2201
1897
                e_book_backend_notify_opened (backend, NULL /* Success */);
2202
1898
        }
2203
1899
 
2439
2135
                priv->bookviews = g_list_delete_link (priv->bookviews, priv->bookviews);
2440
2136
        }
2441
2137
 
2442
 
        if (priv->idle_id) {
2443
 
                g_source_remove (priv->idle_id);
2444
 
                priv->idle_id = 0;
 
2138
        if (priv->refresh_id) {
 
2139
                e_source_refresh_remove_timeout (
 
2140
                        e_backend_get_source (E_BACKEND (object)),
 
2141
                        priv->refresh_id);
 
2142
                priv->refresh_id = 0;
2445
2143
        }
2446
2144
 
2447
2145
        if (priv->service)
2456
2154
                g_object_unref (priv->proxy);
2457
2155
        priv->proxy = NULL;
2458
2156
 
2459
 
        cache_destroy (E_BOOK_BACKEND (object));
 
2157
        g_clear_object (&priv->cache);
2460
2158
 
2461
2159
        G_OBJECT_CLASS (e_book_backend_google_parent_class)->dispose (object);
2462
2160
}
2551
2249
        backend_class->get_backend_property     = e_book_backend_google_get_backend_property;
2552
2250
        backend_class->start_book_view          = e_book_backend_google_start_book_view;
2553
2251
        backend_class->stop_book_view           = e_book_backend_google_stop_book_view;
2554
 
        backend_class->remove                   = e_book_backend_google_remove;
2555
2252
        backend_class->create_contacts          = e_book_backend_google_create_contacts;
2556
2253
        backend_class->remove_contacts          = e_book_backend_google_remove_contacts;
2557
2254
        backend_class->modify_contacts          = e_book_backend_google_modify_contacts;