summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/sessions/sync_session.h
blob: 9e532d779be51747e6e07c8e4edad2477cd04c73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// A class representing an attempt to synchronize the local syncable data
// store with a sync server. A SyncSession instance is passed as a stateful
// bundle to and from various SyncerCommands with the goal of converging the
// client view of data with that of the server. The commands twiddle with
// session status in response to events and hiccups along the way, set and
// query session progress with regards to conflict resolution and applying
// server updates, and access the SyncSessionContext for the current session
// via SyncSession instances.

#ifndef CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_
#define CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_
#pragma once

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "chrome/browser/sync/engine/model_safe_worker.h"
#include "chrome/browser/sync/sessions/ordered_commit_set.h"
#include "chrome/browser/sync/sessions/session_state.h"
#include "chrome/browser/sync/sessions/status_controller.h"
#include "chrome/browser/sync/sessions/sync_session_context.h"
#include "chrome/browser/sync/syncable/model_type.h"
#include "chrome/browser/sync/util/extensions_activity_monitor.h"

namespace syncable {
class WriteTransaction;
}

namespace browser_sync {
class ModelSafeWorker;

namespace sessions {

class SyncSession {
 public:
  // The Delegate services events that occur during the session requiring an
  // explicit (and session-global) action, as opposed to events that are simply
  // recorded in per-session state.
  class Delegate {
   public:
    // The client was throttled and should cease-and-desist syncing activity
    // until the specified time.
    virtual void OnSilencedUntil(const base::TimeTicks& silenced_until) = 0;

    // Silenced intervals can be out of phase with individual sessions, so the
    // delegate is the only thing that can give an authoritative answer for
    // "is syncing silenced right now". This shouldn't be necessary very often
    // as the delegate ensures no session is started if syncing is silenced.
    // ** Note **  This will return true if silencing commenced during this
    // session and the interval has not yet elapsed, but the contract here is
    // solely based on absolute time values. So, this cannot be used to infer
    // that any given session _instance_ is silenced.  An example of reasonable
    // use is for UI reporting.
    virtual bool IsSyncingCurrentlySilenced() = 0;

    // The client has been instructed to change its short poll interval.
    virtual void OnReceivedShortPollIntervalUpdate(
        const base::TimeDelta& new_interval) = 0;

    // The client has been instructed to change its long poll interval.
    virtual void OnReceivedLongPollIntervalUpdate(
        const base::TimeDelta& new_interval) = 0;

    // The client needs to cease and desist syncing at once.  This occurs when
    // the Syncer detects that the backend store has fundamentally changed or
    // is a different instance altogether (e.g. swapping from a test instance
    // to production, or a global stop syncing operation has wiped the store).
    virtual void OnShouldStopSyncingPermanently() = 0;

   protected:
    virtual ~Delegate() {}
  };

  SyncSession(SyncSessionContext* context,
              Delegate* delegate,
              const SyncSourceInfo& source,
              const ModelSafeRoutingInfo& routing_info,
              const std::vector<ModelSafeWorker*>& workers);
  ~SyncSession();

  // Builds a thread-safe and read-only copy of the current session state.
  SyncSessionSnapshot TakeSnapshot() const;

  // Returns true if this session contains data that should go through the sync
  // engine again.
  bool HasMoreToSync() const;

  // Collects all state pertaining to how and why |s| originated and unions it
  // with corresponding state in |this|, leaving |s| unchanged.  Allows |this|
  // to take on the responsibilities |s| had (e.g. certain data types) in the
  // next SyncShare operation using |this|, rather than needed two separate
  // sessions.
  void Coalesce(const SyncSession& session);

  // Should be called any time |this| is being re-used in a new call to
  // SyncShare (e.g., HasMoreToSync returned true).
  void ResetTransientState();

  SyncSessionContext* context() const { return context_; }
  Delegate* delegate() const { return delegate_; }
  syncable::WriteTransaction* write_transaction() { return write_transaction_; }
  StatusController* status_controller() { return status_controller_.get(); }

  const ExtensionsActivityMonitor::Records& extensions_activity() const {
    return extensions_activity_;
  }
  ExtensionsActivityMonitor::Records* mutable_extensions_activity() {
    return &extensions_activity_;
  }

  // Volatile reader for the source member of the sync session object.  The
  // value is set to the SYNC_CYCLE_CONTINUATION value to signal that it has
  // been read.
  SyncSourceInfo TestAndSetSource();

  const std::vector<ModelSafeWorker*>& workers() const { return workers_; }
  const ModelSafeRoutingInfo& routing_info() const { return routing_info_; }
  const SyncSourceInfo& source() const { return source_; }

 private:
  // Extend the encapsulation boundary to utilities for internal member
  // assignments. This way, the scope of these actions is explicit, they can't
  // be overridden, and assigning is always accompanied by unassigning.
  friend class ScopedSetSessionWriteTransaction;

  // The context for this session, guaranteed to outlive |this|.
  SyncSessionContext* const context_;

  // The source for initiating this sync session.
  SyncSourceInfo source_;

  // Information about extensions activity since the last successful commit.
  ExtensionsActivityMonitor::Records extensions_activity_;

  // Used to allow various steps to share a transaction. Can be NULL.
  syncable::WriteTransaction* write_transaction_;

  // The delegate for this session, must never be NULL.
  Delegate* delegate_;

  // Our controller for various status and error counters.
  scoped_ptr<StatusController> status_controller_;

  // The set of active ModelSafeWorkers for the duration of this session.
  // This can change if this session is Coalesce()'d with another.
  std::vector<ModelSafeWorker*> workers_;

  // The routing info for the duration of this session, dictating which
  // datatypes should be synced and which workers should be used when working
  // on those datatypes.
  ModelSafeRoutingInfo routing_info_;

  DISALLOW_COPY_AND_ASSIGN(SyncSession);
};

// Installs a WriteTransaction to a given session and later clears it when the
// utility falls out of scope. Transactions are not nestable, so it is an error
// to try and use one of these if the session already has a transaction.
class ScopedSetSessionWriteTransaction {
 public:
  ScopedSetSessionWriteTransaction(SyncSession* session,
                                   syncable::WriteTransaction* trans)
      : session_(session) {
    DCHECK(!session_->write_transaction_);
    session_->write_transaction_ = trans;
  }
  ~ScopedSetSessionWriteTransaction() { session_->write_transaction_ = NULL; }

 private:
  SyncSession* session_;
  DISALLOW_COPY_AND_ASSIGN(ScopedSetSessionWriteTransaction);
};

}  // namespace sessions
}  // namespace browser_sync

#endif  // CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_H_