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 53f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/profile_sync_service_harness.h" 63f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <stddef.h> 83f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <algorithm> 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <iterator> 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <ostream> 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <set> 123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <vector> 133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/logging.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/message_loop.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/task.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/tracked.h" 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 20513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/sync/sessions/session_state.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/signin_manager.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing browser_sync::sessions::SyncSessionSnapshot; 24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// The amount of time for which we wait for a live sync operation to complete. 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const int kLiveSyncOperationTimeoutMs = 45000; 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Simple class to implement a timeout using PostDelayedTask. If it is not 29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// aborted before picked up by a message queue, then it asserts with the message 30513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// provided. This class is not thread safe. 31513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass StateChangeTimeoutEvent 32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : public base::RefCountedThreadSafe<StateChangeTimeoutEvent> { 33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch public: 34513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch StateChangeTimeoutEvent(ProfileSyncServiceHarness* caller, 35513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& message); 36513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The entry point to the class from PostDelayedTask. 38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void Callback(); 39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 40513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Cancels the actions of the callback. Returns true if success, false 41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // if the callback has already timed out. 42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool Abort(); 43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch private: 45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch friend class base::RefCountedThreadSafe<StateChangeTimeoutEvent>; 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ~StateChangeTimeoutEvent(); 48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool aborted_; 50513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool did_timeout_; 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Due to synchronization of the IO loop, the caller will always be alive 53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // if the class is not aborted. 54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ProfileSyncServiceHarness* caller_; 55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Informative message to assert in the case of a timeout. 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string message_; 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DISALLOW_COPY_AND_ASSIGN(StateChangeTimeoutEvent); 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 62513209b27ff55e2841eac0e4120199c23acce758Ben MurdochStateChangeTimeoutEvent::StateChangeTimeoutEvent( 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ProfileSyncServiceHarness* caller, 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& message) 65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : aborted_(false), did_timeout_(false), caller_(caller), message_(message) { 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 68513209b27ff55e2841eac0e4120199c23acce758Ben MurdochStateChangeTimeoutEvent::~StateChangeTimeoutEvent() { 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid StateChangeTimeoutEvent::Callback() { 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!aborted_) { 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!caller_->RunStateChangeMachine()) { 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Report the message. 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch did_timeout_ = true; 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(!aborted_) << message_; 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch caller_->SignalStateComplete(); 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool StateChangeTimeoutEvent::Abort() { 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch aborted_ = true; 84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch caller_ = NULL; 85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return !did_timeout_; 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 88513209b27ff55e2841eac0e4120199c23acce758Ben MurdochProfileSyncServiceHarness::ProfileSyncServiceHarness( 89513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Profile* profile, 90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& username, 91513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& password, 92513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int id) 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : waiting_for_encryption_type_(syncable::UNSPECIFIED), 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen wait_state_(INITIAL_WAIT_STATE), 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch profile_(profile), 96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service_(NULL), 973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen timestamp_match_partner_(NULL), 98513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch username_(username), 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch password_(password), 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch id_(id) { 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (IsSyncAlreadySetup()) { 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service_ = profile_->GetProfileSyncService(); 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service_->AddObserver(this); 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = FULLY_SYNCED; 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 109513209b27ff55e2841eac0e4120199c23acce758Ben MurdochProfileSyncServiceHarness* ProfileSyncServiceHarness::CreateAndAttach( 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Profile* profile) { 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!profile->HasProfileSyncService()) { 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED() << "Profile has never signed into sync."; 113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NULL; 114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return new ProfileSyncServiceHarness(profile, "", "", 0); 116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 118513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::SetCredentials(const std::string& username, 119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& password) { 120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch username_ = username; 121513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch password_ = password; 122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 124513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::IsSyncAlreadySetup() { 125513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return profile_->HasProfileSyncService(); 126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 127513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 128513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::SetupSync() { 129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeSet synced_datatypes; 130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (int i = syncable::FIRST_REAL_MODEL_TYPE; 131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i < syncable::MODEL_TYPE_COUNT; ++i) { 132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch synced_datatypes.insert(syncable::ModelTypeFromInt(i)); 133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return SetupSync(synced_datatypes); 135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 137513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::SetupSync( 138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const syncable::ModelTypeSet& synced_datatypes) { 139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Initialize the sync client's profile sync service object. 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen service_ = profile_->GetProfileSyncService(""); 141513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (service_ == NULL) { 142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "SetupSync(): service_ is null."; 143513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Subscribe sync client to notifications from the profile sync service. 147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!service_->HasObserver(this)) 148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service_->AddObserver(this); 149513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Authenticate sync client using GAIA credentials. 151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service_->signin()->StartSignIn(username_, password_, "", ""); 152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Wait for the OnBackendInitialized() callback. 154513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = WAITING_FOR_ON_BACKEND_INITIALIZED; 155513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, 156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Waiting for OnBackendInitialized().")) { 157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "OnBackendInitialized() not seen after " 158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << kLiveSyncOperationTimeoutMs / 1000 159513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " seconds."; 160513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 163513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Choose the datatypes to be synced. If all datatypes are to be synced, 164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // set sync_everything to true; otherwise, set it to false. 165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool sync_everything = (synced_datatypes.size() == 166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (syncable::MODEL_TYPE_COUNT - syncable::FIRST_REAL_MODEL_TYPE)); 167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->OnUserChoseDatatypes(sync_everything, synced_datatypes); 168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Wait for initial sync cycle to be completed. 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(wait_state_, WAITING_FOR_INITIAL_SYNC); 171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, 172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Waiting for initial sync cycle to complete.")) { 173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Initial sync cycle did not complete after " 174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << kLiveSyncOperationTimeoutMs / 1000 175513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " seconds."; 176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Indicate to the browser that sync setup is complete. 180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->SetSyncSetupCompleted(); 181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 182513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 185513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::SignalStateCompleteWithNextState( 186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch WaitState next_state) { 187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = next_state; 188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SignalStateComplete(); 189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 191513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::SignalStateComplete() { 192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MessageLoop::current()->Quit(); 193513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 195513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::RunStateChangeMachine() { 196513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch WaitState original_wait_state = wait_state_; 197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch switch (wait_state_) { 198513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case WAITING_FOR_ON_BACKEND_INITIALIZED: { 199513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("WAITING_FOR_ON_BACKEND_INITIALIZED"); 200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (service()->sync_initialized()) { 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The sync backend is initialized. 202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SignalStateCompleteWithNextState(WAITING_FOR_INITIAL_SYNC); 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch break; 205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case WAITING_FOR_INITIAL_SYNC: { 207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("WAITING_FOR_INITIAL_SYNC"); 208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (IsSynced()) { 209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The first sync cycle is now complete. We can start running tests. 210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SignalStateCompleteWithNextState(FULLY_SYNCED); 211513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case WAITING_FOR_SYNC_TO_FINISH: { 215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("WAITING_FOR_SYNC_TO_FINISH"); 216513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!IsSynced()) { 217513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The client is not yet fully synced. Continue waiting. 218513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!GetStatus().server_reachable) { 219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The client cannot reach the sync server because the network is 220513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // disabled. There is no need to wait anymore. 221513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SignalStateCompleteWithNextState(SERVER_UNREACHABLE); 222513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 223513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 224513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 225513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SignalStateCompleteWithNextState(FULLY_SYNCED); 226513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 227513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 228513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case WAITING_FOR_UPDATES: { 229513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("WAITING_FOR_UPDATES"); 2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(timestamp_match_partner_); 2313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!MatchesOtherClient(timestamp_match_partner_)) { 2323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // The client is not yet fully synced; keep waiting until we converge. 233513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 234513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 2353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen timestamp_match_partner_->service()->RemoveObserver(this); 2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen timestamp_match_partner_ = NULL; 2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 238513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SignalStateCompleteWithNextState(FULLY_SYNCED); 239513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 240513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case WAITING_FOR_PASSPHRASE_ACCEPTED: { 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LogClientInfo("WAITING_FOR_PASSPHRASE_ACCEPTED"); 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(atwilson): After ProfileSyncService::OnPassphraseAccepted() is 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fixed, add an extra check to make sure that the value of 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // service()->observed_passphrase_required() is false. 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (service()->ShouldPushChanges()) { 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The passphrase has been accepted, and sync has been restarted. 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SignalStateCompleteWithNextState(FULLY_SYNCED); 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case WAITING_FOR_ENCRYPTION: { 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LogClientInfo("WAITING_FOR_ENCRYPTION"); 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (IsTypeEncrypted(waiting_for_encryption_type_)) { 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Encryption is complete for the type we are waiting on. 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SignalStateCompleteWithNextState(FULLY_SYNCED); 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 260513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case SERVER_UNREACHABLE: { 261513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("SERVER_UNREACHABLE"); 262513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (GetStatus().server_reachable) { 263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The client was offline due to the network being disabled, but is now 264513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // back online. Wait for the pending sync cycle to complete. 265513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SignalStateCompleteWithNextState(WAITING_FOR_SYNC_TO_FINISH); 266513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 267513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case FULLY_SYNCED: { 270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The client is online and fully synced. There is nothing to do. 271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("FULLY_SYNCED"); 272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case SYNC_DISABLED: { 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Syncing is disabled for the client. There is nothing to do. 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("SYNC_DISABLED"); 277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch default: 280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Invalid state during observer callback which may be triggered by other 281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // classes using the the UI message loop. Defer to their handling. 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return original_wait_state != wait_state_; 285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 287513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::OnStateChanged() { 288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RunStateChangeMachine(); 289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 291513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::AwaitPassphraseAccepted() { 292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("AwaitPassphraseAccepted"); 293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (wait_state_ == SYNC_DISABLED) { 294513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Sync disabled for Client " << id_ << "."; 295513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(atwilson): After ProfileSyncService::OnPassphraseAccepted() is 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fixed, add an extra check to make sure that the value of 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // service()->observed_passphrase_required() is false. 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (service()->ShouldPushChanges()) { 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Passphrase is already accepted; don't wait. 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 306513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = WAITING_FOR_PASSPHRASE_ACCEPTED; 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, 308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Waiting for passphrase accepted."); 309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 311513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::AwaitSyncCycleCompletion( 312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& reason) { 313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("AwaitSyncCycleCompletion"); 314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (wait_state_ == SYNC_DISABLED) { 315513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Sync disabled for Client " << id_ << "."; 316513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 317513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (IsSynced()) { 320513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Client is already synced; don't wait. 321513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 322513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (wait_state_ == SERVER_UNREACHABLE) { 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Client was offline; wait for it to go online, and then wait for sync. 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(wait_state_, WAITING_FOR_SYNC_TO_FINISH); 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(service()->sync_initialized()); 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wait_state_ = WAITING_FOR_SYNC_TO_FINISH; 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (wait_state_ == FULLY_SYNCED) { 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Client is online; sync was successful. 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (wait_state_ == SERVER_UNREACHABLE) { 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Client is offline; sync was unsuccessful. 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "Invalid wait state:" << wait_state_; 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 345513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 346513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( 347513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ProfileSyncServiceHarness* partner) { 348513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("AwaitMutualSyncCycleCompletion"); 349513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) 350513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 3513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return partner->WaitUntilTimestampMatches(this, 352513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Sync cycle completion on passive client."); 353513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 354513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 355513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion( 356513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::vector<ProfileSyncServiceHarness*>& partners) { 357513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("AwaitGroupSyncCycleCompletion"); 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) 359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool return_value = true; 361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::vector<ProfileSyncServiceHarness*>::iterator it = 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch partners.begin(); it != partners.end(); ++it) { 363513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if ((this != *it) && ((*it)->wait_state_ != SYNC_DISABLED)) { 364513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return_value = return_value && 3653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen (*it)->WaitUntilTimestampMatches(this, 366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Sync cycle completion on partner client."); 367513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 368513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 369513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return return_value; 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::AwaitQuiescence( 374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::vector<ProfileSyncServiceHarness*>& clients) { 375513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "AwaitQuiescence."; 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool return_value = true; 377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::vector<ProfileSyncServiceHarness*>::iterator it = 378513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch clients.begin(); it != clients.end(); ++it) { 379513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if ((*it)->wait_state_ != SYNC_DISABLED) 380513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return_value = return_value && 381513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (*it)->AwaitGroupSyncCycleCompletion(clients); 382513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 383513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return return_value; 384513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 385513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 3863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool ProfileSyncServiceHarness::WaitUntilTimestampMatches( 3873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ProfileSyncServiceHarness* partner, const std::string& reason) { 3883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LogClientInfo("WaitUntilTimestampMatches"); 389513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (wait_state_ == SYNC_DISABLED) { 390513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Sync disabled for Client " << id_ << "."; 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 392513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (MatchesOtherClient(partner)) { 395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Timestamps already match; don't wait. 396513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 3983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!timestamp_match_partner_); 4003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen timestamp_match_partner_ = partner; 4013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen partner->service()->AddObserver(this); 4023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen wait_state_ = WAITING_FOR_UPDATES; 4033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 404513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 405513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 406513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::AwaitStatusChangeWithTimeout( 407513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int timeout_milliseconds, 408513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& reason) { 409513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("AwaitStatusChangeWithTimeout"); 410513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (wait_state_ == SYNC_DISABLED) { 411513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Sync disabled for Client " << id_ << "."; 412513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 413513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<StateChangeTimeoutEvent> timeout_signal( 415513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new StateChangeTimeoutEvent(this, reason)); 416513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MessageLoop* loop = MessageLoop::current(); 417513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool did_allow_nestable_tasks = loop->NestableTasksAllowed(); 418513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch loop->SetNestableTasksAllowed(true); 419513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch loop->PostDelayedTask( 420513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FROM_HERE, 421513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NewRunnableMethod(timeout_signal.get(), 422513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &StateChangeTimeoutEvent::Callback), 423513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch timeout_milliseconds); 424513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch loop->Run(); 425513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch loop->SetNestableTasksAllowed(did_allow_nestable_tasks); 4263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (timeout_signal->Abort()) { 4273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LogClientInfo("AwaitStatusChangeWithTimeout succeeded"); 4283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return true; 4293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 4303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LogClientInfo("AwaitStatusChangeWithTimeout timed out"); 4313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return false; 4323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 433513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 434513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 435513209b27ff55e2841eac0e4120199c23acce758Ben MurdochProfileSyncService::Status ProfileSyncServiceHarness::GetStatus() { 436513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(service() != NULL) << "GetStatus(): service() is NULL."; 437513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return service()->QueryDetailedSyncStatus(); 438513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 439513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 440513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool ProfileSyncServiceHarness::IsSynced() { 441201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LogClientInfo("IsSynced"); 442513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (service() == NULL) 443513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 444513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); 445513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // TODO(rsimha): Remove additional checks of snap->has_more_to_sync and 446513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // snap->unsynced_count once http://crbug.com/48989 is fixed. 447513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return (snap && 4484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch snap->num_conflicting_updates == 0 && // We can decrypt everything. 449513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ServiceIsPushingChanges() && 450513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GetStatus().notifications_enabled && 45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !service()->HasUnsyncedItems() && 452513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !snap->has_more_to_sync && 453513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch snap->unsynced_count == 0); 454513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 455513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 4563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool ProfileSyncServiceHarness::MatchesOtherClient( 4573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ProfileSyncServiceHarness* partner) { 4583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!IsSynced()) 4593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return false; 4603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 4613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Only look for a match if we have at least one enabled datatype in 4623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // common with the partner client. 4633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen syncable::ModelTypeSet types, other_types, intersection_types; 4643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen service()->GetPreferredDataTypes(&types); 4653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen partner->service()->GetPreferredDataTypes(&other_types); 4663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::set_intersection(types.begin(), types.end(), other_types.begin(), 4673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen other_types.end(), 4683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen inserter(intersection_types, 4693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen intersection_types.begin())); 47072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (syncable::ModelTypeSet::iterator i = intersection_types.begin(); 47172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen i != intersection_types.end(); 47272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ++i) { 47372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!partner->IsSynced() || 47472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen partner->GetUpdatedTimestamp(*i) != GetUpdatedTimestamp(*i)) { 47572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 47672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 4773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 47872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 4793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 4803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 481513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst SyncSessionSnapshot* 482513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ProfileSyncServiceHarness::GetLastSessionSnapshot() const { 483513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(service_ != NULL) << "Sync service has not yet been set up."; 48472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (service_->sync_initialized()) { 48572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return service_->GetLastSessionSnapshot(); 486513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 487513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NULL; 488513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 490513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::EnableSyncForDatatype( 491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelType datatype) { 492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("EnableSyncForDatatype"); 493513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeSet synced_datatypes; 494513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (wait_state_ == SYNC_DISABLED) { 495513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = WAITING_FOR_ON_BACKEND_INITIALIZED; 496513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch synced_datatypes.insert(datatype); 497513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(SetupSync(synced_datatypes)) << "Reinitialization of Client " << id_ 498513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " failed."; 499513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 500513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(service() != NULL) << "EnableSyncForDatatype(): service() is null."; 501513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->GetPreferredDataTypes(&synced_datatypes); 502513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeSet::iterator it = synced_datatypes.find( 503513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeFromInt(datatype)); 504513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (it == synced_datatypes.end()) { 505513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch synced_datatypes.insert(syncable::ModelTypeFromInt(datatype)); 506513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->OnUserChoseDatatypes(false, synced_datatypes); 507513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = WAITING_FOR_SYNC_TO_FINISH; 508513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch AwaitSyncCycleCompletion("Waiting for datatype configuration."); 509513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "EnableSyncForDatatype(): Enabled sync for datatype " 510513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << syncable::ModelTypeToString(datatype) << " on Client " << id_; 511513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 512513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "EnableSyncForDatatype(): Sync already enabled for datatype " 513513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << syncable::ModelTypeToString(datatype) << " on Client " << id_; 514513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 515513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 516513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 517513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 518513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::DisableSyncForDatatype( 519513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelType datatype) { 520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("DisableSyncForDatatype"); 521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeSet synced_datatypes; 522513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(service() != NULL) << "DisableSyncForDatatype(): service() is null."; 523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->GetPreferredDataTypes(&synced_datatypes); 524513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeSet::iterator it = synced_datatypes.find(datatype); 525513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (it != synced_datatypes.end()) { 526513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch synced_datatypes.erase(it); 527513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->OnUserChoseDatatypes(false, synced_datatypes); 528513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch AwaitSyncCycleCompletion("Waiting for datatype configuration."); 529513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "DisableSyncForDatatype(): Disabled sync for datatype " 530513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << syncable::ModelTypeToString(datatype) << " on Client " << id_; 531513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 532513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "DisableSyncForDatatype(): Sync already disabled for datatype " 533513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << syncable::ModelTypeToString(datatype) << " on Client " << id_; 534513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 535513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 536513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 537513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::EnableSyncForAllDatatypes() { 538513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("EnableSyncForAllDatatypes"); 539513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (wait_state_ == SYNC_DISABLED) { 540513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = WAITING_FOR_ON_BACKEND_INITIALIZED; 541513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(SetupSync()) << "Reinitialization of Client " << id_ << " failed."; 542513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 543513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch syncable::ModelTypeSet synced_datatypes; 544513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (int i = syncable::FIRST_REAL_MODEL_TYPE; 545513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i < syncable::MODEL_TYPE_COUNT; ++i) { 546513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch synced_datatypes.insert(syncable::ModelTypeFromInt(i)); 547513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 548513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(service() != NULL) << "EnableSyncForAllDatatypes(): service() is " 549513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch " null."; 550513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->OnUserChoseDatatypes(true, synced_datatypes); 551513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = WAITING_FOR_SYNC_TO_FINISH; 552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch AwaitSyncCycleCompletion("Waiting for datatype configuration."); 553513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "EnableSyncForAllDatatypes(): Enabled sync for all datatypes on " 554513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Client " << id_; 555513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 556513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 557513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 558513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ProfileSyncServiceHarness::DisableSyncForAllDatatypes() { 559513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LogClientInfo("DisableSyncForAllDatatypes"); 560513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(service() != NULL) << "EnableSyncForAllDatatypes(): service() is " 561513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "null."; 562513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch service()->DisableForUser(); 563513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wait_state_ = SYNC_DISABLED; 564513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "DisableSyncForAllDatatypes(): Disabled sync for all datatypes on " 565513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "Client " << id_; 566513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 567513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstd::string ProfileSyncServiceHarness::GetUpdatedTimestamp( 56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen syncable::ModelType model_type) { 570513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); 571513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(snap != NULL) << "GetUpdatedTimestamp(): Sync snapshot is NULL."; 57272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return snap->download_progress_markers[model_type]; 573513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 574513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileSyncServiceHarness::LogClientInfo(const std::string& message) { 576513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (service()) { 577513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); 578513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (snap) { 579513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Client " << id_ << ": " << message 58072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << ": num_updates_downloaded : " 58172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << snap->syncer_status.num_updates_downloaded_total 582513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ", has_more_to_sync: " << snap->has_more_to_sync 583513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ", unsynced_count: " << snap->unsynced_count 584201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << ", num_conflicting_updates: " << snap->num_conflicting_updates 585513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ", has_unsynced_items: " 58672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << service()->HasUnsyncedItems() 587201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << ", observed_passphrase_required: " 588201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << service()->observed_passphrase_required() 589513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ", notifications_enabled: " 590513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << GetStatus().notifications_enabled 591513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ", service_is_pushing_changes: " << ServiceIsPushingChanges(); 592513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 593513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Client " << id_ << ": " << message 594513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ": Sync session snapshot not available."; 595513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 596513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 597513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Client " << id_ << ": " << message 598513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << ": Sync service not available."; 599513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 600513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 601dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 602dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ProfileSyncServiceHarness::EnableEncryptionForType( 603dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen syncable::ModelType type) { 604dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen syncable::ModelTypeSet encrypted_types; 605dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen service_->GetEncryptedDataTypes(&encrypted_types); 606dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (encrypted_types.count(type) > 0) 607dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 608dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen encrypted_types.insert(type); 609dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen service_->EncryptDataTypes(encrypted_types); 610dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 611dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Wait some time to let the enryption finish. 612dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string reason = "Waiting for encryption."; 613dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(FULLY_SYNCED, wait_state_); 614dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen wait_state_ = WAITING_FOR_ENCRYPTION; 615dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen waiting_for_encryption_type_ = type; 616dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason)) { 617dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(ERROR) << "Did not receive EncryptionComplete notification after" 618dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << kLiveSyncOperationTimeoutMs / 1000 619dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " seconds."; 620dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 621dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 622dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 623dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return IsTypeEncrypted(type); 624dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 625dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 626dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ProfileSyncServiceHarness::IsTypeEncrypted(syncable::ModelType type) { 627dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen syncable::ModelTypeSet encrypted_types; 628dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen service_->GetEncryptedDataTypes(&encrypted_types); 629dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (encrypted_types.count(type) == 0) { 630dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 631dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 632dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 633dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 634