Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(572)

Side by Side Diff: chrome/browser/chromeos/contacts/google_contact_store.cc

Issue 10933127: contacts: Don't save deleted contacts to disk. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } 74 }
75 75
76 void GoogleContactStore::TestAPI::NotifyAboutNetworkStateChange(bool online) { 76 void GoogleContactStore::TestAPI::NotifyAboutNetworkStateChange(bool online) {
77 net::NetworkChangeNotifier::ConnectionType type = 77 net::NetworkChangeNotifier::ConnectionType type =
78 online ? 78 online ?
79 net::NetworkChangeNotifier::CONNECTION_UNKNOWN : 79 net::NetworkChangeNotifier::CONNECTION_UNKNOWN :
80 net::NetworkChangeNotifier::CONNECTION_NONE; 80 net::NetworkChangeNotifier::CONNECTION_NONE;
81 store_->OnConnectionTypeChanged(type); 81 store_->OnConnectionTypeChanged(type);
82 } 82 }
83 83
84 scoped_ptr<ContactPointers> GoogleContactStore::TestAPI::GetLoadedContacts() {
85 scoped_ptr<ContactPointers> contacts(new ContactPointers);
86 for (ContactMap::const_iterator it = store_->contacts_.begin();
87 it != store_->contacts_.end(); ++it) {
88 contacts->push_back(it->second);
89 }
90 return contacts.Pass();
91 }
92
84 GoogleContactStore::GoogleContactStore(Profile* profile) 93 GoogleContactStore::GoogleContactStore(Profile* profile)
85 : profile_(profile), 94 : profile_(profile),
86 db_(new ContactDatabase), 95 db_(new ContactDatabase),
87 update_delay_on_next_failure_( 96 update_delay_on_next_failure_(
88 base::TimeDelta::FromSeconds(kUpdateFailureInitialRetrySec)), 97 base::TimeDelta::FromSeconds(kUpdateFailureInitialRetrySec)),
89 is_online_(true), 98 is_online_(true),
90 should_update_when_online_(false), 99 should_update_when_online_(false),
91 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 100 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 102 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
(...skipping 30 matching lines...) Expand all
124 for (ContactMap::const_iterator it = contacts_.begin(); 133 for (ContactMap::const_iterator it = contacts_.begin();
125 it != contacts_.end(); ++it) { 134 it != contacts_.end(); ++it) {
126 if (!it->second->deleted()) 135 if (!it->second->deleted())
127 contacts_out->push_back(it->second); 136 contacts_out->push_back(it->second);
128 } 137 }
129 } 138 }
130 139
131 const Contact* GoogleContactStore::GetContactById( 140 const Contact* GoogleContactStore::GetContactById(
132 const std::string& contact_id) { 141 const std::string& contact_id) {
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
134 const Contact* contact = contacts_.Find(contact_id); 143 return contacts_.Find(contact_id);
135 return (contact && !contact->deleted()) ? contact : NULL;
136 } 144 }
137 145
138 void GoogleContactStore::AddObserver(ContactStoreObserver* observer) { 146 void GoogleContactStore::AddObserver(ContactStoreObserver* observer) {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140 DCHECK(observer); 148 DCHECK(observer);
141 observers_.AddObserver(observer); 149 observers_.AddObserver(observer);
142 } 150 }
143 151
144 void GoogleContactStore::RemoveObserver(ContactStoreObserver* observer) { 152 void GoogleContactStore::RemoveObserver(ContactStoreObserver* observer) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 VLOG(1) << "Scheduling update of " << profile_->GetProfileName() 241 VLOG(1) << "Scheduling update of " << profile_->GetProfileName()
234 << " in " << delay.InSeconds() << " second(s)"; 242 << " in " << delay.InSeconds() << " second(s)";
235 update_timer_.Start( 243 update_timer_.Start(
236 FROM_HERE, delay, this, &GoogleContactStore::UpdateContacts); 244 FROM_HERE, delay, this, &GoogleContactStore::UpdateContacts);
237 } 245 }
238 246
239 void GoogleContactStore::MergeContacts( 247 void GoogleContactStore::MergeContacts(
240 bool is_full_update, 248 bool is_full_update,
241 scoped_ptr<ScopedVector<Contact> > updated_contacts) { 249 scoped_ptr<ScopedVector<Contact> > updated_contacts) {
242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
243 if (is_full_update) 251
252 if (is_full_update) {
244 contacts_.Clear(); 253 contacts_.Clear();
245 size_t num_updated_contacts = updated_contacts->size(); 254 last_contact_update_time_ = base::Time();
246 contacts_.Merge(updated_contacts.Pass(), ContactMap::KEEP_DELETED_CONTACTS); 255 }
247 256
248 if (is_full_update || num_updated_contacts > 0) 257 // Find the maximum update time from |updated_contacts| since contacts whose
249 last_contact_update_time_ = contacts_.GetMaxUpdateTime(); 258 // |deleted| flags are set won't be saved to |contacts_|.
259 for (ScopedVector<Contact>::iterator it = updated_contacts->begin();
260 it != updated_contacts->end(); ++it) {
261 last_contact_update_time_ =
262 std::max(last_contact_update_time_,
263 base::Time::FromInternalValue((*it)->update_time()));
264 }
250 VLOG(1) << "Last contact update time is " 265 VLOG(1) << "Last contact update time is "
251 << (last_contact_update_time_.is_null() ? 266 << (last_contact_update_time_.is_null() ?
252 std::string("null") : 267 std::string("null") :
253 gdata::util::FormatTimeAsString(last_contact_update_time_)); 268 gdata::util::FormatTimeAsString(last_contact_update_time_));
269
270 contacts_.Merge(updated_contacts.Pass(), ContactMap::DROP_DELETED_CONTACTS);
254 } 271 }
255 272
256 void GoogleContactStore::OnDownloadSuccess( 273 void GoogleContactStore::OnDownloadSuccess(
257 bool is_full_update, 274 bool is_full_update,
258 const base::Time& update_start_time, 275 const base::Time& update_start_time,
259 scoped_ptr<ScopedVector<Contact> > updated_contacts) { 276 scoped_ptr<ScopedVector<Contact> > updated_contacts) {
260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
261 VLOG(1) << "Got " << updated_contacts->size() << " contact(s) for " 278 VLOG(1) << "Got " << updated_contacts->size() << " contact(s) for "
262 << profile_->GetProfileName(); 279 << profile_->GetProfileName();
263 280
264 // Copy the pointers so we can update just these contacts in the database. 281 // Copy the pointers so we can update just these contacts in the database.
265 scoped_ptr<ContactPointers> contacts_to_save_to_db(new ContactPointers); 282 scoped_ptr<ContactPointers> contacts_to_save_to_db(new ContactPointers);
283 scoped_ptr<ContactDatabaseInterface::ContactIds>
284 contact_ids_to_delete_from_db(new ContactDatabaseInterface::ContactIds);
266 if (db_) { 285 if (db_) {
267 for (size_t i = 0; i < updated_contacts->size(); ++i) 286 for (size_t i = 0; i < updated_contacts->size(); ++i) {
268 contacts_to_save_to_db->push_back((*updated_contacts)[i]); 287 Contact* contact = (*updated_contacts)[i];
288 if (contact->deleted())
289 contact_ids_to_delete_from_db->push_back(contact->contact_id());
290 else
291 contacts_to_save_to_db->push_back(contact);
292 }
269 } 293 }
270 bool got_updates = !updated_contacts->empty(); 294 bool got_updates = !updated_contacts->empty();
271 295
272 MergeContacts(is_full_update, updated_contacts.Pass()); 296 MergeContacts(is_full_update, updated_contacts.Pass());
273 last_successful_update_start_time_ = update_start_time; 297 last_successful_update_start_time_ = update_start_time;
274 298
275 if (is_full_update || got_updates) { 299 if (is_full_update || got_updates) {
276 FOR_EACH_OBSERVER(ContactStoreObserver, 300 FOR_EACH_OBSERVER(ContactStoreObserver,
277 observers_, 301 observers_,
278 OnContactsUpdated(this)); 302 OnContactsUpdated(this));
279 } 303 }
280 304
281 if (db_) { 305 if (db_) {
282 // Even if this was an incremental update and we didn't get any updated 306 // Even if this was an incremental update and we didn't get any updated
283 // contacts, we still want to write updated metadata containing 307 // contacts, we still want to write updated metadata containing
284 // |update_start_time|. 308 // |update_start_time|.
285 VLOG(1) << "Saving " << contacts_to_save_to_db->size() << " contact(s) to " 309 VLOG(1) << "Saving " << contacts_to_save_to_db->size() << " contact(s) to "
286 << "database as " << (is_full_update ? "full" : "incremental") 310 << "database and deleting " << contact_ids_to_delete_from_db->size()
287 << " update"; 311 << " as " << (is_full_update ? "full" : "incremental") << " update";
312
288 scoped_ptr<UpdateMetadata> metadata(new UpdateMetadata); 313 scoped_ptr<UpdateMetadata> metadata(new UpdateMetadata);
289 metadata->set_last_update_start_time(update_start_time.ToInternalValue()); 314 metadata->set_last_update_start_time(update_start_time.ToInternalValue());
315 metadata->set_last_contact_update_time(
316 last_contact_update_time_.ToInternalValue());
317
290 db_->SaveContacts( 318 db_->SaveContacts(
291 contacts_to_save_to_db.Pass(), 319 contacts_to_save_to_db.Pass(),
320 contact_ids_to_delete_from_db.Pass(),
292 metadata.Pass(), 321 metadata.Pass(),
293 is_full_update, 322 is_full_update,
294 base::Bind(&GoogleContactStore::OnDatabaseContactsSaved, 323 base::Bind(&GoogleContactStore::OnDatabaseContactsSaved,
295 weak_ptr_factory_.GetWeakPtr())); 324 weak_ptr_factory_.GetWeakPtr()));
296 325
297 // We'll schedule an update from OnDatabaseContactsSaved() after we're done 326 // We'll schedule an update from OnDatabaseContactsSaved() after we're done
298 // writing to the database -- we don't want to modify the contacts while 327 // writing to the database -- we don't want to modify the contacts while
299 // they're being used by the database. 328 // they're being used by the database.
300 } else { 329 } else {
301 ScheduleUpdate(true); 330 ScheduleUpdate(true);
(...skipping 26 matching lines...) Expand all
328 void GoogleContactStore::OnDatabaseContactsLoaded( 357 void GoogleContactStore::OnDatabaseContactsLoaded(
329 bool success, 358 bool success,
330 scoped_ptr<ScopedVector<Contact> > contacts, 359 scoped_ptr<ScopedVector<Contact> > contacts,
331 scoped_ptr<UpdateMetadata> metadata) { 360 scoped_ptr<UpdateMetadata> metadata) {
332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
333 if (success) { 362 if (success) {
334 VLOG(1) << "Loaded " << contacts->size() << " contact(s) from database"; 363 VLOG(1) << "Loaded " << contacts->size() << " contact(s) from database";
335 MergeContacts(true, contacts.Pass()); 364 MergeContacts(true, contacts.Pass());
336 last_successful_update_start_time_ = 365 last_successful_update_start_time_ =
337 base::Time::FromInternalValue(metadata->last_update_start_time()); 366 base::Time::FromInternalValue(metadata->last_update_start_time());
367 last_contact_update_time_ = std::max(
368 last_contact_update_time_,
369 base::Time::FromInternalValue(metadata->last_contact_update_time()));
338 370
339 if (!contacts_.empty()) { 371 if (!contacts_.empty()) {
340 FOR_EACH_OBSERVER(ContactStoreObserver, 372 FOR_EACH_OBSERVER(ContactStoreObserver,
341 observers_, 373 observers_,
342 OnContactsUpdated(this)); 374 OnContactsUpdated(this));
343 } 375 }
344 } else { 376 } else {
345 LOG(WARNING) << "Failed to load contacts from database"; 377 LOG(WARNING) << "Failed to load contacts from database";
346 } 378 }
347 UpdateContacts(); 379 UpdateContacts();
(...skipping 22 matching lines...) Expand all
370 return gdata::util::IsGDataAvailable(profile); 402 return gdata::util::IsGDataAvailable(profile);
371 } 403 }
372 404
373 ContactStore* GoogleContactStoreFactory::CreateContactStore(Profile* profile) { 405 ContactStore* GoogleContactStoreFactory::CreateContactStore(Profile* profile) {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
375 DCHECK(CanCreateContactStoreForProfile(profile)); 407 DCHECK(CanCreateContactStoreForProfile(profile));
376 return new GoogleContactStore(profile); 408 return new GoogleContactStore(profile);
377 } 409 }
378 410
379 } // namespace contacts 411 } // namespace contacts
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698