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