OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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. | |
4 | |
5 #include "chrome/browser/invalidation/ticl_invalidation_service.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "chrome/browser/invalidation/invalidation_service_util.h" | |
9 #include "chrome/browser/profiles/profile.h" | |
10 #include "chrome/browser/signin/signin_manager.h" | |
11 #include "chrome/browser/signin/token_service.h" | |
12 #include "chrome/common/chrome_notification_types.h" | |
13 #include "content/public/browser/notification_service.h" | |
14 #include "google_apis/gaia/gaia_constants.h" | |
15 #include "sync/notifier/invalidator.h" | |
16 #include "sync/notifier/invalidator_state.h" | |
17 #include "sync/notifier/non_blocking_invalidator.h" | |
18 | |
19 namespace invalidation { | |
20 | |
21 TiclInvalidationService::TiclInvalidationService(SigninManagerBase* signin, | |
22 TokenService* token_service, | |
23 Profile* profile) | |
24 : profile_(profile), | |
25 signin_manager_(signin), | |
26 token_service_(token_service), | |
27 invalidator_registrar_(new syncer::InvalidatorRegistrar()) { } | |
28 | |
29 TiclInvalidationService::~TiclInvalidationService() { | |
30 DCHECK(CalledOnValidThread()); | |
31 } | |
32 | |
33 void TiclInvalidationService::Init() { | |
34 DCHECK(CalledOnValidThread()); | |
35 | |
36 invalidator_storage_.reset(new InvalidatorStorage(profile_->GetPrefs())); | |
37 if (invalidator_storage_->GetInvalidatorClientId().empty()) { | |
38 // This also clears any existing state. We can't reuse old invalidator | |
39 // state with the new ID anyway. | |
40 invalidator_storage_->SetInvalidatorClientId(GenerateInvalidatorClientId()); | |
41 } | |
42 | |
43 if (IsReadyToStart()) { | |
44 Start(); | |
45 } | |
46 | |
47 notification_registrar_.Add(this, | |
48 chrome::NOTIFICATION_TOKEN_AVAILABLE, | |
49 content::Source<TokenService>(token_service_)); | |
50 notification_registrar_.Add(this, | |
51 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, | |
Joao da Silva
2013/05/15 13:02:00
Question: if there are multiple profiles and one o
rlarocque
2013/05/15 20:29:39
You're right, the registration should apply to not
| |
52 content::NotificationService::AllSources()); | |
53 } | |
54 | |
55 void TiclInvalidationService::InitForTest(syncer::Invalidator* invalidator) { | |
56 // Here we perform the equivalent of Init() and Start(), but with some minor | |
57 // changes to account for the fact that we're injecting the invalidator. | |
58 invalidator_.reset(invalidator); | |
59 | |
60 invalidator_->RegisterHandler(this); | |
61 invalidator_->UpdateRegisteredIds( | |
62 this, | |
63 invalidator_registrar_->GetAllRegisteredIds()); | |
64 } | |
65 | |
66 void TiclInvalidationService::RegisterInvalidationHandler( | |
67 syncer::InvalidationHandler* handler) { | |
68 DCHECK(CalledOnValidThread()); | |
69 DVLOG(2) << "Registering an invalidation handler"; | |
70 invalidator_registrar_->RegisterHandler(handler); | |
71 } | |
72 | |
73 void TiclInvalidationService::UpdateRegisteredInvalidationIds( | |
74 syncer::InvalidationHandler* handler, | |
75 const syncer::ObjectIdSet& ids) { | |
76 DCHECK(CalledOnValidThread()); | |
77 DVLOG(2) << "Registering ids: " << ids.size(); | |
78 invalidator_registrar_->UpdateRegisteredIds(handler, ids); | |
79 if (invalidator_) { | |
80 invalidator_->UpdateRegisteredIds( | |
81 this, | |
82 invalidator_registrar_->GetAllRegisteredIds()); | |
83 } | |
84 } | |
85 | |
86 void TiclInvalidationService::UnregisterInvalidationHandler( | |
87 syncer::InvalidationHandler* handler) { | |
88 DCHECK(CalledOnValidThread()); | |
89 DVLOG(2) << "Unregistering"; | |
90 invalidator_registrar_->UnregisterHandler(handler); | |
91 if (invalidator_) { | |
92 invalidator_->UpdateRegisteredIds( | |
93 this, | |
94 invalidator_registrar_->GetAllRegisteredIds()); | |
95 } | |
96 } | |
97 | |
98 void TiclInvalidationService::AcknowledgeInvalidation( | |
99 const invalidation::ObjectId& id, | |
100 const syncer::AckHandle& ack_handle) { | |
101 DCHECK(CalledOnValidThread()); | |
102 if (invalidator_) { | |
103 invalidator_->Acknowledge(id, ack_handle); | |
104 } | |
105 } | |
106 | |
107 syncer::InvalidatorState TiclInvalidationService::GetInvalidatorState() const { | |
108 DCHECK(CalledOnValidThread()); | |
109 if (invalidator_) { | |
110 DVLOG(2) << "GetInvalidatorState returning " << GetInvalidatorState(); | |
111 return invalidator_->GetInvalidatorState(); | |
112 } else { | |
113 DVLOG(2) << "Invalidator currently stopped"; | |
114 return syncer::TRANSIENT_INVALIDATION_ERROR; | |
115 } | |
116 } | |
117 | |
118 std::string TiclInvalidationService::GetInvalidatorClientId() const { | |
119 DCHECK(CalledOnValidThread()); | |
120 // invalidator_storage_ will be initialized between calls to Init() and | |
121 // Stop(). No one should attempt to get the ID of an uninitialized or stopped | |
122 // service. | |
123 return invalidator_storage_->GetInvalidatorClientId(); | |
124 } | |
125 | |
126 void TiclInvalidationService::Observe( | |
127 int type, | |
128 const content::NotificationSource& source, | |
129 const content::NotificationDetails& details) { | |
130 DCHECK(CalledOnValidThread()); | |
131 | |
132 switch (type) { | |
133 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { | |
134 const TokenService::TokenAvailableDetails& token_details = | |
135 *(content::Details<const TokenService::TokenAvailableDetails>( | |
136 details).ptr()); | |
137 if (token_details.service() == GaiaConstants::kSyncService) { | |
138 DCHECK(IsReadyToStart()); | |
139 if (!IsStarted()) { | |
140 Start(); | |
141 } else { | |
142 UpdateToken(); | |
143 } | |
144 } | |
145 break; | |
146 } | |
147 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: { | |
148 Stop(); | |
149 break; | |
150 } | |
151 default: { | |
152 NOTREACHED(); | |
153 } | |
154 } | |
155 } | |
156 | |
157 void TiclInvalidationService::OnInvalidatorStateChange( | |
158 syncer::InvalidatorState state) { | |
159 invalidator_registrar_->UpdateInvalidatorState(state); | |
160 } | |
161 | |
162 void TiclInvalidationService::OnIncomingInvalidation( | |
163 const syncer::ObjectIdInvalidationMap& invalidation_map) { | |
164 invalidator_registrar_->DispatchInvalidationsToHandlers(invalidation_map); | |
165 } | |
166 | |
167 void TiclInvalidationService::Shutdown() { | |
168 DCHECK(CalledOnValidThread()); | |
169 Stop(); | |
170 invalidator_registrar_.reset(); | |
171 } | |
172 | |
173 bool TiclInvalidationService::IsReadyToStart() { | |
174 if (signin_manager_->GetAuthenticatedUsername().empty()) { | |
175 DVLOG(2) << "Not starting TiclInvalidationService: user is not signed in."; | |
176 return false; | |
177 } | |
178 | |
179 if (!token_service_) { | |
180 DVLOG(2) | |
181 << "Not starting TiclInvalidationService: TokenService unavailable."; | |
182 return false; | |
183 } | |
184 | |
185 if (!token_service_->HasTokenForService(GaiaConstants::kSyncService)) { | |
186 DVLOG(2) << "Not starting TiclInvalidationService: Sync token unavailable."; | |
187 return false; | |
188 } | |
189 | |
190 return true; | |
191 } | |
192 | |
193 bool TiclInvalidationService::IsStarted() { | |
194 return invalidator_.get() != NULL; | |
195 } | |
196 | |
197 void TiclInvalidationService::Start() { | |
198 DCHECK(CalledOnValidThread()); | |
199 DCHECK(!invalidator_); | |
200 | |
201 notifier::NotifierOptions options = | |
202 ParseNotifierOptions(*CommandLine::ForCurrentProcess()); | |
203 options.request_context_getter = profile_->GetRequestContext(); | |
204 invalidator_.reset(new syncer::NonBlockingInvalidator( | |
205 options, | |
206 invalidator_storage_->GetInvalidatorClientId(), | |
207 invalidator_storage_->GetAllInvalidationStates(), | |
208 invalidator_storage_->GetBootstrapData(), | |
209 syncer::WeakHandle<syncer::InvalidationStateTracker>( | |
210 invalidator_storage_->AsWeakPtr()), | |
211 content::GetUserAgent(GURL()))); | |
212 | |
213 UpdateToken(); | |
214 | |
215 invalidator_->RegisterHandler(this); | |
216 invalidator_->UpdateRegisteredIds( | |
217 this, | |
218 invalidator_registrar_->GetAllRegisteredIds()); | |
219 } | |
220 | |
221 void TiclInvalidationService::UpdateToken() { | |
222 std::string email = signin_manager_->GetAuthenticatedUsername(); | |
223 DCHECK(!email.empty()) << "Expected user to be signed in."; | |
224 DCHECK(token_service_->HasTokenForService(GaiaConstants::kSyncService)); | |
225 | |
226 std::string sync_token = token_service_->GetTokenForService( | |
227 GaiaConstants::kSyncService); | |
228 | |
229 DVLOG(2) << "UpdateCredentials: " << email; | |
230 invalidator_->UpdateCredentials(email, sync_token); | |
231 } | |
232 | |
233 void TiclInvalidationService::Stop() { | |
234 if (invalidator_) { | |
235 invalidator_->UnregisterHandler(this); | |
236 invalidator_.reset(); | |
237 } | |
238 if (invalidator_storage_) { | |
239 invalidator_storage_->Clear(); | |
240 invalidator_storage_.reset(); | |
241 } | |
242 } | |
243 | |
244 } // namespace invalidation | |
OLD | NEW |