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