Commit da326fb6 authored by derat@chromium.org's avatar derat@chromium.org

contacts: Add GoogleContactStore.

This class uses GDataContactsService to download contacts
from Google and uses ContactDatabase to save them to disk.
It also contains logic for periodically refreshing contacts.

BUG=128805
TEST=none
TBR=ben@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10829144

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149805 0039d316-1c4b-4281-b951-d872f2087c98
parent 74bb5598
......@@ -29,7 +29,8 @@ const char kUpdateMetadataKey[] = "__chrome_update_metadata__";
} // namespace
ContactDatabase::ContactDatabase() : weak_ptr_factory_(this) {
ContactDatabase::ContactDatabase()
: ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken());
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_STORE_H_
#define CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_STORE_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
namespace contacts {
class Contact;
typedef std::vector<const Contact*> ContactPointers;
class ContactStoreObserver;
// Interface for classes that store contacts from a particular source.
class ContactStore {
public:
ContactStore() {}
virtual ~ContactStore() {}
// Appends all (non-deleted) contacts to |contacts_out|.
virtual void AppendContacts(ContactPointers* contacts_out) = 0;
// Returns the contact identified by |provider_id|.
// NULL is returned if the contact doesn't exist.
virtual const Contact* GetContactByProviderId(
const std::string& provider_id) = 0;
// Adds or removes an observer.
virtual void AddObserver(ContactStoreObserver* observer) = 0;
virtual void RemoveObserver(ContactStoreObserver* observer) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ContactStore);
};
} // namespace contacts
#endif // CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_STORE_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_STORE_OBSERVER_H_
#define CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_STORE_OBSERVER_H_
#include "base/basictypes.h"
namespace contacts {
class ContactStore;
// Interface for observing changes to a ContactStore.
class ContactStoreObserver {
public:
ContactStoreObserver() {}
virtual ~ContactStoreObserver() {}
// Called when the contacts stored within a ContactStore are updated.
virtual void OnContactsUpdated(ContactStore* store) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ContactStoreObserver);
};
} // namespace contacts
#endif // CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_STORE_OBSERVER_H_
......@@ -138,11 +138,8 @@ void CopyContacts(const ContactPointers& source,
ScopedVector<Contact>* dest) {
DCHECK(dest);
dest->clear();
for (size_t i = 0; i < source.size(); ++i) {
Contact* contact = new Contact;
*contact = *source[i];
dest->push_back(contact);
}
for (size_t i = 0; i < source.size(); ++i)
dest->push_back(new Contact(*source[i]));
}
void CopyContacts(const ScopedVector<Contact>& source,
......
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_CONTACTS_GOOGLE_CONTACT_STORE_H_
#define CHROME_BROWSER_CHROMEOS_CONTACTS_GOOGLE_CONTACT_STORE_H_
#include "chrome/browser/chromeos/contacts/contact_store.h"
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/stl_util.h"
#include "base/time.h"
#include "base/timer.h"
class Profile;
namespace gdata {
class GDataContactsServiceInterface;
}
namespace contacts {
class Contact;
class ContactDatabaseInterface;
class UpdateMetadata;
// A collection of contacts from a Google account.
class GoogleContactStore : public ContactStore {
public:
class TestAPI {
public:
explicit TestAPI(GoogleContactStore* store);
~TestAPI();
bool update_scheduled() { return store_->update_timer_.IsRunning(); }
void set_current_time(const base::Time& time) {
store_->current_time_for_testing_ = time;
}
// Takes ownership of |db|. Must be called before Init().
void SetDatabase(ContactDatabaseInterface* db);
// Takes ownership of |service|. Must be called before Init().
void SetGDataService(gdata::GDataContactsServiceInterface* service);
// Triggers an update, similar to what happens when the update timer fires.
void DoUpdate();
private:
GoogleContactStore* store_; // not owned
DISALLOW_COPY_AND_ASSIGN(TestAPI);
};
explicit GoogleContactStore(Profile* profile);
virtual ~GoogleContactStore();
void Init();
// ContactStore implementation:
virtual void AppendContacts(ContactPointers* contacts_out) OVERRIDE;
virtual const Contact* GetContactByProviderId(
const std::string& provider_id) OVERRIDE;
virtual void AddObserver(ContactStoreObserver* observer) OVERRIDE;
virtual void RemoveObserver(ContactStoreObserver* observer) OVERRIDE;
private:
// Map from a contact's Google-assigned ID to the contact itself.
typedef std::map<std::string, Contact*> ContactMap;
// Returns the current time. Uses |current_time_for_testing_| instead if it's
// set.
base::Time GetCurrentTime() const;
// Destroys |db_| if non-NULL and resets the pointer.
// The underlying data is preserved on-disk.
void DestroyDatabase();
// Asynchronously downloads updated contacts and merges them into |contacts_|.
void UpdateContacts();
// Starts |update_timer_| so UpdateContacts() will be run.
void ScheduleUpdate(bool last_update_was_successful);
// Moves |updated_contacts| into |contacts_| and updates
// |last_contact_update_time_|.
void MergeContacts(bool is_full_update,
scoped_ptr<ScopedVector<Contact> > updated_contacts);
// Handles a successful download, merging |updated_contacts| and saving the
// updated contacts to |db_|.
void OnDownloadSuccess(bool is_full_update,
const base::Time& update_start_time,
scoped_ptr<ScopedVector<Contact> > updated_contacts);
// Handles a failed update. A new update is scheduled.
void OnDownloadFailure();
// Handles |db_|'s initialization. On success, we start loading the contacts
// from the database; otherwise, we throw out the database and schedule an
// update.
void OnDatabaseInitialized(bool success);
// Handles contacts being loaded from |db_|. On success, we merge the loaded
// contacts. No matter what, we call UpdateContacts().
void OnDatabaseContactsLoaded(bool success,
scoped_ptr<ScopedVector<Contact> > contacts,
scoped_ptr<UpdateMetadata> metadata);
// Handles contacts being saved to |db_|. Now that the contacts are no longer
// being accessed by the database, we schedule an update.
void OnDatabaseContactsSaved(bool success);
Profile* profile_; // not owned
ObserverList<ContactStoreObserver> observers_;
// Owns the pointed-to Contact values.
ContactMap contacts_;
// Deletes values in |contacts_|.
STLValueDeleter<ContactMap> contacts_deleter_;
// Most-recent time that an entry in |contacts_| has been updated (as reported
// by Google).
base::Time last_contact_update_time_;
// Used to save contacts to disk and load them at startup. Owns the object.
ContactDatabaseInterface* db_;
// If non-NULL, used in place of the real GData service to download contacts.
scoped_ptr<gdata::GDataContactsServiceInterface> gdata_service_for_testing_;
// Used to schedule calls to UpdateContacts().
base::OneShotTimer<GoogleContactStore> update_timer_;
// Time at which the last successful update was started.
base::Time last_successful_update_start_time_;
// Amount of time that we'll wait before retrying the next time that an update
// fails.
base::TimeDelta update_delay_on_next_failure_;
// If non-null, used in place of base::Time::Now() when the current time is
// needed.
base::Time current_time_for_testing_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<GoogleContactStore> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(GoogleContactStore);
};
} // namespace contacts
#endif // CHROME_BROWSER_CHROMEOS_CONTACTS_GOOGLE_CONTACT_STORE_H_
......@@ -461,6 +461,10 @@
'browser/chromeos/chrome_browser_main_chromeos.h',
'browser/chromeos/contacts/contact_database.cc',
'browser/chromeos/contacts/contact_database.h',
'browser/chromeos/contacts/contact_store.h',
'browser/chromeos/contacts/contact_store_observer.h',
'browser/chromeos/contacts/google_contact_store.cc',
'browser/chromeos/contacts/google_contact_store.h',
'browser/chromeos/cros/burn_library.cc',
'browser/chromeos/cros/burn_library.h',
'browser/chromeos/cros/cellular_data_plan.cc',
......
......@@ -1086,6 +1086,7 @@
'browser/chromeos/contacts/contact_test_util.h',
'browser/chromeos/contacts/fake_contact_database.cc',
'browser/chromeos/contacts/fake_contact_database.h',
'browser/chromeos/contacts/google_contact_store_unittest.cc',
'browser/chromeos/cros/cros_network_functions_unittest.cc',
'browser/chromeos/cros/network_constants.h',
'browser/chromeos/cros/network_library.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment