• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/sync/sessions/status_controller.h"
6 
7 #include "base/basictypes.h"
8 #include "chrome/browser/sync/syncable/model_type.h"
9 
10 namespace browser_sync {
11 namespace sessions {
12 
13 using syncable::FIRST_REAL_MODEL_TYPE;
14 using syncable::MODEL_TYPE_COUNT;
15 
StatusController(const ModelSafeRoutingInfo & routes)16 StatusController::StatusController(const ModelSafeRoutingInfo& routes)
17     : shared_(&is_dirty_),
18       per_model_group_deleter_(&per_model_group_),
19       is_dirty_(false),
20       group_restriction_in_effect_(false),
21       group_restriction_(GROUP_PASSIVE),
22       routing_info_(routes) {
23 }
24 
~StatusController()25 StatusController::~StatusController() {}
26 
TestAndClearIsDirty()27 bool StatusController::TestAndClearIsDirty() {
28   bool is_dirty = is_dirty_;
29   is_dirty_ = false;
30   return is_dirty;
31 }
32 
GetOrCreateModelSafeGroupState(bool restrict,ModelSafeGroup group)33 PerModelSafeGroupState* StatusController::GetOrCreateModelSafeGroupState(
34     bool restrict, ModelSafeGroup group) {
35   DCHECK(restrict == group_restriction_in_effect_) << "Group violation!";
36   if (per_model_group_.find(group) == per_model_group_.end()) {
37     PerModelSafeGroupState* state = new PerModelSafeGroupState(&is_dirty_);
38     per_model_group_[group] = state;
39     return state;
40   }
41   return per_model_group_[group];
42 }
43 
increment_num_conflicting_commits_by(int value)44 void StatusController::increment_num_conflicting_commits_by(int value) {
45   if (value == 0)
46     return;
47   shared_.error_counters.mutate()->num_conflicting_commits += value;
48 }
49 
increment_num_updates_downloaded_by(int value)50 void StatusController::increment_num_updates_downloaded_by(int value) {
51   shared_.syncer_status.mutate()->num_updates_downloaded_total += value;
52 }
53 
set_types_needing_local_migration(const syncable::ModelTypeSet & types)54 void StatusController::set_types_needing_local_migration(
55     const syncable::ModelTypeSet& types) {
56   shared_.syncer_status.mutate()->types_needing_local_migration = types;
57 }
58 
increment_num_tombstone_updates_downloaded_by(int value)59 void StatusController::increment_num_tombstone_updates_downloaded_by(
60     int value) {
61   shared_.syncer_status.mutate()->num_tombstone_updates_downloaded_total +=
62       value;
63 }
64 
reset_num_conflicting_commits()65 void StatusController::reset_num_conflicting_commits() {
66   if (shared_.error_counters.value().num_conflicting_commits != 0)
67     shared_.error_counters.mutate()->num_conflicting_commits = 0;
68 }
69 
set_num_consecutive_transient_error_commits(int value)70 void StatusController::set_num_consecutive_transient_error_commits(int value) {
71   if (shared_.error_counters.value().consecutive_transient_error_commits !=
72       value) {
73     shared_.error_counters.mutate()->consecutive_transient_error_commits =
74         value;
75   }
76 }
77 
increment_num_consecutive_transient_error_commits_by(int value)78 void StatusController::increment_num_consecutive_transient_error_commits_by(
79     int value) {
80   set_num_consecutive_transient_error_commits(
81       shared_.error_counters.value().consecutive_transient_error_commits +
82       value);
83 }
84 
set_num_consecutive_errors(int value)85 void StatusController::set_num_consecutive_errors(int value) {
86   if (shared_.error_counters.value().consecutive_errors != value)
87     shared_.error_counters.mutate()->consecutive_errors = value;
88 }
89 
set_num_server_changes_remaining(int64 changes_remaining)90 void StatusController::set_num_server_changes_remaining(
91     int64 changes_remaining) {
92   if (shared_.num_server_changes_remaining.value() != changes_remaining)
93     *(shared_.num_server_changes_remaining.mutate()) = changes_remaining;
94 }
95 
set_invalid_store(bool invalid_store)96 void StatusController::set_invalid_store(bool invalid_store) {
97   if (shared_.syncer_status.value().invalid_store != invalid_store)
98     shared_.syncer_status.mutate()->invalid_store = invalid_store;
99 }
100 
set_syncer_stuck(bool syncer_stuck)101 void StatusController::set_syncer_stuck(bool syncer_stuck) {
102   if (shared_.syncer_status.value().syncer_stuck != syncer_stuck)
103     shared_.syncer_status.mutate()->syncer_stuck = syncer_stuck;
104 }
105 
set_syncing(bool syncing)106 void StatusController::set_syncing(bool syncing) {
107   if (shared_.syncer_status.value().syncing != syncing)
108     shared_.syncer_status.mutate()->syncing = syncing;
109 }
110 
set_num_successful_bookmark_commits(int value)111 void StatusController::set_num_successful_bookmark_commits(int value) {
112   if (shared_.syncer_status.value().num_successful_bookmark_commits != value)
113     shared_.syncer_status.mutate()->num_successful_bookmark_commits = value;
114 }
115 
set_unsynced_handles(const std::vector<int64> & unsynced_handles)116 void StatusController::set_unsynced_handles(
117     const std::vector<int64>& unsynced_handles) {
118   if (!operator==(unsynced_handles, shared_.unsynced_handles.value())) {
119     *(shared_.unsynced_handles.mutate()) = unsynced_handles;
120   }
121 }
122 
increment_num_consecutive_errors()123 void StatusController::increment_num_consecutive_errors() {
124   set_num_consecutive_errors(
125       shared_.error_counters.value().consecutive_errors + 1);
126 }
127 
increment_num_consecutive_errors_by(int value)128 void StatusController::increment_num_consecutive_errors_by(int value) {
129   set_num_consecutive_errors(
130       shared_.error_counters.value().consecutive_errors + value);
131 }
132 
increment_num_successful_bookmark_commits()133 void StatusController::increment_num_successful_bookmark_commits() {
134   set_num_successful_bookmark_commits(
135       shared_.syncer_status.value().num_successful_bookmark_commits + 1);
136 }
137 
increment_num_successful_commits()138 void StatusController::increment_num_successful_commits() {
139   shared_.syncer_status.mutate()->num_successful_commits++;
140 }
141 
set_commit_set(const OrderedCommitSet & commit_set)142 void StatusController::set_commit_set(const OrderedCommitSet& commit_set) {
143   DCHECK(!group_restriction_in_effect_);
144   shared_.commit_set = commit_set;
145 }
146 
update_conflict_sets_built(bool built)147 void StatusController::update_conflict_sets_built(bool built) {
148   shared_.control_params.conflict_sets_built |= built;
149 }
update_conflicts_resolved(bool resolved)150 void StatusController::update_conflicts_resolved(bool resolved) {
151   shared_.control_params.conflict_sets_built |= resolved;
152 }
reset_conflicts_resolved()153 void StatusController::reset_conflicts_resolved() {
154   shared_.control_params.conflicts_resolved = false;
155 }
set_items_committed()156 void StatusController::set_items_committed() {
157   shared_.control_params.items_committed = true;
158 }
159 
160 // Returns the number of updates received from the sync server.
CountUpdates() const161 int64 StatusController::CountUpdates() const {
162   const ClientToServerResponse& updates = shared_.updates_response;
163   if (updates.has_get_updates()) {
164     return updates.get_updates().entries().size();
165   } else {
166     return 0;
167   }
168 }
169 
CurrentCommitIdProjectionHasIndex(size_t index)170 bool StatusController::CurrentCommitIdProjectionHasIndex(size_t index) {
171   OrderedCommitSet::Projection proj =
172       shared_.commit_set.GetCommitIdProjection(group_restriction_);
173   return std::binary_search(proj.begin(), proj.end(), index);
174 }
175 
HasConflictingUpdates() const176 bool StatusController::HasConflictingUpdates() const {
177   DCHECK(!group_restriction_in_effect_)
178       << "HasConflictingUpdates applies to all ModelSafeGroups";
179   std::map<ModelSafeGroup, PerModelSafeGroupState*>::const_iterator it =
180     per_model_group_.begin();
181   for (; it != per_model_group_.end(); ++it) {
182     if (it->second->update_progress.HasConflictingUpdates())
183       return true;
184   }
185   return false;
186 }
187 
TotalNumConflictingItems() const188 int StatusController::TotalNumConflictingItems() const {
189   DCHECK(!group_restriction_in_effect_)
190       << "TotalNumConflictingItems applies to all ModelSafeGroups";
191   std::map<ModelSafeGroup, PerModelSafeGroupState*>::const_iterator it =
192     per_model_group_.begin();
193   int sum = 0;
194   for (; it != per_model_group_.end(); ++it) {
195     sum += it->second->conflict_progress.ConflictingItemsSize();
196   }
197   return sum;
198 }
199 
ServerSaysNothingMoreToDownload() const200 bool StatusController::ServerSaysNothingMoreToDownload() const {
201   if (!download_updates_succeeded())
202     return false;
203 
204   if (!updates_response().get_updates().has_changes_remaining()) {
205     NOTREACHED();  // Server should always send changes remaining.
206     return false;  // Avoid looping forever.
207   }
208   // Changes remaining is an estimate, but if it's estimated to be
209   // zero, that's firm and we don't have to ask again.
210   return updates_response().get_updates().changes_remaining() == 0;
211 }
212 
213 }  // namespace sessions
214 }  // namespace browser_sync
215