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 #ifndef CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_ 6 #define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_ 7 #pragma once 8 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "chrome/browser/sync/profile_sync_service.h" 14 #include "chrome/browser/sync/profile_sync_service_observer.h" 15 #include "chrome/browser/sync/syncable/model_type.h" 16 17 class Profile; 18 19 namespace browser_sync { 20 namespace sessions { 21 struct SyncSessionSnapshot; 22 } 23 } 24 25 // An instance of this class is basically our notion of a "sync client" for 26 // automation purposes. It harnesses the ProfileSyncService member of the 27 // profile passed to it on construction and automates certain things like setup 28 // and authentication. It provides ways to "wait" adequate periods of time for 29 // several clients to get to the same state. 30 class ProfileSyncServiceHarness : public ProfileSyncServiceObserver { 31 public: 32 ProfileSyncServiceHarness(Profile* profile, 33 const std::string& username, 34 const std::string& password, 35 int id); 36 ~ProfileSyncServiceHarness()37 virtual ~ProfileSyncServiceHarness() {} 38 39 // Creates a ProfileSyncServiceHarness object and attaches it to |profile|, a 40 // profile that is assumed to have been signed into sync in the past. Caller 41 // takes ownership. 42 static ProfileSyncServiceHarness* CreateAndAttach(Profile* profile); 43 44 // Sets the GAIA credentials with which to sign in to sync. 45 void SetCredentials(const std::string& username, const std::string& password); 46 47 // Returns true if sync has been enabled on |profile_|. 48 bool IsSyncAlreadySetup(); 49 50 // Creates a ProfileSyncService for the profile passed at construction and 51 // enables sync for all available datatypes. Returns true only after sync has 52 // been fully initialized and authenticated, and we are ready to process 53 // changes. 54 bool SetupSync(); 55 56 // Same as the above method, but enables sync only for the datatypes contained 57 // in |synced_datatypes|. 58 bool SetupSync(const syncable::ModelTypeSet& synced_datatypes); 59 60 // ProfileSyncServiceObserver implementation. 61 virtual void OnStateChanged(); 62 63 // Blocks the caller until this harness has completed a single sync cycle 64 // since the previous one. Returns true if a sync cycle has completed. 65 bool AwaitSyncCycleCompletion(const std::string& reason); 66 67 // Blocks the caller until this harness has observed that the sync engine 68 // has downloaded all the changes seen by the |partner| harness's client. 69 bool WaitUntilTimestampMatches( 70 ProfileSyncServiceHarness* partner, const std::string& reason); 71 72 // Calling this acts as a barrier and blocks the caller until |this| and 73 // |partner| have both completed a sync cycle. When calling this method, 74 // the |partner| should be the passive responder who responds to the actions 75 // of |this|. This method relies upon the synchronization of callbacks 76 // from the message queue. Returns true if two sync cycles have completed. 77 // Note: Use this method when exactly one client makes local change(s), and 78 // exactly one client is waiting to receive those changes. 79 bool AwaitMutualSyncCycleCompletion(ProfileSyncServiceHarness* partner); 80 81 // Blocks the caller until |this| completes its ongoing sync cycle and every 82 // other client in |partners| have achieved identical download progresses. 83 // Note: Use this method when exactly one client makes local change(s), 84 // and more than one client is waiting to receive those changes. 85 bool AwaitGroupSyncCycleCompletion( 86 std::vector<ProfileSyncServiceHarness*>& partners); 87 88 // Blocks the caller until every client in |clients| completes its ongoing 89 // sync cycle and all the clients' timestamps match. Note: Use this method 90 // when more than one client makes local change(s), and more than one client 91 // is waiting to receive those changes. 92 static bool AwaitQuiescence( 93 std::vector<ProfileSyncServiceHarness*>& clients); 94 95 // If a SetPassphrase call has been issued with a valid passphrase, this 96 // will wait until the passphrase has been accepted. 97 bool AwaitPassphraseAccepted(); 98 99 // Returns the ProfileSyncService member of the the sync client. service()100 ProfileSyncService* service() { return service_; } 101 102 // Returns the status of the ProfileSyncService member of the the sync client. 103 ProfileSyncService::Status GetStatus(); 104 105 // See ProfileSyncService::ShouldPushChanges(). ServiceIsPushingChanges()106 bool ServiceIsPushingChanges() { return service_->ShouldPushChanges(); } 107 108 // Enables sync for a particular sync datatype. 109 void EnableSyncForDatatype(syncable::ModelType datatype); 110 111 // Disables sync for a particular sync datatype. 112 void DisableSyncForDatatype(syncable::ModelType datatype); 113 114 // Enables sync for all sync datatypes. 115 void EnableSyncForAllDatatypes(); 116 117 // Disables sync for all sync datatypes. 118 void DisableSyncForAllDatatypes(); 119 120 // Returns a snapshot of the current sync session. 121 const browser_sync::sessions::SyncSessionSnapshot* 122 GetLastSessionSnapshot() const; 123 124 // Encrypt the datatype |type|. This method will block while the sync backend 125 // host performs the encryption or a timeout is reached. Returns false if 126 // encryption failed, else true. 127 // Note: this method does not currently support tracking encryption status 128 // while other sync activities are being performed. Sync should be fully 129 // synced when this is called. 130 bool EnableEncryptionForType(syncable::ModelType type); 131 132 // Check if |type| is encrypted. 133 bool IsTypeEncrypted(syncable::ModelType type); 134 135 private: 136 friend class StateChangeTimeoutEvent; 137 138 enum WaitState { 139 // The sync client has just been initialized. 140 INITIAL_WAIT_STATE = 0, 141 142 // The sync client awaits the OnBackendInitialized() callback. 143 WAITING_FOR_ON_BACKEND_INITIALIZED, 144 145 // The sync client is waiting for the first sync cycle to complete. 146 WAITING_FOR_INITIAL_SYNC, 147 148 // The sync client is waiting for an ongoing sync cycle to complete. 149 WAITING_FOR_SYNC_TO_FINISH, 150 151 // The sync client anticipates incoming updates leading to a new sync cycle. 152 WAITING_FOR_UPDATES, 153 154 // The sync client is waiting for its passphrase to be accepted by the 155 // cryptographer. 156 WAITING_FOR_PASSPHRASE_ACCEPTED, 157 158 // The sync client anticipates encryption of new datatypes. 159 WAITING_FOR_ENCRYPTION, 160 161 // The sync client cannot reach the server. 162 SERVER_UNREACHABLE, 163 164 // The sync client is fully synced and there are no pending updates. 165 FULLY_SYNCED, 166 167 // Syncing is disabled for the client. 168 SYNC_DISABLED, 169 170 NUMBER_OF_STATES, 171 }; 172 173 // Called from the observer when the current wait state has been completed. 174 void SignalStateCompleteWithNextState(WaitState next_state); 175 176 // Indicates that the operation being waited on is complete. 177 void SignalStateComplete(); 178 179 // Finite state machine for controlling state. Returns true only if a state 180 // change has taken place. 181 bool RunStateChangeMachine(); 182 183 // Returns true if a status change took place, false on timeout. 184 bool AwaitStatusChangeWithTimeout(int timeout_milliseconds, 185 const std::string& reason); 186 187 // Returns true if the sync client has no unsynced items. 188 bool IsSynced(); 189 190 // Returns true if this client has downloaded all the items that the 191 // other client has. 192 bool MatchesOtherClient(ProfileSyncServiceHarness* partner); 193 194 // Logs message with relevant info about client's sync state (if available). 195 void LogClientInfo(const std::string& message); 196 197 // Gets the current progress indicator of the current sync session 198 // for a particular datatype. 199 std::string GetUpdatedTimestamp(syncable::ModelType model_type); 200 201 // When in WAITING_FOR_ENCRYPTION state, we check to see if this type is now 202 // encrypted to determine if we're done. 203 syncable::ModelType waiting_for_encryption_type_; 204 205 WaitState wait_state_; 206 207 Profile* profile_; 208 ProfileSyncService* service_; 209 210 // The harness of the client whose update progress marker we're expecting 211 // eventually match. 212 ProfileSyncServiceHarness* timestamp_match_partner_; 213 214 // Credentials used for GAIA authentication. 215 std::string username_; 216 std::string password_; 217 218 // Client ID, used for logging purposes. 219 int id_; 220 221 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceHarness); 222 }; 223 224 #endif // CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_ 225