OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/contacts/google_contact_store.h" | 5 #include "chrome/browser/chromeos/contacts/google_contact_store.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 : profile_(profile), | 78 : profile_(profile), |
79 contacts_deleter_(&contacts_), | 79 contacts_deleter_(&contacts_), |
80 db_(new ContactDatabase), | 80 db_(new ContactDatabase), |
81 update_delay_on_next_failure_( | 81 update_delay_on_next_failure_( |
82 base::TimeDelta::FromSeconds(kUpdateFailureInitialRetrySec)), | 82 base::TimeDelta::FromSeconds(kUpdateFailureInitialRetrySec)), |
83 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 83 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
85 } | 85 } |
86 | 86 |
87 GoogleContactStore::~GoogleContactStore() { | 87 GoogleContactStore::~GoogleContactStore() { |
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 88 // This should also be running on the UI thread but we can't check it; the |
89 // message loop is typically already getting torn down at this point. | |
Daniel Erat
2012/08/03 20:00:23
[9076:9076:952949823645:FATAL:google_contact_store
satorux1
2012/08/03 20:08:14
wow this is subtle...
On 2012/08/03 20:00:23, Dan
| |
89 weak_ptr_factory_.InvalidateWeakPtrs(); | 90 weak_ptr_factory_.InvalidateWeakPtrs(); |
90 DestroyDatabase(); | 91 DestroyDatabase(); |
91 } | 92 } |
92 | 93 |
93 void GoogleContactStore::Init() { | 94 void GoogleContactStore::Init() { |
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
95 FilePath db_path = profile_->GetPath().Append(kDatabaseDirectoryName); | 96 FilePath db_path = profile_->GetPath().Append(kDatabaseDirectoryName); |
96 VLOG(1) << "Initializing contact database \"" << db_path.value() << "\" for " | 97 VLOG(1) << "Initializing contact database \"" << db_path.value() << "\" for " |
97 << profile_->GetProfileName(); | 98 << profile_->GetProfileName(); |
98 db_->Init(db_path, | 99 db_->Init(db_path, |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 gdata::util::FormatTimeAsString(last_contact_update_time_)); | 255 gdata::util::FormatTimeAsString(last_contact_update_time_)); |
255 } | 256 } |
256 | 257 |
257 void GoogleContactStore::OnDownloadSuccess( | 258 void GoogleContactStore::OnDownloadSuccess( |
258 bool is_full_update, | 259 bool is_full_update, |
259 const base::Time& update_start_time, | 260 const base::Time& update_start_time, |
260 scoped_ptr<ScopedVector<Contact> > updated_contacts) { | 261 scoped_ptr<ScopedVector<Contact> > updated_contacts) { |
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
262 VLOG(1) << "Got " << updated_contacts->size() << " contact(s) for " | 263 VLOG(1) << "Got " << updated_contacts->size() << " contact(s) for " |
263 << profile_->GetProfileName(); | 264 << profile_->GetProfileName(); |
264 size_t num_updated_contacts = updated_contacts->size(); | 265 |
266 // Copy the pointers so we can update just these contacts in the database. | |
267 scoped_ptr<ContactPointers> contacts_to_save_to_db(new ContactPointers); | |
268 if (db_) { | |
269 for (size_t i = 0; i < updated_contacts->size(); ++i) | |
270 contacts_to_save_to_db->push_back((*updated_contacts)[i]); | |
271 } | |
272 bool got_updates = !updated_contacts->empty(); | |
273 | |
265 MergeContacts(is_full_update, updated_contacts.Pass()); | 274 MergeContacts(is_full_update, updated_contacts.Pass()); |
266 last_successful_update_start_time_ = update_start_time; | 275 last_successful_update_start_time_ = update_start_time; |
267 | 276 |
268 if (is_full_update || num_updated_contacts > 0) { | 277 if (is_full_update || got_updates > 0) { |
269 FOR_EACH_OBSERVER(ContactStoreObserver, | 278 FOR_EACH_OBSERVER(ContactStoreObserver, |
270 observers_, | 279 observers_, |
271 OnContactsUpdated(this)); | 280 OnContactsUpdated(this)); |
272 } | 281 } |
273 | 282 |
274 if (db_) { | 283 if (db_) { |
275 scoped_ptr<ContactPointers> contacts_to_save(new ContactPointers); | 284 VLOG(1) << "Saving " << contacts_to_save_to_db->size() << " contact(s) to " |
276 for (ContactMap::const_iterator it = contacts_.begin(); | 285 << "database as " << (is_full_update ? "full" : "partial") |
277 it != contacts_.end(); ++it) { | 286 << " update"; |
278 contacts_to_save->push_back(it->second); | |
279 } | |
280 scoped_ptr<UpdateMetadata> metadata(new UpdateMetadata); | 287 scoped_ptr<UpdateMetadata> metadata(new UpdateMetadata); |
281 metadata->set_last_update_start_time(update_start_time.ToInternalValue()); | 288 metadata->set_last_update_start_time(update_start_time.ToInternalValue()); |
282 | |
283 db_->SaveContacts( | 289 db_->SaveContacts( |
284 contacts_to_save.Pass(), | 290 contacts_to_save_to_db.Pass(), |
285 metadata.Pass(), | 291 metadata.Pass(), |
286 is_full_update, | 292 is_full_update, |
287 base::Bind(&GoogleContactStore::OnDatabaseContactsSaved, | 293 base::Bind(&GoogleContactStore::OnDatabaseContactsSaved, |
288 weak_ptr_factory_.GetWeakPtr())); | 294 weak_ptr_factory_.GetWeakPtr())); |
289 | 295 |
290 // We'll schedule an update from OnDatabaseContactsSaved() after we're done | 296 // We'll schedule an update from OnDatabaseContactsSaved() after we're done |
291 // writing to the database -- we don't want to modify the contacts while | 297 // writing to the database -- we don't want to modify the contacts while |
292 // they're being used by the database. | 298 // they're being used by the database. |
293 } else { | 299 } else { |
294 ScheduleUpdate(true); | 300 ScheduleUpdate(true); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 void GoogleContactStore::OnDatabaseContactsSaved(bool success) { | 349 void GoogleContactStore::OnDatabaseContactsSaved(bool success) { |
344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
345 if (!success) | 351 if (!success) |
346 LOG(WARNING) << "Failed to save contacts to database"; | 352 LOG(WARNING) << "Failed to save contacts to database"; |
347 | 353 |
348 // We only update the database when we've successfully downloaded contacts, so | 354 // We only update the database when we've successfully downloaded contacts, so |
349 // report success to ScheduleUpdate() even if the database update failed. | 355 // report success to ScheduleUpdate() even if the database update failed. |
350 ScheduleUpdate(true); | 356 ScheduleUpdate(true); |
351 } | 357 } |
352 | 358 |
359 GoogleContactStoreFactory::GoogleContactStoreFactory() { | |
360 } | |
361 | |
362 GoogleContactStoreFactory::~GoogleContactStoreFactory() { | |
363 } | |
364 | |
365 bool GoogleContactStoreFactory::CanCreateContactStoreForProfile( | |
366 Profile* profile) { | |
367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
368 DCHECK(profile); | |
369 return gdata::util::IsGDataAvailable(profile); | |
370 } | |
371 | |
372 ContactStore* GoogleContactStoreFactory::CreateContactStore(Profile* profile) { | |
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
374 DCHECK(CanCreateContactStoreForProfile(profile)); | |
375 return new GoogleContactStore(profile); | |
376 } | |
377 | |
353 } // namespace contacts | 378 } // namespace contacts |
OLD | NEW |