blob: 383c7862aaaa685ad6778b3e083c3c8fba1121ef [file] [log] [blame]
// 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.
#ifndef CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_
#define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_
#pragma once
#include <string>
#include <vector>
#include "base/time.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
using browser_sync::sessions::SyncSessionSnapshot;
class Profile;
// An instance of this class is basically our notion of a "sync client" for
// automation purposes. It harnesses the ProfileSyncService member of the
// profile passed to it on construction and automates certain things like setup
// and authentication. It provides ways to "wait" adequate periods of time for
// several clients to get to the same state.
class ProfileSyncServiceHarness : public ProfileSyncServiceObserver,
public NotificationObserver {
public:
ProfileSyncServiceHarness(Profile* profile,
const std::string& username,
const std::string& password,
int id);
virtual ~ProfileSyncServiceHarness() {}
// Creates a ProfileSyncServiceHarness object and attaches it to |profile|, a
// profile that is assumed to have been signed into sync in the past. Caller
// takes ownership.
static ProfileSyncServiceHarness* CreateAndAttach(Profile* profile);
// Sets the GAIA credentials with which to sign in to sync.
void SetCredentials(const std::string& username, const std::string& password);
// Returns true if sync has been enabled on |profile_|.
bool IsSyncAlreadySetup();
// Creates a ProfileSyncService for the profile passed at construction and
// enables sync for all available datatypes. Returns true only after sync has
// been fully initialized and authenticated, and we are ready to process
// changes.
bool SetupSync();
// Same as the above method, but enables sync only for the datatypes contained
// in |synced_datatypes|.
bool SetupSync(const syncable::ModelTypeSet& synced_datatypes);
// ProfileSyncServiceObserver implementation.
virtual void OnStateChanged();
// NotificationObserver implementation.
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
// Blocks the caller until this harness has completed a single sync cycle
// since the previous one. Returns true if a sync cycle has completed.
bool AwaitSyncCycleCompletion(const std::string& reason);
// Blocks the caller until this harness has observed that the sync engine
// has "synced" up to at least the specified local timestamp.
bool WaitUntilTimestampIsAtLeast(int64 timestamp, const std::string& reason);
// Calling this acts as a barrier and blocks the caller until |this| and
// |partner| have both completed a sync cycle. When calling this method,
// the |partner| should be the passive responder who responds to the actions
// of |this|. This method relies upon the synchronization of callbacks
// from the message queue. Returns true if two sync cycles have completed.
// Note: Use this method when exactly one client makes local change(s), and
// exactly one client is waiting to receive those changes.
bool AwaitMutualSyncCycleCompletion(ProfileSyncServiceHarness* partner);
// Blocks the caller until |this| completes its ongoing sync cycle and every
// other client in |partners| has a timestamp that is greater than or equal to
// the timestamp of |this|. Note: Use this method when exactly one client
// makes local change(s), and more than one client is waiting to receive those
// changes.
bool AwaitGroupSyncCycleCompletion(
std::vector<ProfileSyncServiceHarness*>& partners);
// Blocks the caller until every client in |clients| completes its ongoing
// sync cycle and all the clients' timestamps match. Note: Use this method
// when more than one client makes local change(s), and more than one client
// is waiting to receive those changes.
static bool AwaitQuiescence(
std::vector<ProfileSyncServiceHarness*>& clients);
// If a SetPassphrase call has been issued with a valid passphrase, this
// will wait until the Cryptographer broadcasts SYNC_PASSPHRASE_ACCEPTED.
bool AwaitPassphraseAccepted();
// Returns the ProfileSyncService member of the the sync client.
ProfileSyncService* service() { return service_; }
// Returns the status of the ProfileSyncService member of the the sync client.
ProfileSyncService::Status GetStatus();
// See ProfileSyncService::ShouldPushChanges().
bool ServiceIsPushingChanges() { return service_->ShouldPushChanges(); }
// Enables sync for a particular sync datatype.
void EnableSyncForDatatype(syncable::ModelType datatype);
// Disables sync for a particular sync datatype.
void DisableSyncForDatatype(syncable::ModelType datatype);
// Enables sync for all sync datatypes.
void EnableSyncForAllDatatypes();
// Disables sync for all sync datatypes.
void DisableSyncForAllDatatypes();
// Returns a snapshot of the current sync session.
const SyncSessionSnapshot* GetLastSessionSnapshot() const;
private:
friend class StateChangeTimeoutEvent;
enum WaitState {
// The sync client has just been initialized.
INITIAL_WAIT_STATE = 0,
// The sync client awaits the OnBackendInitialized() callback.
WAITING_FOR_ON_BACKEND_INITIALIZED,
// The sync client is waiting for the first sync cycle to complete.
WAITING_FOR_INITIAL_SYNC,
// The sync client is waiting for an ongoing sync cycle to complete.
WAITING_FOR_SYNC_TO_FINISH,
// The sync client anticipates incoming updates leading to a new sync cycle.
WAITING_FOR_UPDATES,
// The sync client cannot reach the server.
SERVER_UNREACHABLE,
// The sync client is fully synced and there are no pending updates.
FULLY_SYNCED,
// Waiting for a set passphrase to be accepted by the cryptographer.
WAITING_FOR_PASSPHRASE_ACCEPTED,
// Syncing is disabled for the client.
SYNC_DISABLED,
NUMBER_OF_STATES,
};
// Called from the observer when the current wait state has been completed.
void SignalStateCompleteWithNextState(WaitState next_state);
// Indicates that the operation being waited on is complete.
void SignalStateComplete();
// Finite state machine for controlling state. Returns true only if a state
// change has taken place.
bool RunStateChangeMachine();
// Returns true if a status change took place, false on timeout.
bool AwaitStatusChangeWithTimeout(int timeout_milliseconds,
const std::string& reason);
// Returns true if the sync client has no unsynced items.
bool IsSynced();
// Logs message with relevant info about client's sync state (if available).
void LogClientInfo(std::string message);
// Updates |last_timestamp_| with the timestamp of the current sync session.
// Returns the new value of |last_timestamp_|.
int64 GetUpdatedTimestamp();
void StartObservingPassphraseAcceptance();
WaitState wait_state_;
Profile* profile_;
ProfileSyncService* service_;
// This value tracks the max sync timestamp (e.g. synced-to revision) inside
// the sync engine. It gets updated when a sync cycle ends and the session
// snapshot implies syncing is "done".
int64 last_timestamp_;
// The minimum value of the 'max_local_timestamp' member of a
// SyncSessionSnapshot we need to wait to observe in OnStateChanged when told
// to WaitUntilTimestampIsAtLeast(...).
int64 min_timestamp_needed_;
// Credentials used for GAIA authentication.
std::string username_;
std::string password_;
// A counter to track the number of await passphrase requests versus
// actual acceptances. Can go negative if #requests > #acceptances.
int passphrase_acceptance_counter_;
NotificationRegistrar registrar_;
// Client ID, used for logging purposes.
int id_;
DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceHarness);
};
#endif // CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_