OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/sync/sessions/status_controller.h" | 5 #include "chrome/browser/sync/sessions/status_controller.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "chrome/browser/sync/syncable/model_type.h" | 8 #include "chrome/browser/sync/syncable/model_type.h" |
9 | 9 |
10 namespace browser_sync { | 10 namespace browser_sync { |
11 namespace sessions { | 11 namespace sessions { |
12 | 12 |
13 using syncable::FIRST_REAL_MODEL_TYPE; | 13 using syncable::FIRST_REAL_MODEL_TYPE; |
14 using syncable::MODEL_TYPE_COUNT; | 14 using syncable::MODEL_TYPE_COUNT; |
15 | 15 |
16 StatusController::StatusController(const ModelSafeRoutingInfo& routes) | 16 StatusController::StatusController(const ModelSafeRoutingInfo& routes) |
17 : shared_(&is_dirty_), | 17 : shared_(&is_dirty_), |
18 per_model_group_deleter_(&per_model_group_), | 18 per_model_group_deleter_(&per_model_group_), |
19 per_model_type_deleter_(&per_model_type_), | |
20 is_dirty_(false), | 19 is_dirty_(false), |
21 group_restriction_in_effect_(false), | 20 group_restriction_in_effect_(false), |
22 group_restriction_(GROUP_PASSIVE), | 21 group_restriction_(GROUP_PASSIVE), |
23 routing_info_(routes) { | 22 routing_info_(routes) { |
24 } | 23 } |
25 | 24 |
26 StatusController::~StatusController() {} | 25 StatusController::~StatusController() {} |
27 | 26 |
28 bool StatusController::TestAndClearIsDirty() { | 27 bool StatusController::TestAndClearIsDirty() { |
29 bool is_dirty = is_dirty_; | 28 bool is_dirty = is_dirty_; |
30 is_dirty_ = false; | 29 is_dirty_ = false; |
31 return is_dirty; | 30 return is_dirty; |
32 } | 31 } |
33 | 32 |
34 PerModelSafeGroupState* StatusController::GetOrCreateModelSafeGroupState( | 33 PerModelSafeGroupState* StatusController::GetOrCreateModelSafeGroupState( |
35 bool restrict, ModelSafeGroup group) { | 34 bool restrict, ModelSafeGroup group) { |
36 DCHECK(restrict == group_restriction_in_effect_) << "Group violation!"; | 35 DCHECK(restrict == group_restriction_in_effect_) << "Group violation!"; |
37 if (per_model_group_.find(group) == per_model_group_.end()) { | 36 if (per_model_group_.find(group) == per_model_group_.end()) { |
38 PerModelSafeGroupState* state = new PerModelSafeGroupState(&is_dirty_); | 37 PerModelSafeGroupState* state = new PerModelSafeGroupState(&is_dirty_); |
39 per_model_group_[group] = state; | 38 per_model_group_[group] = state; |
40 return state; | 39 return state; |
41 } | 40 } |
42 return per_model_group_[group]; | 41 return per_model_group_[group]; |
43 } | 42 } |
44 | 43 |
45 PerModelTypeState* StatusController::GetOrCreateModelTypeState( | |
46 bool restrict, syncable::ModelType model) { | |
47 if (restrict) { | |
48 DCHECK(group_restriction_in_effect_) << "No group restriction in effect!"; | |
49 DCHECK_EQ(group_restriction_, GetGroupForModelType(model, routing_info_)); | |
50 } | |
51 if (per_model_type_.find(model) == per_model_type_.end()) { | |
52 PerModelTypeState* state = new PerModelTypeState(&is_dirty_); | |
53 per_model_type_[model] = state; | |
54 return state; | |
55 } | |
56 return per_model_type_[model]; | |
57 } | |
58 | |
59 void StatusController::increment_num_conflicting_commits_by(int value) { | 44 void StatusController::increment_num_conflicting_commits_by(int value) { |
60 if (value == 0) | 45 if (value == 0) |
61 return; | 46 return; |
62 shared_.error_counters.mutate()->num_conflicting_commits += value; | 47 shared_.error_counters.mutate()->num_conflicting_commits += value; |
63 } | 48 } |
64 | 49 |
| 50 void StatusController::increment_num_updates_downloaded_by(int value) { |
| 51 shared_.syncer_status.mutate()->num_updates_downloaded_total += value; |
| 52 } |
| 53 |
| 54 void StatusController::increment_num_tombstone_updates_downloaded_by( |
| 55 int value) { |
| 56 shared_.syncer_status.mutate()->num_tombstone_updates_downloaded_total += |
| 57 value; |
| 58 } |
| 59 |
65 void StatusController::reset_num_conflicting_commits() { | 60 void StatusController::reset_num_conflicting_commits() { |
66 if (shared_.error_counters.value().num_conflicting_commits != 0) | 61 if (shared_.error_counters.value().num_conflicting_commits != 0) |
67 shared_.error_counters.mutate()->num_conflicting_commits = 0; | 62 shared_.error_counters.mutate()->num_conflicting_commits = 0; |
68 } | 63 } |
69 | 64 |
70 void StatusController::set_num_consecutive_transient_error_commits(int value) { | 65 void StatusController::set_num_consecutive_transient_error_commits(int value) { |
71 if (shared_.error_counters.value().consecutive_transient_error_commits != | 66 if (shared_.error_counters.value().consecutive_transient_error_commits != |
72 value) { | 67 value) { |
73 shared_.error_counters.mutate()->consecutive_transient_error_commits = | 68 shared_.error_counters.mutate()->consecutive_transient_error_commits = |
74 value; | 69 value; |
75 } | 70 } |
76 } | 71 } |
77 | 72 |
78 void StatusController::increment_num_consecutive_transient_error_commits_by( | 73 void StatusController::increment_num_consecutive_transient_error_commits_by( |
79 int value) { | 74 int value) { |
80 set_num_consecutive_transient_error_commits( | 75 set_num_consecutive_transient_error_commits( |
81 shared_.error_counters.value().consecutive_transient_error_commits + | 76 shared_.error_counters.value().consecutive_transient_error_commits + |
82 value); | 77 value); |
83 } | 78 } |
84 | 79 |
85 void StatusController::set_num_consecutive_errors(int value) { | 80 void StatusController::set_num_consecutive_errors(int value) { |
86 if (shared_.error_counters.value().consecutive_errors != value) | 81 if (shared_.error_counters.value().consecutive_errors != value) |
87 shared_.error_counters.mutate()->consecutive_errors = value; | 82 shared_.error_counters.mutate()->consecutive_errors = value; |
88 } | 83 } |
89 | 84 |
90 void StatusController::set_current_download_timestamp( | |
91 syncable::ModelType model, | |
92 int64 current_timestamp) { | |
93 PerModelTypeState* state = GetOrCreateModelTypeState(false, model); | |
94 if (current_timestamp > state->current_download_timestamp.value()) | |
95 *(state->current_download_timestamp.mutate()) = current_timestamp; | |
96 } | |
97 | |
98 void StatusController::set_num_server_changes_remaining( | 85 void StatusController::set_num_server_changes_remaining( |
99 int64 changes_remaining) { | 86 int64 changes_remaining) { |
100 if (shared_.num_server_changes_remaining.value() != changes_remaining) | 87 if (shared_.num_server_changes_remaining.value() != changes_remaining) |
101 *(shared_.num_server_changes_remaining.mutate()) = changes_remaining; | 88 *(shared_.num_server_changes_remaining.mutate()) = changes_remaining; |
102 } | 89 } |
103 | 90 |
104 void StatusController::set_invalid_store(bool invalid_store) { | 91 void StatusController::set_invalid_store(bool invalid_store) { |
105 if (shared_.syncer_status.value().invalid_store != invalid_store) | 92 if (shared_.syncer_status.value().invalid_store != invalid_store) |
106 shared_.syncer_status.mutate()->invalid_store = invalid_store; | 93 shared_.syncer_status.mutate()->invalid_store = invalid_store; |
107 } | 94 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 return 0; | 161 return 0; |
175 } | 162 } |
176 } | 163 } |
177 | 164 |
178 bool StatusController::CurrentCommitIdProjectionHasIndex(size_t index) { | 165 bool StatusController::CurrentCommitIdProjectionHasIndex(size_t index) { |
179 OrderedCommitSet::Projection proj = | 166 OrderedCommitSet::Projection proj = |
180 shared_.commit_set.GetCommitIdProjection(group_restriction_); | 167 shared_.commit_set.GetCommitIdProjection(group_restriction_); |
181 return std::binary_search(proj.begin(), proj.end(), index); | 168 return std::binary_search(proj.begin(), proj.end(), index); |
182 } | 169 } |
183 | 170 |
184 int64 StatusController::ComputeMaxLocalTimestamp() const { | |
185 std::map<syncable::ModelType, PerModelTypeState*>::const_iterator it = | |
186 per_model_type_.begin(); | |
187 int64 max_timestamp = 0; | |
188 for (; it != per_model_type_.end(); ++it) { | |
189 if (it->second->current_download_timestamp.value() > max_timestamp) | |
190 max_timestamp = it->second->current_download_timestamp.value(); | |
191 } | |
192 return max_timestamp; | |
193 } | |
194 | |
195 bool StatusController::HasConflictingUpdates() const { | 171 bool StatusController::HasConflictingUpdates() const { |
196 DCHECK(!group_restriction_in_effect_) | 172 DCHECK(!group_restriction_in_effect_) |
197 << "HasConflictingUpdates applies to all ModelSafeGroups"; | 173 << "HasConflictingUpdates applies to all ModelSafeGroups"; |
198 std::map<ModelSafeGroup, PerModelSafeGroupState*>::const_iterator it = | 174 std::map<ModelSafeGroup, PerModelSafeGroupState*>::const_iterator it = |
199 per_model_group_.begin(); | 175 per_model_group_.begin(); |
200 for (; it != per_model_group_.end(); ++it) { | 176 for (; it != per_model_group_.end(); ++it) { |
201 if (it->second->update_progress.HasConflictingUpdates()) | 177 if (it->second->update_progress.HasConflictingUpdates()) |
202 return true; | 178 return true; |
203 } | 179 } |
204 return false; | 180 return false; |
205 } | 181 } |
206 | 182 |
207 int StatusController::TotalNumConflictingItems() const { | 183 int StatusController::TotalNumConflictingItems() const { |
208 DCHECK(!group_restriction_in_effect_) | 184 DCHECK(!group_restriction_in_effect_) |
209 << "TotalNumConflictingItems applies to all ModelSafeGroups"; | 185 << "TotalNumConflictingItems applies to all ModelSafeGroups"; |
210 std::map<ModelSafeGroup, PerModelSafeGroupState*>::const_iterator it = | 186 std::map<ModelSafeGroup, PerModelSafeGroupState*>::const_iterator it = |
211 per_model_group_.begin(); | 187 per_model_group_.begin(); |
212 int sum = 0; | 188 int sum = 0; |
213 for (; it != per_model_group_.end(); ++it) { | 189 for (; it != per_model_group_.end(); ++it) { |
214 sum += it->second->conflict_progress.ConflictingItemsSize(); | 190 sum += it->second->conflict_progress.ConflictingItemsSize(); |
215 } | 191 } |
216 return sum; | 192 return sum; |
217 } | 193 } |
218 | 194 |
219 bool StatusController::ServerSaysNothingMoreToDownload() const { | 195 bool StatusController::ServerSaysNothingMoreToDownload() const { |
220 if (!download_updates_succeeded()) | 196 if (!download_updates_succeeded()) |
221 return false; | 197 return false; |
222 // If we didn't request every enabled datatype, then we can't say for | 198 |
223 // sure that there's nothing left to download. | 199 if (!updates_response().get_updates().has_changes_remaining()) { |
224 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | 200 NOTREACHED(); // Server should always send changes remaining. |
225 if (!updates_request_parameters().data_types[i] && | 201 return false; // Avoid looping forever. |
226 routing_info_.count(syncable::ModelTypeFromInt(i)) != 0) { | |
227 return false; | |
228 } | |
229 } | 202 } |
230 // Changes remaining is an estimate, but if it's estimated to be | 203 // Changes remaining is an estimate, but if it's estimated to be |
231 // zero, that's firm and we don't have to ask again. | 204 // zero, that's firm and we don't have to ask again. |
232 if (updates_response().get_updates().has_changes_remaining() && | 205 return updates_response().get_updates().changes_remaining() == 0; |
233 updates_response().get_updates().changes_remaining() == 0) { | |
234 return true; | |
235 } | |
236 // Otherwise, the server can also indicate "you're up to date" | |
237 // by not sending a new timestamp. | |
238 return !updates_response().get_updates().has_new_timestamp(); | |
239 } | 206 } |
240 | 207 |
241 } // namespace sessions | 208 } // namespace sessions |
242 } // namespace browser_sync | 209 } // namespace browser_sync |
OLD | NEW |