1 // Copyright 2012 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.
5 // StatusController handles all counter and status related number crunching and
6 // state tracking on behalf of a SyncSession.
8 // The most important feature of StatusController is the
9 // ScopedModelSafeGroupRestriction. Some of its functions expose per-thread
10 // state, and can be called only when the restriction is in effect. For
11 // example, if GROUP_UI is set then the value returned from
12 // commit_id_projection() will be useful for iterating over the commit IDs of
13 // items that live on the UI thread.
15 // Other parts of its state are global, and do not require the restriction.
17 // NOTE: There is no concurrent access protection provided by this class. It
18 // assumes one single thread is accessing this class for each unique
19 // ModelSafeGroup, and also only one single thread (in practice, the
20 // SyncerThread) responsible for all "shared" access when no restriction is in
21 // place. Thus, every bit of data is to be accessed mutually exclusively with
22 // respect to threads.
24 // StatusController can also track if changes occur to certain parts of state
25 // so that various parts of the sync engine can avoid broadcasting
26 // notifications if no changes occurred.
28 #ifndef SYNC_SESSIONS_STATUS_CONTROLLER_H_
29 #define SYNC_SESSIONS_STATUS_CONTROLLER_H_
34 #include "base/logging.h"
35 #include "base/stl_util.h"
36 #include "base/time/time.h"
37 #include "sync/base/sync_export.h"
38 #include "sync/internal_api/public/engine/model_safe_worker.h"
39 #include "sync/internal_api/public/sessions/model_neutral_state.h"
44 class SYNC_EXPORT_PRIVATE StatusController {
46 explicit StatusController();
49 // ClientToServer messages.
50 const ModelTypeSet updates_request_types() const {
51 return model_neutral_.updates_request_types;
53 void set_updates_request_types(ModelTypeSet value) {
54 model_neutral_.updates_request_types = value;
56 const ModelTypeSet commit_request_types() const {
57 return model_neutral_.commit_request_types;
59 void set_commit_request_types(ModelTypeSet value) {
60 model_neutral_.commit_request_types = value;
62 const sync_pb::ClientToServerResponse& updates_response() const {
63 return model_neutral_.updates_response;
65 sync_pb::ClientToServerResponse* mutable_updates_response() {
66 return &model_neutral_.updates_response;
69 // Changelog related state.
70 int64 num_server_changes_remaining() const {
71 return model_neutral_.num_server_changes_remaining;
74 // Various conflict counters.
75 int num_encryption_conflicts() const;
76 int num_hierarchy_conflicts() const;
77 int num_server_conflicts() const;
79 // Aggregate sum of all conflicting items over all conflict types.
80 int TotalNumConflictingItems() const;
82 // Number of successfully applied updates.
83 int num_updates_applied() const;
85 int num_server_overwrites() const;
87 // Returns the number of updates received from the sync server.
88 int64 CountUpdates() const;
90 // Returns true if the last download_updates_command received a valid
92 bool download_updates_succeeded() const {
93 return model_neutral_.last_download_updates_result
97 // Returns true if the last updates response indicated that we were fully
98 // up to date. This is subtle: if it's false, it could either mean that
99 // the server said there WAS more to download, or it could mean that we
100 // were unable to reach the server. If we didn't request every enabled
101 // datatype, then we can't say for sure that there's nothing left to
102 // download: in that case, this also returns false.
103 bool ServerSaysNothingMoreToDownload() const;
105 ModelSafeGroup group_restriction() const {
106 return group_restriction_;
109 base::Time sync_start_time() const {
110 // The time at which we sent the first GetUpdates command for this sync.
111 return sync_start_time_;
114 const ModelNeutralState& model_neutral_state() const {
115 return model_neutral_;
118 SyncerError last_get_key_result() const;
120 // Download counters.
121 void set_num_server_changes_remaining(int64 changes_remaining);
122 void increment_num_updates_downloaded_by(int value);
123 void increment_num_tombstone_updates_downloaded_by(int value);
124 void increment_num_reflected_updates_downloaded_by(int value);
126 // Update application and conflict resolution counters.
127 void increment_num_updates_applied_by(int value);
128 void increment_num_encryption_conflicts_by(int value);
129 void increment_num_hierarchy_conflicts_by(int value);
130 void increment_num_server_conflicts();
131 void increment_num_local_overwrites();
132 void increment_num_server_overwrites();
135 void increment_num_successful_commits();
136 void increment_num_successful_bookmark_commits();
137 void set_num_successful_bookmark_commits(int value);
139 // Server communication status tracking.
140 void set_sync_protocol_error(const SyncProtocolError& error);
141 void set_last_get_key_result(const SyncerError result);
142 void set_last_download_updates_result(const SyncerError result);
143 void set_commit_result(const SyncerError result);
145 // A very important flag used to inform frontend of need to migrate.
146 void set_types_needing_local_migration(ModelTypeSet types);
148 void UpdateStartTime();
150 void set_debug_info_sent();
152 bool debug_info_sent() const;
155 friend class ScopedModelSafeGroupRestriction;
157 ModelNeutralState model_neutral_;
159 // Used to fail read/write operations on state that don't obey the current
160 // active ModelSafeWorker contract.
161 bool group_restriction_in_effect_;
162 ModelSafeGroup group_restriction_;
164 base::Time sync_start_time_;
166 DISALLOW_COPY_AND_ASSIGN(StatusController);
169 // A utility to restrict access to only those parts of the given
170 // StatusController that pertain to the specified ModelSafeGroup.
171 class ScopedModelSafeGroupRestriction {
173 ScopedModelSafeGroupRestriction(StatusController* to_restrict,
174 ModelSafeGroup restriction)
175 : status_(to_restrict) {
176 DCHECK(!status_->group_restriction_in_effect_);
177 status_->group_restriction_ = restriction;
178 status_->group_restriction_in_effect_ = true;
180 ~ScopedModelSafeGroupRestriction() {
181 DCHECK(status_->group_restriction_in_effect_);
182 status_->group_restriction_in_effect_ = false;
185 StatusController* status_;
186 DISALLOW_COPY_AND_ASSIGN(ScopedModelSafeGroupRestriction);
189 } // namespace sessions
190 } // namespace syncer
192 #endif // SYNC_SESSIONS_STATUS_CONTROLLER_H_