1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// found in the LICENSE file.
4513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
5513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#ifndef CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_
6513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_
7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#pragma once
8513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
9513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <string>
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <vector>
11513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/basictypes.h"
13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/sync/profile_sync_service.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/profile_sync_service_observer.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/syncable/model_type.h"
16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
17513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass Profile;
18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace browser_sync {
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  namespace sessions {
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    struct SyncSessionSnapshot;
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// An instance of this class is basically our notion of a "sync client" for
26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// automation purposes. It harnesses the ProfileSyncService member of the
27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// profile passed to it on construction and automates certain things like setup
28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// and authentication. It provides ways to "wait" adequate periods of time for
29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// several clients to get to the same state.
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch public:
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ProfileSyncServiceHarness(Profile* profile,
33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                            const std::string& username,
34513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                            const std::string& password,
35513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                            int id);
36513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual ~ProfileSyncServiceHarness() {}
38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Creates a ProfileSyncServiceHarness object and attaches it to |profile|, a
40513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // profile that is assumed to have been signed into sync in the past. Caller
41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // takes ownership.
42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static ProfileSyncServiceHarness* CreateAndAttach(Profile* profile);
43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Sets the GAIA credentials with which to sign in to sync.
45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void SetCredentials(const std::string& username, const std::string& password);
46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Returns true if sync has been enabled on |profile_|.
48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool IsSyncAlreadySetup();
49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
50513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Creates a ProfileSyncService for the profile passed at construction and
51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // enables sync for all available datatypes. Returns true only after sync has
52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // been fully initialized and authenticated, and we are ready to process
53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // changes.
54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool SetupSync();
55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Same as the above method, but enables sync only for the datatypes contained
57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // in |synced_datatypes|.
58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool SetupSync(const syncable::ModelTypeSet& synced_datatypes);
59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // ProfileSyncServiceObserver implementation.
61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void OnStateChanged();
62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Blocks the caller until this harness has completed a single sync cycle
64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // since the previous one.  Returns true if a sync cycle has completed.
65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool AwaitSyncCycleCompletion(const std::string& reason);
66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Blocks the caller until this harness has observed that the sync engine
683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // has downloaded all the changes seen by the |partner| harness's client.
693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool WaitUntilTimestampMatches(
703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncServiceHarness* partner, const std::string& reason);
71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Calling this acts as a barrier and blocks the caller until |this| and
73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // |partner| have both completed a sync cycle.  When calling this method,
74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // the |partner| should be the passive responder who responds to the actions
75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // of |this|.  This method relies upon the synchronization of callbacks
76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // from the message queue. Returns true if two sync cycles have completed.
77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Note: Use this method when exactly one client makes local change(s), and
78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // exactly one client is waiting to receive those changes.
79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool AwaitMutualSyncCycleCompletion(ProfileSyncServiceHarness* partner);
80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Blocks the caller until |this| completes its ongoing sync cycle and every
823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // other client in |partners| have achieved identical download progresses.
833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Note: Use this method when exactly one client makes local change(s),
843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // and more than one client is waiting to receive those changes.
85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool AwaitGroupSyncCycleCompletion(
86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      std::vector<ProfileSyncServiceHarness*>& partners);
87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
88513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Blocks the caller until every client in |clients| completes its ongoing
89513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // sync cycle and all the clients' timestamps match.  Note: Use this method
90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // when more than one client makes local change(s), and more than one client
91513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // is waiting to receive those changes.
92513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static bool AwaitQuiescence(
93513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      std::vector<ProfileSyncServiceHarness*>& clients);
94513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // If a SetPassphrase call has been issued with a valid passphrase, this
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // will wait until the passphrase has been accepted.
97513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool AwaitPassphraseAccepted();
98513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Returns the ProfileSyncService member of the the sync client.
100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ProfileSyncService* service() { return service_; }
101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Returns the status of the ProfileSyncService member of the the sync client.
103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ProfileSyncService::Status GetStatus();
104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // See ProfileSyncService::ShouldPushChanges().
106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool ServiceIsPushingChanges() { return service_->ShouldPushChanges(); }
107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Enables sync for a particular sync datatype.
109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void EnableSyncForDatatype(syncable::ModelType datatype);
110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Disables sync for a particular sync datatype.
112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void DisableSyncForDatatype(syncable::ModelType datatype);
113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Enables sync for all sync datatypes.
115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void EnableSyncForAllDatatypes();
116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Disables sync for all sync datatypes.
118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void DisableSyncForAllDatatypes();
119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Returns a snapshot of the current sync session.
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const browser_sync::sessions::SyncSessionSnapshot*
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetLastSessionSnapshot() const;
123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Encrypt the datatype |type|. This method will block while the sync backend
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // host performs the encryption or a timeout is reached. Returns false if
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // encryption failed, else true.
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Note: this method does not currently support tracking encryption status
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // while other sync activities are being performed. Sync should be fully
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // synced when this is called.
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool EnableEncryptionForType(syncable::ModelType type);
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Check if |type| is encrypted.
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool IsTypeEncrypted(syncable::ModelType type);
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch private:
136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  friend class StateChangeTimeoutEvent;
137513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  enum WaitState {
139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client has just been initialized.
140513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    INITIAL_WAIT_STATE = 0,
141513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client awaits the OnBackendInitialized() callback.
143513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    WAITING_FOR_ON_BACKEND_INITIALIZED,
144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client is waiting for the first sync cycle to complete.
146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    WAITING_FOR_INITIAL_SYNC,
147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client is waiting for an ongoing sync cycle to complete.
149513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    WAITING_FOR_SYNC_TO_FINISH,
150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client anticipates incoming updates leading to a new sync cycle.
152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    WAITING_FOR_UPDATES,
153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The sync client is waiting for its passphrase to be accepted by the
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // cryptographer.
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WAITING_FOR_PASSPHRASE_ACCEPTED,
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // The sync client anticipates encryption of new datatypes.
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    WAITING_FOR_ENCRYPTION,
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client cannot reach the server.
162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    SERVER_UNREACHABLE,
163513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The sync client is fully synced and there are no pending updates.
165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    FULLY_SYNCED,
166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Syncing is disabled for the client.
168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    SYNC_DISABLED,
169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    NUMBER_OF_STATES,
171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  };
172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Called from the observer when the current wait state has been completed.
174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void SignalStateCompleteWithNextState(WaitState next_state);
175513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Indicates that the operation being waited on is complete.
177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void SignalStateComplete();
178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Finite state machine for controlling state.  Returns true only if a state
180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // change has taken place.
181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool RunStateChangeMachine();
182513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Returns true if a status change took place, false on timeout.
184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool AwaitStatusChangeWithTimeout(int timeout_milliseconds,
185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                    const std::string& reason);
186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Returns true if the sync client has no unsynced items.
188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool IsSynced();
189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns true if this client has downloaded all the items that the
1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // other client has.
1923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool MatchesOtherClient(ProfileSyncServiceHarness* partner);
1933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Logs message with relevant info about client's sync state (if available).
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void LogClientInfo(const std::string& message);
196513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Gets the current progress indicator of the current sync session
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // for a particular datatype.
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string GetUpdatedTimestamp(syncable::ModelType model_type);
200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // When in WAITING_FOR_ENCRYPTION state, we check to see if this type is now
202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // encrypted to determine if we're done.
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncable::ModelType waiting_for_encryption_type_;
204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
205513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  WaitState wait_state_;
206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  Profile* profile_;
208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ProfileSyncService* service_;
209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // The harness of the client whose update progress marker we're expecting
2113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // eventually match.
2123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ProfileSyncServiceHarness* timestamp_match_partner_;
213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Credentials used for GAIA authentication.
215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  std::string username_;
216513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  std::string password_;
217513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
218513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Client ID, used for logging purposes.
219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  int id_;
220513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
221513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceHarness);
222513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch};
223513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
224513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif  // CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_
225