OLD | NEW |
---|---|
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 "sync/notifier/sync_invalidation_listener.h" | 5 #include "sync/notifier/sync_invalidation_listener.h" |
6 | 6 |
7 #include <string> | |
8 #include <vector> | 7 #include <vector> |
9 | 8 |
9 #include "base/bind.h" | |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/stl_util.h" | |
13 #include "base/tracked_objects.h" | 14 #include "base/tracked_objects.h" |
14 #include "google/cacheinvalidation/include/invalidation-client.h" | 15 #include "google/cacheinvalidation/include/invalidation-client.h" |
15 #include "google/cacheinvalidation/include/types.h" | 16 #include "google/cacheinvalidation/include/types.h" |
16 #include "google/cacheinvalidation/types.pb.h" | 17 #include "google/cacheinvalidation/types.pb.h" |
17 #include "jingle/notifier/listener/push_client.h" | 18 #include "jingle/notifier/listener/push_client.h" |
18 #include "sync/notifier/invalidation_util.h" | 19 #include "sync/notifier/invalidation_util.h" |
19 #include "sync/notifier/registration_manager.h" | 20 #include "sync/notifier/registration_manager.h" |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 const char kApplicationName[] = "chrome-sync"; | 24 const char kApplicationName[] = "chrome-sync"; |
25 const int kMaxDelayInSeconds = 600; | |
26 | |
27 // TODO(dcheng): This is not testable yet. | |
28 base::TimeDelta CalculateBackoffDelay(int retry_count) { | |
29 // TODO(dcheng): This is not overflow safe. | |
30 int delay = std::min(kMaxDelayInSeconds, (1 << retry_count) * 60); | |
31 return base::TimeDelta::FromSeconds(delay); | |
32 } | |
24 | 33 |
25 } // namespace | 34 } // namespace |
26 | 35 |
27 namespace syncer { | 36 namespace syncer { |
28 | 37 |
29 SyncInvalidationListener::Delegate::~Delegate() {} | 38 SyncInvalidationListener::Delegate::~Delegate() {} |
30 | 39 |
31 SyncInvalidationListener::SyncInvalidationListener( | 40 SyncInvalidationListener::SyncInvalidationListener( |
32 scoped_ptr<notifier::PushClient> push_client) | 41 scoped_ptr<notifier::PushClient> push_client) |
33 : push_client_(push_client.get()), | 42 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
43 push_client_(push_client.get()), | |
34 sync_system_resources_(push_client.Pass(), | 44 sync_system_resources_(push_client.Pass(), |
35 ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 45 ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
36 delegate_(NULL), | 46 delegate_(NULL), |
37 ticl_state_(DEFAULT_INVALIDATION_ERROR), | 47 ticl_state_(DEFAULT_INVALIDATION_ERROR), |
38 push_client_state_(DEFAULT_INVALIDATION_ERROR) { | 48 push_client_state_(DEFAULT_INVALIDATION_ERROR) { |
39 DCHECK(CalledOnValidThread()); | 49 DCHECK(CalledOnValidThread()); |
40 push_client_->AddObserver(this); | 50 push_client_->AddObserver(this); |
41 } | 51 } |
42 | 52 |
43 SyncInvalidationListener::~SyncInvalidationListener() { | 53 SyncInvalidationListener::~SyncInvalidationListener() { |
44 DCHECK(CalledOnValidThread()); | 54 DCHECK(CalledOnValidThread()); |
45 push_client_->RemoveObserver(this); | 55 push_client_->RemoveObserver(this); |
46 Stop(); | 56 Stop(); |
47 DCHECK(!delegate_); | 57 DCHECK(!delegate_); |
48 } | 58 } |
49 | 59 |
50 void SyncInvalidationListener::Start( | 60 void SyncInvalidationListener::Start( |
51 const CreateInvalidationClientCallback& | 61 const CreateInvalidationClientCallback& |
52 create_invalidation_client_callback, | 62 create_invalidation_client_callback, |
53 const std::string& client_id, const std::string& client_info, | 63 const std::string& client_id, const std::string& client_info, |
54 const std::string& state, | 64 const std::string& state, |
55 const InvalidationVersionMap& initial_max_invalidation_versions, | 65 const InvalidationStateMap& initial_invalidation_state_map, |
56 const WeakHandle<InvalidationStateTracker>& invalidation_state_tracker, | 66 const WeakHandle<InvalidationStateTracker>& invalidation_state_tracker, |
57 Delegate* delegate) { | 67 Delegate* delegate) { |
58 DCHECK(CalledOnValidThread()); | 68 DCHECK(CalledOnValidThread()); |
59 Stop(); | 69 Stop(); |
60 | 70 |
61 sync_system_resources_.set_platform(client_info); | 71 sync_system_resources_.set_platform(client_info); |
62 sync_system_resources_.Start(); | 72 sync_system_resources_.Start(); |
63 | 73 |
64 // The Storage resource is implemented as a write-through cache. We populate | 74 // The Storage resource is implemented as a write-through cache. We populate |
65 // it with the initial state on startup, so subsequent writes go to disk and | 75 // it with the initial state on startup, so subsequent writes go to disk and |
66 // update the in-memory cache, while reads just return the cached state. | 76 // update the in-memory cache, while reads just return the cached state. |
67 sync_system_resources_.storage()->SetInitialState(state); | 77 sync_system_resources_.storage()->SetInitialState(state); |
68 | 78 |
69 max_invalidation_versions_ = initial_max_invalidation_versions; | 79 invalidation_state_map_ = initial_invalidation_state_map; |
70 if (max_invalidation_versions_.empty()) { | 80 if (invalidation_state_map_.empty()) { |
71 DVLOG(2) << "No initial max invalidation versions for any id"; | 81 DVLOG(2) << "No initial max invalidation versions for any id"; |
72 } else { | 82 } else { |
73 for (InvalidationVersionMap::const_iterator it = | 83 for (InvalidationStateMap::const_iterator it = |
74 max_invalidation_versions_.begin(); | 84 invalidation_state_map_.begin(); |
75 it != max_invalidation_versions_.end(); ++it) { | 85 it != invalidation_state_map_.end(); ++it) { |
76 DVLOG(2) << "Initial max invalidation version for " | 86 DVLOG(2) << "Initial max invalidation version for " |
77 << ObjectIdToString(it->first) << " is " | 87 << ObjectIdToString(it->first) << " is " |
78 << it->second; | 88 << it->second.version; |
79 } | 89 } |
80 } | 90 } |
81 invalidation_state_tracker_ = invalidation_state_tracker; | 91 invalidation_state_tracker_ = invalidation_state_tracker; |
82 DCHECK(invalidation_state_tracker_.IsInitialized()); | 92 DCHECK(invalidation_state_tracker_.IsInitialized()); |
83 | 93 |
84 DCHECK(!delegate_); | 94 DCHECK(!delegate_); |
85 DCHECK(delegate); | 95 DCHECK(delegate); |
86 delegate_ = delegate; | 96 delegate_ = delegate; |
87 | 97 |
88 int client_type = ipc::invalidation::ClientType::CHROME_SYNC; | 98 int client_type = ipc::invalidation::ClientType::CHROME_SYNC; |
(...skipping 17 matching lines...) Expand all Loading... | |
106 DCHECK(CalledOnValidThread()); | 116 DCHECK(CalledOnValidThread()); |
107 registered_ids_ = ids; | 117 registered_ids_ = ids; |
108 // |ticl_state_| can go to INVALIDATIONS_ENABLED even without a | 118 // |ticl_state_| can go to INVALIDATIONS_ENABLED even without a |
109 // working XMPP connection (as observed by us), so check it instead | 119 // working XMPP connection (as observed by us), so check it instead |
110 // of GetState() (see http://crbug.com/139424). | 120 // of GetState() (see http://crbug.com/139424). |
111 if (ticl_state_ == INVALIDATIONS_ENABLED && registration_manager_.get()) { | 121 if (ticl_state_ == INVALIDATIONS_ENABLED && registration_manager_.get()) { |
112 DoRegistrationUpdate(); | 122 DoRegistrationUpdate(); |
113 } | 123 } |
114 } | 124 } |
115 | 125 |
126 void SyncInvalidationListener::Acknowledge(const invalidation::ObjectId& id, | |
127 const AckHandle& ack_handle) { | |
128 DCHECK(CalledOnValidThread()); | |
129 InvalidationStateMap::iterator state_it = invalidation_state_map_.find(id); | |
130 if (state_it == invalidation_state_map_.end()) | |
131 return; | |
132 state_it->second.current = ack_handle; | |
133 if (state_it->second.expected.Equals(ack_handle)) { | |
134 // If the received ack matches the expected ack, then we no longer need to | |
135 // keep track of |id| since it is up-to-date. | |
136 for (TimerQueue::iterator it = timer_queue_.begin(); | |
137 it != timer_queue_.end(); ++it) { | |
138 if (it->second.id == id) { | |
139 timer_queue_.erase(it); | |
140 if (timer_queue_.empty()) { | |
141 timer_.Stop(); | |
142 } | |
143 return; | |
144 } | |
145 } | |
146 // This shouldn't happen unless someone is acking multiple times. | |
147 NOTREACHED(); | |
148 } | |
149 } | |
150 | |
116 void SyncInvalidationListener::Ready( | 151 void SyncInvalidationListener::Ready( |
117 invalidation::InvalidationClient* client) { | 152 invalidation::InvalidationClient* client) { |
118 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
119 DCHECK_EQ(client, invalidation_client_.get()); | 154 DCHECK_EQ(client, invalidation_client_.get()); |
120 ticl_state_ = INVALIDATIONS_ENABLED; | 155 ticl_state_ = INVALIDATIONS_ENABLED; |
121 EmitStateChange(); | 156 EmitStateChange(); |
122 DoRegistrationUpdate(); | 157 DoRegistrationUpdate(); |
123 } | 158 } |
124 | 159 |
125 void SyncInvalidationListener::Invalidate( | 160 void SyncInvalidationListener::Invalidate( |
126 invalidation::InvalidationClient* client, | 161 invalidation::InvalidationClient* client, |
127 const invalidation::Invalidation& invalidation, | 162 const invalidation::Invalidation& invalidation, |
128 const invalidation::AckHandle& ack_handle) { | 163 const invalidation::AckHandle& ack_handle) { |
129 DCHECK(CalledOnValidThread()); | 164 DCHECK(CalledOnValidThread()); |
130 DCHECK_EQ(client, invalidation_client_.get()); | 165 DCHECK_EQ(client, invalidation_client_.get()); |
131 DVLOG(1) << "Invalidate: " << InvalidationToString(invalidation); | 166 DVLOG(1) << "Invalidate: " << InvalidationToString(invalidation); |
132 | 167 |
133 const invalidation::ObjectId& id = invalidation.object_id(); | 168 const invalidation::ObjectId& id = invalidation.object_id(); |
134 | 169 |
135 // The invalidation API spec allows for the possibility of redundant | 170 // The invalidation API spec allows for the possibility of redundant |
136 // invalidations, so keep track of the max versions and drop | 171 // invalidations, so keep track of the max versions and drop |
137 // invalidations with old versions. | 172 // invalidations with old versions. |
138 // | 173 // |
139 // TODO(akalin): Now that we keep track of registered ids, we | 174 // TODO(akalin): Now that we keep track of registered ids, we |
140 // should drop invalidations for unregistered ids. We may also | 175 // should drop invalidations for unregistered ids. We may also |
141 // have to filter it at a higher level, as invalidations for | 176 // have to filter it at a higher level, as invalidations for |
142 // newly-unregistered ids may already be in flight. | 177 // newly-unregistered ids may already be in flight. |
143 InvalidationVersionMap::const_iterator it = | 178 InvalidationStateMap::const_iterator it = invalidation_state_map_.find(id); |
144 max_invalidation_versions_.find(id); | 179 if ((it != invalidation_state_map_.end()) && |
145 if ((it != max_invalidation_versions_.end()) && | 180 (invalidation.version() <= it->second.version)) { |
146 (invalidation.version() <= it->second)) { | |
147 // Drop redundant invalidations. | 181 // Drop redundant invalidations. |
148 client->Acknowledge(ack_handle); | 182 client->Acknowledge(ack_handle); |
149 return; | 183 return; |
150 } | 184 } |
151 DVLOG(2) << "Setting max invalidation version for " << ObjectIdToString(id) | 185 DVLOG(2) << "Setting max invalidation version for " << ObjectIdToString(id) |
152 << " to " << invalidation.version(); | 186 << " to " << invalidation.version(); |
153 max_invalidation_versions_[id] = invalidation.version(); | 187 invalidation_state_map_[id].version = invalidation.version(); |
154 invalidation_state_tracker_.Call( | 188 invalidation_state_tracker_.Call( |
155 FROM_HERE, | 189 FROM_HERE, |
156 &InvalidationStateTracker::SetMaxVersion, | 190 &InvalidationStateTracker::SetMaxVersion, |
157 id, invalidation.version()); | 191 id, invalidation.version()); |
158 | 192 |
159 std::string payload; | 193 std::string payload; |
160 // payload() CHECK()'s has_payload(), so we must check it ourselves first. | 194 // payload() CHECK()'s has_payload(), so we must check it ourselves first. |
161 if (invalidation.has_payload()) | 195 if (invalidation.has_payload()) |
162 payload = invalidation.payload(); | 196 payload = invalidation.payload(); |
163 | 197 |
164 ObjectIdStateMap id_state_map; | 198 ObjectIdSet ids; |
165 id_state_map[id].payload = payload; | 199 ids.insert(id); |
166 EmitInvalidation(id_state_map); | 200 PrepareInvalidation(ids, payload, client, ack_handle); |
167 // TODO(akalin): We should really acknowledge only after we get the | |
168 // updates from the sync server. (see http://crbug.com/78462). | |
169 client->Acknowledge(ack_handle); | |
170 } | 201 } |
171 | 202 |
172 void SyncInvalidationListener::InvalidateUnknownVersion( | 203 void SyncInvalidationListener::InvalidateUnknownVersion( |
173 invalidation::InvalidationClient* client, | 204 invalidation::InvalidationClient* client, |
174 const invalidation::ObjectId& object_id, | 205 const invalidation::ObjectId& object_id, |
175 const invalidation::AckHandle& ack_handle) { | 206 const invalidation::AckHandle& ack_handle) { |
176 DCHECK(CalledOnValidThread()); | 207 DCHECK(CalledOnValidThread()); |
177 DCHECK_EQ(client, invalidation_client_.get()); | 208 DCHECK_EQ(client, invalidation_client_.get()); |
178 DVLOG(1) << "InvalidateUnknownVersion"; | 209 DVLOG(1) << "InvalidateUnknownVersion"; |
179 | 210 |
180 ObjectIdStateMap id_state_map; | 211 ObjectIdSet ids; |
181 id_state_map[object_id].payload = std::string(); | 212 ids.insert(object_id); |
182 EmitInvalidation(id_state_map); | 213 PrepareInvalidation(ids, std::string(), client, ack_handle); |
183 // TODO(akalin): We should really acknowledge only after we get the | |
184 // updates from the sync server. (see http://crbug.com/78462). | |
185 client->Acknowledge(ack_handle); | |
186 } | 214 } |
187 | 215 |
188 // This should behave as if we got an invalidation with version | 216 // This should behave as if we got an invalidation with version |
189 // UNKNOWN_OBJECT_VERSION for all known data types. | 217 // UNKNOWN_OBJECT_VERSION for all known data types. |
190 void SyncInvalidationListener::InvalidateAll( | 218 void SyncInvalidationListener::InvalidateAll( |
191 invalidation::InvalidationClient* client, | 219 invalidation::InvalidationClient* client, |
192 const invalidation::AckHandle& ack_handle) { | 220 const invalidation::AckHandle& ack_handle) { |
193 DCHECK(CalledOnValidThread()); | 221 DCHECK(CalledOnValidThread()); |
194 DCHECK_EQ(client, invalidation_client_.get()); | 222 DCHECK_EQ(client, invalidation_client_.get()); |
195 DVLOG(1) << "InvalidateAll"; | 223 DVLOG(1) << "InvalidateAll"; |
196 | 224 |
197 ObjectIdStateMap id_state_map; | 225 PrepareInvalidation(registered_ids_, std::string(), client, ack_handle); |
198 for (ObjectIdSet::const_iterator it = registered_ids_.begin(); | 226 } |
199 it != registered_ids_.end(); ++it) { | 227 |
200 id_state_map[*it].payload = std::string(); | 228 void SyncInvalidationListener::PrepareInvalidation( |
229 const ObjectIdSet& ids, | |
230 const std::string& payload, | |
231 invalidation::InvalidationClient* client, | |
232 const invalidation::AckHandle& ack_handle) { | |
233 DCHECK(CalledOnValidThread()); | |
234 | |
235 scoped_ptr<AckHandleMap> local_ack_handles(new AckHandleMap); | |
236 invalidation_state_tracker_.CallWithReply( | |
akalin
2012/09/17 23:59:54
Hmm I don't think we need to add new CallWithReply
dcheng
2012/09/25 22:35:06
Per our discussion, we pass TaskRunner/Callback no
akalin
2012/10/01 23:23:08
Yeah. :/ WeakHandle only really works well in one-
| |
237 FROM_HERE, | |
238 &InvalidationStateTracker::GenerateAckHandles, | |
239 ids, | |
240 local_ack_handles.get(), | |
241 base::Bind(&SyncInvalidationListener::EmitInvalidation, | |
242 weak_ptr_factory_.GetWeakPtr(), | |
243 ids, | |
244 payload, | |
245 base::Owned(local_ack_handles.release()), | |
246 client, | |
247 ack_handle)); | |
248 } | |
249 | |
250 void SyncInvalidationListener::EmitInvalidation( | |
251 const ObjectIdSet& ids, | |
252 const std::string& payload, | |
253 const AckHandleMap* const local_ack_handles, | |
254 invalidation::InvalidationClient* client, | |
255 const invalidation::AckHandle& ack_handle) { | |
256 DCHECK(CalledOnValidThread()); | |
257 ObjectIdStateMap id_state_map = ObjectIdSetToStateMap(ids, payload); | |
258 // Erase any timer queue entries that correspond with an id in |ids|; a new | |
259 // invalidation will reset the retry count. | |
260 for (TimerQueue::iterator it = timer_queue_.begin(); | |
261 it != timer_queue_.end(); ) { | |
262 // We could be more clever here and reduce the complexity, since both | |
263 // containers are already sorted. Since we don't expect timer_queue_ to be | |
264 // very long in practice though, we just do things the simpler way. | |
265 if (ContainsKey(ids, it->second.id)) { | |
266 TimerQueue::iterator erase_it = it; | |
267 ++it; | |
268 timer_queue_.erase(erase_it); | |
269 } else { | |
270 ++it; | |
271 } | |
201 } | 272 } |
202 EmitInvalidation(id_state_map); | 273 const base::TimeTicks now = base::TimeTicks::Now(); |
203 // TODO(akalin): We should really acknowledge only after we get the | 274 const base::TimeTicks expiration_time = now + CalculateBackoffDelay(0); |
204 // updates from the sync server. (see http://crbug.com/76482). | 275 for (AckHandleMap::const_iterator it = local_ack_handles->begin(); |
276 it != local_ack_handles->end(); ++it) { | |
277 // Update in-memory copy of the invalidation state. | |
278 // TODO(dcheng): Maybe add some debug checks that the in-memory copy here is | |
279 // in sync with the copy in IST? | |
280 invalidation_state_map_[it->first].expected = it->second; | |
281 id_state_map[it->first].ack_handle = it->second; | |
282 timer_queue_.insert(std::make_pair( | |
283 expiration_time, QueueEntry(it->first, payload, 0 /* retry_count */))); | |
284 } | |
285 DCHECK(!timer_queue_.empty()); | |
286 // Start or update the timer to fire when the first item in the queue expires. | |
287 timer_.Start(FROM_HERE, now - timer_queue_.begin()->first, | |
288 this, &SyncInvalidationListener::RemitInvalidation); | |
289 delegate_->OnInvalidate(id_state_map); | |
205 client->Acknowledge(ack_handle); | 290 client->Acknowledge(ack_handle); |
206 } | 291 } |
207 | 292 |
208 void SyncInvalidationListener::EmitInvalidation( | 293 void SyncInvalidationListener::RemitInvalidation() { |
209 const ObjectIdStateMap& id_state_map) { | 294 ObjectIdStateMap id_state_map; |
210 DCHECK(CalledOnValidThread()); | 295 const base::TimeTicks now = base::TimeTicks::Now(); |
296 for (TimerQueue::iterator it = timer_queue_.begin(); | |
297 it != timer_queue_.end() && it->first <= now; ) { | |
298 it->second.retry_count++; | |
299 timer_queue_.insert(std::make_pair( | |
300 now + CalculateBackoffDelay(it->second.retry_count), it->second)); | |
301 InvalidationState state; | |
302 state.ack_handle = invalidation_state_map_[it->second.id].expected; | |
303 state.payload = it->second.payload; | |
304 id_state_map.insert(std::make_pair(it->second.id, state)); | |
305 TimerQueue::iterator erase_it = it; | |
306 ++it; | |
307 timer_queue_.erase(erase_it); | |
308 } | |
211 delegate_->OnInvalidate(id_state_map); | 309 delegate_->OnInvalidate(id_state_map); |
310 | |
212 } | 311 } |
213 | 312 |
214 void SyncInvalidationListener::InformRegistrationStatus( | 313 void SyncInvalidationListener::InformRegistrationStatus( |
215 invalidation::InvalidationClient* client, | 314 invalidation::InvalidationClient* client, |
216 const invalidation::ObjectId& object_id, | 315 const invalidation::ObjectId& object_id, |
217 InvalidationListener::RegistrationState new_state) { | 316 InvalidationListener::RegistrationState new_state) { |
218 DCHECK(CalledOnValidThread()); | 317 DCHECK(CalledOnValidThread()); |
219 DCHECK_EQ(client, invalidation_client_.get()); | 318 DCHECK_EQ(client, invalidation_client_.get()); |
220 DVLOG(1) << "InformRegistrationStatus: " | 319 DVLOG(1) << "InformRegistrationStatus: " |
221 << ObjectIdToString(object_id) << " " << new_state; | 320 << ObjectIdToString(object_id) << " " << new_state; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 invalidation_state_tracker_.Call( | 386 invalidation_state_tracker_.Call( |
288 FROM_HERE, &InvalidationStateTracker::SetInvalidationState, state); | 387 FROM_HERE, &InvalidationStateTracker::SetInvalidationState, state); |
289 } | 388 } |
290 | 389 |
291 void SyncInvalidationListener::DoRegistrationUpdate() { | 390 void SyncInvalidationListener::DoRegistrationUpdate() { |
292 DCHECK(CalledOnValidThread()); | 391 DCHECK(CalledOnValidThread()); |
293 const ObjectIdSet& unregistered_ids = | 392 const ObjectIdSet& unregistered_ids = |
294 registration_manager_->UpdateRegisteredIds(registered_ids_); | 393 registration_manager_->UpdateRegisteredIds(registered_ids_); |
295 invalidation_state_tracker_.Call( | 394 invalidation_state_tracker_.Call( |
296 FROM_HERE, &InvalidationStateTracker::Forget, unregistered_ids); | 395 FROM_HERE, &InvalidationStateTracker::Forget, unregistered_ids); |
396 for (ObjectIdSet::const_iterator it = unregistered_ids.begin(); | |
397 it != unregistered_ids.end(); ++it) { | |
398 invalidation_state_map_.erase(*it); | |
399 } | |
400 for (TimerQueue::iterator it = timer_queue_.begin(); | |
401 it != timer_queue_.end(); ) { | |
402 if (unregistered_ids.find(it->second.id) != unregistered_ids.end()) { | |
403 TimerQueue::iterator erase_it = it; | |
404 ++it; | |
405 timer_queue_.erase(erase_it); | |
406 } else { | |
407 ++it; | |
408 } | |
409 } | |
297 } | 410 } |
298 | 411 |
299 void SyncInvalidationListener::StopForTest() { | 412 void SyncInvalidationListener::StopForTest() { |
300 DCHECK(CalledOnValidThread()); | 413 DCHECK(CalledOnValidThread()); |
301 Stop(); | 414 Stop(); |
302 } | 415 } |
303 | 416 |
304 void SyncInvalidationListener::Stop() { | 417 void SyncInvalidationListener::Stop() { |
305 DCHECK(CalledOnValidThread()); | 418 DCHECK(CalledOnValidThread()); |
306 if (!invalidation_client_.get()) { | 419 if (!invalidation_client_.get()) { |
307 return; | 420 return; |
308 } | 421 } |
309 | 422 |
310 registration_manager_.reset(); | 423 registration_manager_.reset(); |
311 sync_system_resources_.Stop(); | 424 sync_system_resources_.Stop(); |
312 invalidation_client_->Stop(); | 425 invalidation_client_->Stop(); |
313 | 426 |
314 invalidation_client_.reset(); | 427 invalidation_client_.reset(); |
315 delegate_ = NULL; | 428 delegate_ = NULL; |
316 | 429 |
317 invalidation_state_tracker_.Reset(); | 430 invalidation_state_tracker_.Reset(); |
318 max_invalidation_versions_.clear(); | 431 invalidation_state_map_.clear(); |
319 ticl_state_ = DEFAULT_INVALIDATION_ERROR; | 432 ticl_state_ = DEFAULT_INVALIDATION_ERROR; |
320 push_client_state_ = DEFAULT_INVALIDATION_ERROR; | 433 push_client_state_ = DEFAULT_INVALIDATION_ERROR; |
321 } | 434 } |
322 | 435 |
323 InvalidatorState SyncInvalidationListener::GetState() const { | 436 InvalidatorState SyncInvalidationListener::GetState() const { |
324 DCHECK(CalledOnValidThread()); | 437 DCHECK(CalledOnValidThread()); |
325 if (ticl_state_ == INVALIDATION_CREDENTIALS_REJECTED || | 438 if (ticl_state_ == INVALIDATION_CREDENTIALS_REJECTED || |
326 push_client_state_ == INVALIDATION_CREDENTIALS_REJECTED) { | 439 push_client_state_ == INVALIDATION_CREDENTIALS_REJECTED) { |
327 // If either the ticl or the push client rejected our credentials, | 440 // If either the ticl or the push client rejected our credentials, |
328 // return INVALIDATION_CREDENTIALS_REJECTED. | 441 // return INVALIDATION_CREDENTIALS_REJECTED. |
(...skipping 27 matching lines...) Expand all Loading... | |
356 EmitStateChange(); | 469 EmitStateChange(); |
357 } | 470 } |
358 | 471 |
359 void SyncInvalidationListener::OnIncomingNotification( | 472 void SyncInvalidationListener::OnIncomingNotification( |
360 const notifier::Notification& notification) { | 473 const notifier::Notification& notification) { |
361 DCHECK(CalledOnValidThread()); | 474 DCHECK(CalledOnValidThread()); |
362 // Do nothing, since this is already handled by |invalidation_client_|. | 475 // Do nothing, since this is already handled by |invalidation_client_|. |
363 } | 476 } |
364 | 477 |
365 } // namespace syncer | 478 } // namespace syncer |
OLD | NEW |