1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 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// A class representing an attempt to synchronize the local syncable data
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// store with a sync server. A SyncSession instance is passed as a stateful
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// bundle to and from various SyncerCommands with the goal of converging the
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// client view of data with that of the server. The commands twiddle with
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// session status in response to events and hiccups along the way, set and
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// query session progress with regards to conflict resolution and applying
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// server updates, and access the SyncSessionContext for the current session
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// via SyncSession instances.
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <map>
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <string>
204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <utility>
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/engine/model_safe_worker.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/ordered_commit_set.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/session_state.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/status_controller.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/sync_session_context.h"
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/syncable/model_type.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/util/extensions_activity_monitor.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace syncable {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WriteTransaction;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ModelSafeWorker;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace sessions {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SyncSession {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The Delegate services events that occur during the session requiring an
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // explicit (and session-global) action, as opposed to events that are simply
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // recorded in per-session state.
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Delegate {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The client was throttled and should cease-and-desist syncing activity
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // until the specified time.
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnSilencedUntil(const base::TimeTicks& silenced_until) = 0;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Silenced intervals can be out of phase with individual sessions, so the
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // delegate is the only thing that can give an authoritative answer for
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // "is syncing silenced right now". This shouldn't be necessary very often
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // as the delegate ensures no session is started if syncing is silenced.
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // ** Note **  This will return true if silencing commenced during this
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // session and the interval has not yet elapsed, but the contract here is
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // solely based on absolute time values. So, this cannot be used to infer
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // that any given session _instance_ is silenced.  An example of reasonable
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // use is for UI reporting.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual bool IsSyncingCurrentlySilenced() = 0;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The client has been instructed to change its short poll interval.
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnReceivedShortPollIntervalUpdate(
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const base::TimeDelta& new_interval) = 0;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The client has been instructed to change its long poll interval.
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnReceivedLongPollIntervalUpdate(
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const base::TimeDelta& new_interval) = 0;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The client needs to cease and desist syncing at once.  This occurs when
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the Syncer detects that the backend store has fundamentally changed or
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // is a different instance altogether (e.g. swapping from a test instance
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // to production, or a global stop syncing operation has wiped the store).
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnShouldStopSyncingPermanently() = 0;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   protected:
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual ~Delegate() {}
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SyncSession(SyncSessionContext* context,
84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              Delegate* delegate,
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              const SyncSourceInfo& source,
86201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              const ModelSafeRoutingInfo& routing_info,
87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              const std::vector<ModelSafeWorker*>& workers);
88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ~SyncSession();
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Builds a thread-safe and read-only copy of the current session state.
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncSessionSnapshot TakeSnapshot() const;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if this session contains data that should go through the sync
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // engine again.
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool HasMoreToSync() const;
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Collects all state pertaining to how and why |s| originated and unions it
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // with corresponding state in |this|, leaving |s| unchanged.  Allows |this|
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // to take on the responsibilities |s| had (e.g. certain data types) in the
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // next SyncShare operation using |this|, rather than needed two separate
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // sessions.
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void Coalesce(const SyncSession& session);
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Should be called any time |this| is being re-used in a new call to
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // SyncShare (e.g., HasMoreToSync returned true).
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void ResetTransientState();
10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncSessionContext* context() const { return context_; }
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Delegate* delegate() const { return delegate_; }
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::WriteTransaction* write_transaction() { return write_transaction_; }
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatusController* status_controller() { return status_controller_.get(); }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ExtensionsActivityMonitor::Records& extensions_activity() const {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return extensions_activity_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor::Records* mutable_extensions_activity() {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &extensions_activity_;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Volatile reader for the source member of the sync session object.  The
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // value is set to the SYNC_CYCLE_CONTINUATION value to signal that it has
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // been read.
1234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  SyncSourceInfo TestAndSetSource();
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<ModelSafeWorker*>& workers() const { return workers_; }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ModelSafeRoutingInfo& routing_info() const { return routing_info_; }
127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const SyncSourceInfo& source() const { return source_; }
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extend the encapsulation boundary to utilities for internal member
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // assignments. This way, the scope of these actions is explicit, they can't
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be overridden, and assigning is always accompanied by unassigning.
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class ScopedSetSessionWriteTransaction;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The context for this session, guaranteed to outlive |this|.
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncSessionContext* const context_;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The source for initiating this sync session.
1394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  SyncSourceInfo source_;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Information about extensions activity since the last successful commit.
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsActivityMonitor::Records extensions_activity_;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to allow various steps to share a transaction. Can be NULL.
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::WriteTransaction* write_transaction_;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The delegate for this session, must never be NULL.
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Delegate* delegate_;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Our controller for various status and error counters.
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<StatusController> status_controller_;
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The set of active ModelSafeWorkers for the duration of this session.
15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // This can change if this session is Coalesce()'d with another.
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::vector<ModelSafeWorker*> workers_;
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The routing info for the duration of this session, dictating which
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // datatypes should be synced and which workers should be used when working
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on those datatypes.
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ModelSafeRoutingInfo routing_info_;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncSession);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Installs a WriteTransaction to a given session and later clears it when the
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// utility falls out of scope. Transactions are not nestable, so it is an error
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to try and use one of these if the session already has a transaction.
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScopedSetSessionWriteTransaction {
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedSetSessionWriteTransaction(SyncSession* session,
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   syncable::WriteTransaction* trans)
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : session_(session) {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!session_->write_transaction_);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    session_->write_transaction_ = trans;
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~ScopedSetSessionWriteTransaction() { session_->write_transaction_ = NULL; }
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncSession* session_;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ScopedSetSessionWriteTransaction);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace sessions
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser_sync
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_
187