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.h"
37 #include "sync/base/sync_export.h"
38 #include "sync/internal_api/public/sessions/model_neutral_state.h"
39 #include "sync/sessions/ordered_commit_set.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 sync_pb::ClientToServerResponse
& updates_response() const {
57 return model_neutral_
.updates_response
;
59 sync_pb::ClientToServerResponse
* mutable_updates_response() {
60 return &model_neutral_
.updates_response
;
63 // Changelog related state.
64 int64
num_server_changes_remaining() const {
65 return model_neutral_
.num_server_changes_remaining
;
68 const OrderedCommitSet::Projection
& commit_id_projection(
69 const sessions::OrderedCommitSet
&commit_set
) {
70 DCHECK(group_restriction_in_effect_
)
71 << "No group restriction for projection.";
72 return commit_set
.GetCommitIdProjection(group_restriction_
);
75 // Various conflict counters.
76 int num_encryption_conflicts() const;
77 int num_hierarchy_conflicts() const;
78 int num_server_conflicts() const;
80 // Aggregate sum of all conflicting items over all conflict types.
81 int TotalNumConflictingItems() const;
83 // Number of successfully applied updates.
84 int num_updates_applied() const;
86 int num_server_overwrites() const;
88 // Returns the number of updates received from the sync server.
89 int64
CountUpdates() const;
91 // Returns true if the last download_updates_command received a valid
93 bool download_updates_succeeded() const {
94 return model_neutral_
.last_download_updates_result
98 // Returns true if the last updates response indicated that we were fully
99 // up to date. This is subtle: if it's false, it could either mean that
100 // the server said there WAS more to download, or it could mean that we
101 // were unable to reach the server. If we didn't request every enabled
102 // datatype, then we can't say for sure that there's nothing left to
103 // download: in that case, this also returns false.
104 bool ServerSaysNothingMoreToDownload() const;
106 ModelSafeGroup
group_restriction() const {
107 return group_restriction_
;
110 base::Time
sync_start_time() const {
111 // The time at which we sent the first GetUpdates command for this sync.
112 return sync_start_time_
;
115 const ModelNeutralState
& model_neutral_state() const {
116 return model_neutral_
;
119 SyncerError
last_get_key_result() const;
121 // Download counters.
122 void set_num_server_changes_remaining(int64 changes_remaining
);
123 void increment_num_updates_downloaded_by(int value
);
124 void increment_num_tombstone_updates_downloaded_by(int value
);
125 void increment_num_reflected_updates_downloaded_by(int value
);
127 // Update application and conflict resolution counters.
128 void increment_num_updates_applied_by(int value
);
129 void increment_num_encryption_conflicts_by(int value
);
130 void increment_num_hierarchy_conflicts_by(int value
);
131 void increment_num_server_conflicts();
132 void increment_num_local_overwrites();
133 void increment_num_server_overwrites();
136 void increment_num_successful_commits();
137 void increment_num_successful_bookmark_commits();
138 void set_num_successful_bookmark_commits(int value
);
140 // Server communication status tracking.
141 void set_sync_protocol_error(const SyncProtocolError
& error
);
142 void set_last_get_key_result(const SyncerError result
);
143 void set_last_download_updates_result(const SyncerError result
);
144 void set_commit_result(const SyncerError result
);
146 // A very important flag used to inform frontend of need to migrate.
147 void set_types_needing_local_migration(ModelTypeSet types
);
149 void UpdateStartTime();
151 void set_debug_info_sent();
153 bool debug_info_sent() const;
156 friend class ScopedModelSafeGroupRestriction
;
158 ModelNeutralState model_neutral_
;
160 // Used to fail read/write operations on state that don't obey the current
161 // active ModelSafeWorker contract.
162 bool group_restriction_in_effect_
;
163 ModelSafeGroup group_restriction_
;
165 base::Time sync_start_time_
;
167 DISALLOW_COPY_AND_ASSIGN(StatusController
);
170 // A utility to restrict access to only those parts of the given
171 // StatusController that pertain to the specified ModelSafeGroup.
172 class ScopedModelSafeGroupRestriction
{
174 ScopedModelSafeGroupRestriction(StatusController
* to_restrict
,
175 ModelSafeGroup restriction
)
176 : status_(to_restrict
) {
177 DCHECK(!status_
->group_restriction_in_effect_
);
178 status_
->group_restriction_
= restriction
;
179 status_
->group_restriction_in_effect_
= true;
181 ~ScopedModelSafeGroupRestriction() {
182 DCHECK(status_
->group_restriction_in_effect_
);
183 status_
->group_restriction_in_effect_
= false;
186 StatusController
* status_
;
187 DISALLOW_COPY_AND_ASSIGN(ScopedModelSafeGroupRestriction
);
190 } // namespace sessions
191 } // namespace syncer
193 #endif // SYNC_SESSIONS_STATUS_CONTROLLER_H_