1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// StatusController handles all counter and status related number crunching and
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// state tracking on behalf of a SyncSession.  It 'controls' the model data
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// defined in session_state.h.  The most important feature of StatusController
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is the ScopedModelSafetyRestriction. When one of these is active, the
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// underlying data set exposed via accessors is swapped out to the appropriate
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// set for the restricted ModelSafeGroup behind the scenes.  For example, if
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// GROUP_UI is set, then accessors such as conflict_progress() and commit_ids()
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// are implicitly restricted to returning only data pertaining to GROUP_UI.
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// You can see which parts of status fall into this "restricted" category, or
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// the global "shared" category for all model types, by looking at the struct
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// declarations in session_state.h. If these accessors are invoked without a
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// restriction in place, this is a violation and will cause debug assertions
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// to surface improper use of the API in development.  Likewise for
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// invocation of "shared" accessors when a restriction is in place; for
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// safety's sake, an assertion will fire.
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NOTE: There is no concurrent access protection provided by this class. It
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// assumes one single thread is accessing this class for each unique
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ModelSafeGroup, and also only one single thread (in practice, the
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SyncerThread) responsible for all "shared" access when no restriction is in
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// place. Thus, every bit of data is to be accessed mutually exclusively with
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// respect to threads.
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// StatusController can also track if changes occur to certain parts of state
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// so that various parts of the sync engine can avoid broadcasting
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notifications if no changes occurred.
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_SYNC_SESSIONS_STATUS_CONTROLLER_H_
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_SYNC_SESSIONS_STATUS_CONTROLLER_H_
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/ordered_commit_set.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/session_state.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace sessions {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass StatusController {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit StatusController(const ModelSafeRoutingInfo& routes);
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ~StatusController();
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if some portion of the session state has changed (is dirty)
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // since it was created or was last reset.
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool TestAndClearIsDirty();
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Progress counters.
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ConflictProgress& conflict_progress() {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return GetOrCreateModelSafeGroupState(true,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        group_restriction_)->conflict_progress;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ConflictProgress* mutable_conflict_progress() {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &GetOrCreateModelSafeGroupState(true,
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        group_restriction_)->conflict_progress;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const UpdateProgress& update_progress() {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return GetOrCreateModelSafeGroupState(true,
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        group_restriction_)->update_progress;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateProgress* mutable_update_progress() {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &GetOrCreateModelSafeGroupState(true,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        group_restriction_)->update_progress;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Some unrestricted, non-ModelChangingSyncerCommand commands need to store
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // meta information about updates.
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateProgress* GetUnrestrictedUpdateProgress(ModelSafeGroup group) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &GetOrCreateModelSafeGroupState(false, group)->update_progress;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ClientToServer messages.
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ClientToServerMessage& commit_message() {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.commit_message;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientToServerMessage* mutable_commit_message() {
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &shared_.commit_message;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ClientToServerResponse& commit_response() const {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.commit_response;
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientToServerResponse* mutable_commit_response() {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &shared_.commit_response;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const syncable::ModelTypeBitSet& updates_request_types() const {
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return shared_.updates_request_types;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void set_updates_request_types(const syncable::ModelTypeBitSet& value) {
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    shared_.updates_request_types = value;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ClientToServerResponse& updates_response() const {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.updates_response;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientToServerResponse* mutable_updates_response() {
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &shared_.updates_response;
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Errors and SyncerStatus.
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ErrorCounters& error_counters() const {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.error_counters.value();
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const SyncerStatus& syncer_status() const {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.syncer_status.value();
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Changelog related state.
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 num_server_changes_remaining() const {
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.num_server_changes_remaining.value();
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Commit path data.
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<syncable::Id>& commit_ids() const {
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!group_restriction_in_effect_) << "Group restriction in effect!";
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.commit_set.GetAllCommitIds();
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const OrderedCommitSet::Projection& commit_id_projection() {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(group_restriction_in_effect_)
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        << "No group restriction for projection.";
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.commit_set.GetCommitIdProjection(group_restriction_);
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const syncable::Id& GetCommitIdAt(size_t index) {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(CurrentCommitIdProjectionHasIndex(index));
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.commit_set.GetCommitIdAt(index);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::ModelType GetCommitIdModelTypeAt(size_t index) {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(CurrentCommitIdProjectionHasIndex(index));
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.commit_set.GetModelTypeAt(index);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<int64>& unsynced_handles() const {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!group_restriction_in_effect_)
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        << "unsynced_handles is unrestricted.";
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.unsynced_handles.value();
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Control parameters for sync cycles.
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool conflict_sets_built() const {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.control_params.conflict_sets_built;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool conflicts_resolved() const {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.control_params.conflicts_resolved;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool did_commit_items() const {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return shared_.control_params.items_committed;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If a GetUpdates for any data type resulted in downloading an update that
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is in conflict, this method returns true.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool HasConflictingUpdates() const;
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Aggregate sum of ConflictingItemSize() over all ConflictProgress objects
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (one for each ModelSafeGroup currently in-use).
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int TotalNumConflictingItems() const;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the number of updates received from the sync server.
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 CountUpdates() const;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true iff any of the commit ids added during this session are
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bookmark related, and the bookmark group restriction is in effect.
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool HasBookmarkCommitActivity() const {
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ActiveGroupRestrictionIncludesModel(syncable::BOOKMARKS) &&
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        shared_.commit_set.HasBookmarkCommitId();
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if the last download_updates_command received a valid
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // server response.
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool download_updates_succeeded() const {
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return updates_response().has_get_updates();
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if the last updates response indicated that we were fully
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // up to date.  This is subtle: if it's false, it could either mean that
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the server said there WAS more to download, or it could mean that we
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // were unable to reach the server.  If we didn't request every enabled
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // datatype, then we can't say for sure that there's nothing left to
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // download: in that case, this also returns false.
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ServerSaysNothingMoreToDownload() const;
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ModelSafeGroup group_restriction() const {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return group_restriction_;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check whether a particular model is included by the active group
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // restriction.
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ActiveGroupRestrictionIncludesModel(syncable::ModelType model) const {
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!group_restriction_in_effect_)
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ModelSafeRoutingInfo::const_iterator it = routing_info_.find(model);
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (it == routing_info_.end())
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return group_restriction() == it->second;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A toolbelt full of methods for updating counters and flags.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void increment_num_conflicting_commits_by(int value);
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void reset_num_conflicting_commits();
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_num_consecutive_transient_error_commits(int value);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void increment_num_consecutive_transient_error_commits_by(int value);
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_num_consecutive_errors(int value);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void increment_num_consecutive_errors();
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void increment_num_consecutive_errors_by(int value);
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_num_server_changes_remaining(int64 changes_remaining);
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_invalid_store(bool invalid_store);
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_syncer_stuck(bool syncer_stuck);
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_syncing(bool syncing);
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_num_successful_bookmark_commits(int value);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void increment_num_successful_commits();
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void increment_num_successful_bookmark_commits();
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void increment_num_updates_downloaded_by(int value);
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void increment_num_tombstone_updates_downloaded_by(int value);
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void set_types_needing_local_migration(const syncable::ModelTypeSet& types);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_unsynced_handles(const std::vector<int64>& unsynced_handles);
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_commit_set(const OrderedCommitSet& commit_set);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void update_conflict_sets_built(bool built);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void update_conflicts_resolved(bool resolved);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void reset_conflicts_resolved();
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_items_committed();
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class ScopedModelSafeGroupRestriction;
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true iff the commit id projection for |group_restriction_|
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // references position |index| into the full set of commit ids in play.
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool CurrentCommitIdProjectionHasIndex(size_t index);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper to lazily create objects for per-ModelSafeGroup state.
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PerModelSafeGroupState* GetOrCreateModelSafeGroupState(bool restrict,
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                         ModelSafeGroup group);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AllModelTypeState shared_;
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<ModelSafeGroup, PerModelSafeGroupState*> per_model_group_;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLValueDeleter<std::map<ModelSafeGroup, PerModelSafeGroupState*> >
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      per_model_group_deleter_;
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set to true if any DirtyOnWrite pieces of state we maintain are changed.
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset to false by TestAndClearIsDirty.
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_dirty_;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to fail read/write operations on state that don't obey the current
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // active ModelSafeWorker contract.
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool group_restriction_in_effect_;
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ModelSafeGroup group_restriction_;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ModelSafeRoutingInfo routing_info_;
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(StatusController);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A utility to restrict access to only those parts of the given
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// StatusController that pertain to the specified ModelSafeGroup.
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScopedModelSafeGroupRestriction {
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedModelSafeGroupRestriction(StatusController* to_restrict,
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  ModelSafeGroup restriction)
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : status_(to_restrict) {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!status_->group_restriction_in_effect_);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    status_->group_restriction_ = restriction;
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    status_->group_restriction_in_effect_ = true;
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~ScopedModelSafeGroupRestriction() {
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(status_->group_restriction_in_effect_);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    status_->group_restriction_in_effect_ = false;
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatusController* status_;
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ScopedModelSafeGroupRestriction);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SYNC_SESSIONS_STATUS_CONTROLLER_H_
279