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
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/contacts/contact_manager.h"
7 #include "base/logging.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/chromeos/contacts/contact.pb.h"
11 #include "chrome/browser/chromeos/contacts/contact_manager_observer.h"
12 #include "chrome/browser/chromeos/contacts/contact_store.h"
13 #include "chrome/browser/chromeos/contacts/google_contact_store.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/notification_service.h"
19 using content::BrowserThread;
25 // Singleton instance.
26 ContactManager* g_instance = NULL;
31 ContactManager* ContactManager::GetInstance() {
32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
37 ContactManager::ContactManager()
38 : profile_observers_deleter_(&profile_observers_),
39 contact_store_factory_(new GoogleContactStoreFactory),
40 contact_stores_deleter_(&contact_stores_),
41 weak_ptr_factory_(this) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47 ContactManager::~ContactManager() {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
49 DCHECK_EQ(g_instance, this);
50 weak_ptr_factory_.InvalidateWeakPtrs();
52 for (ContactStoreMap::const_iterator it = contact_stores_.begin();
53 it != contact_stores_.end(); ++it) {
54 it->second->RemoveObserver(this);
58 void ContactManager::SetContactStoreForTesting(
59 scoped_ptr<ContactStoreFactory> factory) {
60 DCHECK(contact_stores_.empty());
61 contact_store_factory_.swap(factory);
64 void ContactManager::Init() {
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
68 chrome::NOTIFICATION_PROFILE_CREATED,
69 content::NotificationService::AllSources());
72 chrome::NOTIFICATION_PROFILE_DESTROYED,
73 content::NotificationService::AllSources());
75 // Notify about any already-existing profiles.
76 std::vector<Profile*> profiles(
77 g_browser_process->profile_manager()->GetLoadedProfiles());
78 for (size_t i = 0; i < profiles.size(); ++i)
79 HandleProfileCreated(profiles[i]);
82 base::WeakPtr<ContactManagerInterface> ContactManager::GetWeakPtr() {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84 return weak_ptr_factory_.GetWeakPtr();
87 void ContactManager::AddObserver(ContactManagerObserver* observer,
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 Observers* observers = GetObserversForProfile(profile, true);
93 observers->AddObserver(observer);
96 void ContactManager::RemoveObserver(ContactManagerObserver* observer,
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101 Observers* observers = GetObserversForProfile(profile, false);
103 observers->RemoveObserver(observer);
106 scoped_ptr<ContactPointers> ContactManager::GetAllContacts(Profile* profile) {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 scoped_ptr<ContactPointers> contacts(new ContactPointers);
110 ContactStoreMap::const_iterator it = contact_stores_.find(profile);
111 if (it != contact_stores_.end())
112 it->second->AppendContacts(contacts.get());
113 return contacts.Pass();
116 const Contact* ContactManager::GetContactById(Profile* profile,
117 const std::string& contact_id) {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120 ContactStoreMap::const_iterator it = contact_stores_.find(profile);
121 return it != contact_stores_.end() ?
122 it->second->GetContactById(contact_id) :
126 void ContactManager::OnContactsUpdated(ContactStore* store) {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128 for (ContactStoreMap::const_iterator it = contact_stores_.begin();
129 it != contact_stores_.end(); ++it) {
130 if (it->second == store) {
131 Profile* profile = it->first;
132 Observers* observers = GetObserversForProfile(profile, false);
134 FOR_EACH_OBSERVER(ContactManagerObserver,
136 OnContactsUpdated(profile));
141 NOTREACHED() << "Got update from unknown contact store " << store;
144 void ContactManager::Observe(int type,
145 const content::NotificationSource& source,
146 const content::NotificationDetails& details) {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 case chrome::NOTIFICATION_PROFILE_CREATED:
150 HandleProfileCreated(content::Source<Profile>(source).ptr());
152 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
153 Profile* profile = content::Details<Profile>(details).ptr();
155 HandleProfileDestroyed(profile);
159 NOTREACHED() << "Unexpected notification " << type;
163 ContactManager::Observers* ContactManager::GetObserversForProfile(
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
167 ProfileObserversMap::const_iterator it = profile_observers_.find(profile);
168 if (it != profile_observers_.end())
173 Observers* observers = new Observers;
174 profile_observers_[profile] = observers;
178 void ContactManager::HandleProfileCreated(Profile* profile) {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182 ContactStoreMap::iterator it = contact_stores_.find(profile);
183 if (it != contact_stores_.end())
186 if (!contact_store_factory_->CanCreateContactStoreForProfile(profile))
189 VLOG(1) << "Adding profile " << profile->GetProfileName();
190 ContactStore* store = contact_store_factory_->CreateContactStore(profile);
192 store->AddObserver(this);
194 DCHECK_EQ(contact_stores_.count(profile), static_cast<size_t>(0));
195 contact_stores_[profile] = store;
198 void ContactManager::HandleProfileDestroyed(Profile* profile) {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
202 ContactStoreMap::iterator store_it = contact_stores_.find(profile);
203 if (store_it != contact_stores_.end()) {
204 store_it->second->RemoveObserver(this);
205 delete store_it->second;
206 contact_stores_.erase(store_it);
209 ProfileObserversMap::iterator observer_it = profile_observers_.find(profile);
210 if (observer_it != profile_observers_.end()) {
211 delete observer_it->second;
212 profile_observers_.erase(observer_it);
216 } // namespace contacts