1// Copyright (c) 2011 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.
4
5// SyncSessionContext encapsulates the contextual information and engine
6// components specific to a SyncSession. A context is accessible via
7// a SyncSession so that session SyncerCommands and parts of the engine have
8// a convenient way to access other parts. In this way it can be thought of as
9// the surrounding environment for the SyncSession. The components of this
10// environment are either valid or not valid for the entire context lifetime,
11// or they are valid for explicitly scoped periods of time by using Scoped
12// installation utilities found below. This means that the context assumes no
13// ownership whatsoever of any object that was not created by the context
14// itself.
15//
16// It can only be used from the SyncerThread.
17
18#ifndef CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_CONTEXT_H_
19#define CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_CONTEXT_H_
20#pragma once
21
22#include <string>
23
24#include "base/memory/scoped_ptr.h"
25#include "chrome/browser/sync/engine/model_safe_worker.h"
26#include "chrome/browser/sync/engine/syncer_types.h"
27
28namespace syncable {
29class DirectoryManager;
30}
31
32namespace browser_sync {
33
34class ConflictResolver;
35class ExtensionsActivityMonitor;
36class ModelSafeWorkerRegistrar;
37class ServerConnectionManager;
38
39// Default number of items a client can commit in a single message.
40static const int kDefaultMaxCommitBatchSize = 25;
41
42namespace sessions {
43class ScopedSessionContextConflictResolver;
44struct SyncSessionSnapshot;
45class TestScopedSessionEventListener;
46
47class SyncSessionContext {
48 public:
49  SyncSessionContext(ServerConnectionManager* connection_manager,
50                     syncable::DirectoryManager* directory_manager,
51                     ModelSafeWorkerRegistrar* model_safe_worker_registrar,
52                     const std::vector<SyncEngineEventListener*>& listeners);
53  ~SyncSessionContext();
54
55  ConflictResolver* resolver() { return resolver_; }
56  ServerConnectionManager* connection_manager() {
57    return connection_manager_;
58  }
59  syncable::DirectoryManager* directory_manager() {
60    return directory_manager_;
61  }
62  ModelSafeWorkerRegistrar* registrar() {
63    return registrar_;
64  }
65  ExtensionsActivityMonitor* extensions_monitor() {
66    return extensions_activity_monitor_;
67  }
68
69  // Talk notification status.
70  void set_notifications_enabled(bool enabled) {
71    notifications_enabled_ = enabled;
72  }
73  bool notifications_enabled() { return notifications_enabled_; }
74
75  // Account name, set once a directory has been opened.
76  void set_account_name(const std::string name) {
77    DCHECK(account_name_.empty());
78    account_name_ = name;
79  }
80  const std::string& account_name() { return account_name_; }
81
82  void set_max_commit_batch_size(int batch_size) {
83    max_commit_batch_size_ = batch_size;
84  }
85  int32 max_commit_batch_size() const { return max_commit_batch_size_; }
86
87  const ModelSafeRoutingInfo& previous_session_routing_info() const {
88    return previous_session_routing_info_;
89  }
90
91  void set_previous_session_routing_info(const ModelSafeRoutingInfo& info) {
92    previous_session_routing_info_ = info;
93  }
94
95  void NotifyListeners(const SyncEngineEvent& event) {
96    FOR_EACH_OBSERVER(SyncEngineEventListener, listeners_,
97                      OnSyncEngineEvent(event));
98  }
99
100 private:
101  // Rather than force clients to set and null-out various context members, we
102  // extend our encapsulation boundary to scoped helpers that take care of this
103  // once they are allocated. See definitions of these below.
104  friend class ScopedSessionContextConflictResolver;
105  friend class TestScopedSessionEventListener;
106
107  // This is installed by Syncer objects when needed and may be NULL.
108  ConflictResolver* resolver_;
109
110  ObserverList<SyncEngineEventListener> listeners_;
111
112  ServerConnectionManager* const connection_manager_;
113  syncable::DirectoryManager* const directory_manager_;
114
115  // A registrar of workers capable of processing work closures on a thread
116  // that is guaranteed to be safe for model modifications.
117  ModelSafeWorkerRegistrar* registrar_;
118
119  // We use this to stuff extensions activity into CommitMessages so the server
120  // can correlate commit traffic with extension-related bookmark mutations.
121  ExtensionsActivityMonitor* extensions_activity_monitor_;
122
123  // Kept up to date with talk events to determine whether notifications are
124  // enabled. True only if the notification channel is authorized and open.
125  bool notifications_enabled_;
126
127  // The name of the account being synced.
128  std::string account_name_;
129
130  // The server limits the number of items a client can commit in one batch.
131  int max_commit_batch_size_;
132
133  // Some routing info history to help us clean up types that get disabled
134  // by the user.
135  ModelSafeRoutingInfo previous_session_routing_info_;
136
137  // Cache of last session snapshot information.
138  scoped_ptr<sessions::SyncSessionSnapshot> previous_session_snapshot_;
139
140  DISALLOW_COPY_AND_ASSIGN(SyncSessionContext);
141};
142
143// Installs a ConflictResolver to a given session context for the lifetime of
144// the ScopedSessionContextConflictResolver.  There should never be more than
145// one ConflictResolver in the system, so it is an error to use this if the
146// context already has a resolver.
147class ScopedSessionContextConflictResolver {
148 public:
149  // Note: |context| and |resolver| should outlive |this|.
150  ScopedSessionContextConflictResolver(SyncSessionContext* context,
151                                       ConflictResolver* resolver)
152      : context_(context), resolver_(resolver) {
153    DCHECK(NULL == context->resolver_);
154    context->resolver_ = resolver;
155  }
156  ~ScopedSessionContextConflictResolver() {
157    context_->resolver_ = NULL;
158   }
159 private:
160  SyncSessionContext* context_;
161  ConflictResolver* resolver_;
162  DISALLOW_COPY_AND_ASSIGN(ScopedSessionContextConflictResolver);
163};
164
165}  // namespace sessions
166}  // namespace browser_sync
167
168#endif  // CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSION_CONTEXT_H_
169