| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" | 5 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" |
| 6 | 6 |
| 7 #include <cstddef> | 7 #include <cstddef> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <ostream> | 9 #include <ostream> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 #include "sync/internal_api/public/util/sync_string_conversions.h" | 42 #include "sync/internal_api/public/util/sync_string_conversions.h" |
| 43 | 43 |
| 44 #if defined(ENABLE_MANAGED_USERS) | 44 #if defined(ENABLE_MANAGED_USERS) |
| 45 #include "chrome/browser/managed_mode/managed_user_constants.h" | 45 #include "chrome/browser/managed_mode/managed_user_constants.h" |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 using syncer::sessions::SyncSessionSnapshot; | 48 using syncer::sessions::SyncSessionSnapshot; |
| 49 using invalidation::P2PInvalidationService; | 49 using invalidation::P2PInvalidationService; |
| 50 | 50 |
| 51 // The amount of time for which we wait for a sync operation to complete. | 51 // The amount of time for which we wait for a sync operation to complete. |
| 52 // TODO(sync): This timeout must eventually be made less than the default 45 |
| 53 // second timeout for integration tests so that in case a sync operation times |
| 54 // out, it is able to log a useful failure message before the test is killed. |
| 52 static const int kSyncOperationTimeoutMs = 45000; | 55 static const int kSyncOperationTimeoutMs = 45000; |
| 53 | 56 |
| 54 namespace { | 57 namespace { |
| 55 | 58 |
| 56 // Checks if a desired change in the state of the sync engine has taken place by | 59 // Checks if a desired change in the state of the sync engine has taken place by |
| 57 // running the callback passed to it. | 60 // running the callback passed to it. |
| 58 class CallbackStatusChecker : public StatusChangeChecker { | 61 class CallbackStatusChecker : public StatusChangeChecker { |
| 59 public: | 62 public: |
| 60 CallbackStatusChecker(base::Callback<bool()> callback, | 63 CallbackStatusChecker(base::Callback<bool()> callback, |
| 61 const std::string& source) | 64 const std::string& source) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 89 // Backend initialization is blocked by an auth error. | 92 // Backend initialization is blocked by an auth error. |
| 90 if (harness->HasAuthError()) | 93 if (harness->HasAuthError()) |
| 91 return true; | 94 return true; |
| 92 // Backend initialization is blocked by a failure to fetch Oauth2 tokens. | 95 // Backend initialization is blocked by a failure to fetch Oauth2 tokens. |
| 93 if (harness->service()->IsRetryingAccessTokenFetchForTest()) | 96 if (harness->service()->IsRetryingAccessTokenFetchForTest()) |
| 94 return true; | 97 return true; |
| 95 // Still waiting on backend initialization. | 98 // Still waiting on backend initialization. |
| 96 return false; | 99 return false; |
| 97 } | 100 } |
| 98 | 101 |
| 99 // Helper function which returns true if initial sync is complete, or if the | 102 // Helper function which returns true if sync setup is complete, or in case |
| 100 // initial sync is blocked for some reason. | 103 // it is blocked for some reason. |
| 101 bool DoneWaitingForInitialSync(const ProfileSyncServiceHarness* harness) { | 104 bool DoneWaitingForSyncSetup(const ProfileSyncServiceHarness* harness) { |
| 102 DCHECK(harness); | 105 DCHECK(harness); |
| 103 // Initial sync is complete. | 106 // Sync setup is complete, and the client is ready to sync new changes. |
| 104 if (harness->IsFullySynced()) | 107 if (harness->ServiceIsPushingChanges()) |
| 105 return true; | 108 return true; |
| 106 // Initial sync is blocked because custom passphrase is required. | 109 // Sync is blocked because a custom passphrase is required. |
| 107 if (harness->service()->passphrase_required_reason() == | 110 if (harness->service()->passphrase_required_reason() == |
| 108 syncer::REASON_DECRYPTION) { | 111 syncer::REASON_DECRYPTION) { |
| 109 return true; | 112 return true; |
| 110 } | 113 } |
| 111 // Initial sync is blocked by an auth error. | 114 // Sync is blocked by an auth error. |
| 112 if (harness->HasAuthError()) | 115 if (harness->HasAuthError()) |
| 113 return true; | 116 return true; |
| 114 // Still waiting on initial sync. | 117 // Still waiting on sync setup. |
| 115 return false; | 118 return false; |
| 116 } | 119 } |
| 117 | 120 |
| 118 // Helper function which returns true if the sync client is fully synced, or if | |
| 119 // sync is blocked for some reason. | |
| 120 bool DoneWaitingForFullSync(const ProfileSyncServiceHarness* harness) { | |
| 121 DCHECK(harness); | |
| 122 // Sync is complete. | |
| 123 if (harness->IsFullySynced()) | |
| 124 return true; | |
| 125 // Sync is blocked by an auth error. | |
| 126 if (harness->HasAuthError()) | |
| 127 return true; | |
| 128 // Sync is blocked by a failure to fetch Oauth2 tokens. | |
| 129 if (harness->service()->IsRetryingAccessTokenFetchForTest()) | |
| 130 return true; | |
| 131 // Still waiting on sync. | |
| 132 return false; | |
| 133 } | |
| 134 | |
| 135 // Helper function which returns true if the sync client requires a custom | 121 // Helper function which returns true if the sync client requires a custom |
| 136 // passphrase to be entered for decryption. | 122 // passphrase to be entered for decryption. |
| 137 bool IsPassphraseRequired(const ProfileSyncServiceHarness* harness) { | 123 bool IsPassphraseRequired(const ProfileSyncServiceHarness* harness) { |
| 138 DCHECK(harness); | 124 DCHECK(harness); |
| 139 return harness->service()->IsPassphraseRequired(); | 125 return harness->service()->IsPassphraseRequired(); |
| 140 } | 126 } |
| 141 | 127 |
| 142 // Helper function which returns true if the custom passphrase entered was | 128 // Helper function which returns true if the custom passphrase entered was |
| 143 // accepted. | 129 // accepted. |
| 144 bool IsPassphraseAccepted(const ProfileSyncServiceHarness* harness) { | 130 bool IsPassphraseAccepted(const ProfileSyncServiceHarness* harness) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 if (!service()->IsUsingSecondaryPassphrase()) { | 266 if (!service()->IsUsingSecondaryPassphrase()) { |
| 281 service()->SetEncryptionPassphrase(password_, ProfileSyncService::IMPLICIT); | 267 service()->SetEncryptionPassphrase(password_, ProfileSyncService::IMPLICIT); |
| 282 } else { | 268 } else { |
| 283 LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" | 269 LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" |
| 284 " until SetDecryptionPassphrase is called."; | 270 " until SetDecryptionPassphrase is called."; |
| 285 return false; | 271 return false; |
| 286 } | 272 } |
| 287 | 273 |
| 288 // Wait for initial sync cycle to be completed. | 274 // Wait for initial sync cycle to be completed. |
| 289 DCHECK(service()->sync_initialized()); | 275 DCHECK(service()->sync_initialized()); |
| 290 CallbackStatusChecker initial_sync_checker( | 276 if (!AwaitSyncSetupCompletion()) { |
| 291 base::Bind(&DoneWaitingForInitialSync, base::Unretained(this)), | |
| 292 "DoneWaitingForInitialSync"); | |
| 293 if (!AwaitStatusChange(&initial_sync_checker, "SetupSync")) { | |
| 294 LOG(ERROR) << "Initial sync cycle did not complete after " | 277 LOG(ERROR) << "Initial sync cycle did not complete after " |
| 295 << kSyncOperationTimeoutMs / 1000 | 278 << kSyncOperationTimeoutMs / 1000 |
| 296 << " seconds."; | 279 << " seconds."; |
| 297 return false; | 280 return false; |
| 298 } | 281 } |
| 299 | 282 |
| 300 // Make sure that initial sync wasn't blocked by a missing passphrase. | 283 // Make sure that initial sync wasn't blocked by a missing passphrase. |
| 301 if (service()->passphrase_required_reason() == syncer::REASON_DECRYPTION) { | 284 if (service()->passphrase_required_reason() == syncer::REASON_DECRYPTION) { |
| 302 LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" | 285 LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" |
| 303 " until SetDecryptionPassphrase is called."; | 286 " until SetDecryptionPassphrase is called."; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 syncer::ModelTypeSet model_types = | 319 syncer::ModelTypeSet model_types = |
| 337 snap.model_neutral_state().commit_request_types; | 320 snap.model_neutral_state().commit_request_types; |
| 338 syncer::ObjectIdSet ids = ModelTypeSetToObjectIdSet(model_types); | 321 syncer::ObjectIdSet ids = ModelTypeSetToObjectIdSet(model_types); |
| 339 p2p_invalidation_service_->SendInvalidation(ids); | 322 p2p_invalidation_service_->SendInvalidation(ids); |
| 340 } | 323 } |
| 341 OnStateChanged(); | 324 OnStateChanged(); |
| 342 } | 325 } |
| 343 | 326 |
| 344 bool ProfileSyncServiceHarness::AwaitPassphraseRequired() { | 327 bool ProfileSyncServiceHarness::AwaitPassphraseRequired() { |
| 345 DVLOG(1) << GetClientInfoString("AwaitPassphraseRequired"); | 328 DVLOG(1) << GetClientInfoString("AwaitPassphraseRequired"); |
| 346 if (IsSyncDisabled()) { | |
| 347 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | |
| 348 return false; | |
| 349 } | |
| 350 | |
| 351 if (service()->IsPassphraseRequired()) { | |
| 352 // It's already true that a passphrase is required; don't wait. | |
| 353 return true; | |
| 354 } | |
| 355 | |
| 356 CallbackStatusChecker passphrase_required_checker( | 329 CallbackStatusChecker passphrase_required_checker( |
| 357 base::Bind(&::IsPassphraseRequired, base::Unretained(this)), | 330 base::Bind(&::IsPassphraseRequired, base::Unretained(this)), |
| 358 "IsPassphraseRequired"); | 331 "IsPassphraseRequired"); |
| 359 return AwaitStatusChange(&passphrase_required_checker, | 332 return AwaitStatusChange(&passphrase_required_checker, |
| 360 "AwaitPassphraseRequired"); | 333 "AwaitPassphraseRequired"); |
| 361 } | 334 } |
| 362 | 335 |
| 363 bool ProfileSyncServiceHarness::AwaitPassphraseAccepted() { | 336 bool ProfileSyncServiceHarness::AwaitPassphraseAccepted() { |
| 364 DVLOG(1) << GetClientInfoString("AwaitPassphraseAccepted"); | |
| 365 if (IsSyncDisabled()) { | |
| 366 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | |
| 367 return false; | |
| 368 } | |
| 369 | |
| 370 if (!service()->IsPassphraseRequired() && | |
| 371 service()->IsUsingSecondaryPassphrase()) { | |
| 372 // Passphrase is already accepted; don't wait. | |
| 373 FinishSyncSetup(); | |
| 374 return true; | |
| 375 } | |
| 376 | |
| 377 CallbackStatusChecker passphrase_accepted_checker( | 337 CallbackStatusChecker passphrase_accepted_checker( |
| 378 base::Bind(&::IsPassphraseAccepted, base::Unretained(this)), | 338 base::Bind(&::IsPassphraseAccepted, base::Unretained(this)), |
| 379 "IsPassphraseAccepted"); | 339 "IsPassphraseAccepted"); |
| 380 bool return_value = AwaitStatusChange(&passphrase_accepted_checker, | 340 bool return_value = AwaitStatusChange(&passphrase_accepted_checker, |
| 381 "AwaitPassphraseAccepted"); | 341 "AwaitPassphraseAccepted"); |
| 382 if (return_value) | 342 if (return_value) |
| 383 FinishSyncSetup(); | 343 FinishSyncSetup(); |
| 384 return return_value; | 344 return return_value; |
| 385 } | 345 } |
| 386 | 346 |
| 387 bool ProfileSyncServiceHarness::AwaitBackendInitialized() { | 347 bool ProfileSyncServiceHarness::AwaitBackendInitialized() { |
| 388 DVLOG(1) << GetClientInfoString("AwaitBackendInitialized"); | 348 DVLOG(1) << GetClientInfoString("AwaitBackendInitialized"); |
| 389 if (service()->sync_initialized()) { | |
| 390 // The sync backend host has already been initialized; don't wait. | |
| 391 return true; | |
| 392 } | |
| 393 | |
| 394 CallbackStatusChecker backend_initialized_checker( | 349 CallbackStatusChecker backend_initialized_checker( |
| 395 base::Bind(&DoneWaitingForBackendInitialization, | 350 base::Bind(&DoneWaitingForBackendInitialization, |
| 396 base::Unretained(this)), | 351 base::Unretained(this)), |
| 397 "DoneWaitingForBackendInitialization"); | 352 "DoneWaitingForBackendInitialization"); |
| 398 AwaitStatusChange(&backend_initialized_checker, "AwaitBackendInitialized"); | 353 AwaitStatusChange(&backend_initialized_checker, "AwaitBackendInitialized"); |
| 399 return service()->sync_initialized(); | 354 return service()->sync_initialized(); |
| 400 } | 355 } |
| 401 | 356 |
| 402 bool ProfileSyncServiceHarness::AwaitDataSyncCompletion() { | 357 // TODO(sync): As of today, we wait for a client to finish its commit activity |
| 403 DVLOG(1) << GetClientInfoString("AwaitDataSyncCompletion"); | 358 // by checking if its progress markers are up to date. In future, once we have |
| 404 | 359 // an in-process C++ server, this function can be reimplemented without relying |
| 405 DCHECK(service()->sync_initialized()); | 360 // on progress markers. |
| 406 DCHECK(!IsSyncDisabled()); | 361 bool ProfileSyncServiceHarness::AwaitCommitActivityCompletion() { |
| 407 | 362 DVLOG(1) << GetClientInfoString("AwaitCommitActivityCompletion"); |
| 408 if (IsDataSynced()) { | 363 CallbackStatusChecker latest_progress_markers_checker( |
| 409 // Client is already synced; don't wait. | 364 base::Bind(&ProfileSyncServiceHarness::HasLatestProgressMarkers, |
| 410 return true; | |
| 411 } | |
| 412 | |
| 413 CallbackStatusChecker data_synced_checker( | |
| 414 base::Bind(&ProfileSyncServiceHarness::IsDataSynced, | |
| 415 base::Unretained(this)), | 365 base::Unretained(this)), |
| 416 "IsDataSynced"); | 366 "HasLatestProgressMarkers"); |
| 417 return AwaitStatusChange(&data_synced_checker, "AwaitDataSyncCompletion"); | 367 AwaitStatusChange(&latest_progress_markers_checker, |
| 418 } | 368 "AwaitCommitActivityCompletion"); |
| 419 | 369 return HasLatestProgressMarkers(); |
| 420 bool ProfileSyncServiceHarness::AwaitFullSyncCompletion() { | |
| 421 DVLOG(1) << GetClientInfoString("AwaitFullSyncCompletion"); | |
| 422 if (IsSyncDisabled()) { | |
| 423 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | |
| 424 return false; | |
| 425 } | |
| 426 | |
| 427 if (IsFullySynced()) { | |
| 428 // Client is already synced; don't wait. | |
| 429 return true; | |
| 430 } | |
| 431 | |
| 432 DCHECK(service()->sync_initialized()); | |
| 433 CallbackStatusChecker fully_synced_checker( | |
| 434 base::Bind(&DoneWaitingForFullSync, base::Unretained(this)), | |
| 435 "DoneWaitingForFullSync"); | |
| 436 AwaitStatusChange(&fully_synced_checker, "AwaitFullSyncCompletion"); | |
| 437 return IsFullySynced(); | |
| 438 } | 370 } |
| 439 | 371 |
| 440 bool ProfileSyncServiceHarness::AwaitSyncDisabled() { | 372 bool ProfileSyncServiceHarness::AwaitSyncDisabled() { |
| 441 DCHECK(service()->HasSyncSetupCompleted()); | 373 DCHECK(service()->HasSyncSetupCompleted()); |
| 442 DCHECK(!IsSyncDisabled()); | 374 DCHECK(!IsSyncDisabled()); |
| 443 CallbackStatusChecker sync_disabled_checker( | 375 CallbackStatusChecker sync_disabled_checker( |
| 444 base::Bind(&ProfileSyncServiceHarness::IsSyncDisabled, | 376 base::Bind(&ProfileSyncServiceHarness::IsSyncDisabled, |
| 445 base::Unretained(this)), | 377 base::Unretained(this)), |
| 446 "IsSyncDisabled"); | 378 "IsSyncDisabled"); |
| 447 return AwaitStatusChange(&sync_disabled_checker, "AwaitSyncDisabled"); | 379 return AwaitStatusChange(&sync_disabled_checker, "AwaitSyncDisabled"); |
| 448 } | 380 } |
| 449 | 381 |
| 382 bool ProfileSyncServiceHarness::AwaitSyncSetupCompletion() { |
| 383 CallbackStatusChecker sync_setup_complete_checker( |
| 384 base::Bind(&DoneWaitingForSyncSetup, base::Unretained(this)), |
| 385 "DoneWaitingForSyncSetup"); |
| 386 return AwaitStatusChange(&sync_setup_complete_checker, |
| 387 "AwaitSyncSetupCompletion"); |
| 388 } |
| 389 |
| 450 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( | 390 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( |
| 451 ProfileSyncServiceHarness* partner) { | 391 ProfileSyncServiceHarness* partner) { |
| 452 DVLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion"); | 392 DVLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion"); |
| 453 if (!AwaitFullSyncCompletion()) | 393 if (!AwaitCommitActivityCompletion()) |
| 454 return false; | 394 return false; |
| 455 return partner->WaitUntilProgressMarkersMatch(this); | 395 return partner->WaitUntilProgressMarkersMatch(this); |
| 456 } | 396 } |
| 457 | 397 |
| 458 bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion( | 398 bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion( |
| 459 std::vector<ProfileSyncServiceHarness*>& partners) { | 399 std::vector<ProfileSyncServiceHarness*>& partners) { |
| 460 DVLOG(1) << GetClientInfoString("AwaitGroupSyncCycleCompletion"); | 400 DVLOG(1) << GetClientInfoString("AwaitGroupSyncCycleCompletion"); |
| 461 if (!AwaitFullSyncCompletion()) | 401 if (!AwaitCommitActivityCompletion()) |
| 462 return false; | 402 return false; |
| 463 bool return_value = true; | 403 bool return_value = true; |
| 464 for (std::vector<ProfileSyncServiceHarness*>::iterator it = | 404 for (std::vector<ProfileSyncServiceHarness*>::iterator it = |
| 465 partners.begin(); it != partners.end(); ++it) { | 405 partners.begin(); it != partners.end(); ++it) { |
| 466 if ((this != *it) && (!(*it)->IsSyncDisabled())) { | 406 if ((this != *it) && (!(*it)->IsSyncDisabled())) { |
| 467 return_value = return_value && | 407 return_value = return_value && |
| 468 (*it)->WaitUntilProgressMarkersMatch(this); | 408 (*it)->WaitUntilProgressMarkersMatch(this); |
| 469 } | 409 } |
| 470 } | 410 } |
| 471 return return_value; | 411 return return_value; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 482 return_value = return_value && | 422 return_value = return_value && |
| 483 (*it)->AwaitGroupSyncCycleCompletion(clients); | 423 (*it)->AwaitGroupSyncCycleCompletion(clients); |
| 484 } | 424 } |
| 485 } | 425 } |
| 486 return return_value; | 426 return return_value; |
| 487 } | 427 } |
| 488 | 428 |
| 489 bool ProfileSyncServiceHarness::WaitUntilProgressMarkersMatch( | 429 bool ProfileSyncServiceHarness::WaitUntilProgressMarkersMatch( |
| 490 ProfileSyncServiceHarness* partner) { | 430 ProfileSyncServiceHarness* partner) { |
| 491 DVLOG(1) << GetClientInfoString("WaitUntilProgressMarkersMatch"); | 431 DVLOG(1) << GetClientInfoString("WaitUntilProgressMarkersMatch"); |
| 492 if (IsSyncDisabled()) { | |
| 493 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | |
| 494 return false; | |
| 495 } | |
| 496 | 432 |
| 497 // TODO(rsimha): Replace the mechanism of matching up progress markers with | 433 // TODO(rsimha): Replace the mechanism of matching up progress markers with |
| 498 // one that doesn't require every client to have the same progress markers. | 434 // one that doesn't require every client to have the same progress markers. |
| 499 DCHECK(!progress_marker_partner_); | 435 DCHECK(!progress_marker_partner_); |
| 500 progress_marker_partner_ = partner; | 436 progress_marker_partner_ = partner; |
| 501 bool return_value = false; | 437 bool return_value = false; |
| 502 if (MatchesPartnerClient()) { | 438 if (MatchesPartnerClient()) { |
| 503 // Progress markers already match; don't wait. | 439 // Progress markers already match; don't wait. |
| 504 return_value = true; | 440 return_value = true; |
| 505 } else { | 441 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 518 | 454 |
| 519 bool ProfileSyncServiceHarness::AwaitStatusChange( | 455 bool ProfileSyncServiceHarness::AwaitStatusChange( |
| 520 StatusChangeChecker* checker, const std::string& source) { | 456 StatusChangeChecker* checker, const std::string& source) { |
| 521 DVLOG(1) << GetClientInfoString("AwaitStatusChange"); | 457 DVLOG(1) << GetClientInfoString("AwaitStatusChange"); |
| 522 | 458 |
| 523 if (IsSyncDisabled()) { | 459 if (IsSyncDisabled()) { |
| 524 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | 460 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; |
| 525 return false; | 461 return false; |
| 526 } | 462 } |
| 527 | 463 |
| 464 DCHECK(checker); |
| 465 if (checker->IsExitConditionSatisfied()) { |
| 466 DVLOG(1) << GetClientInfoString("AwaitStatusChange exiting early because " |
| 467 "condition is already satisfied"); |
| 468 return true; |
| 469 } |
| 470 |
| 528 DCHECK(status_change_checker_ == NULL); | 471 DCHECK(status_change_checker_ == NULL); |
| 529 status_change_checker_ = checker; | 472 status_change_checker_ = checker; |
| 530 | 473 |
| 531 base::OneShotTimer<ProfileSyncServiceHarness> timer; | 474 base::OneShotTimer<ProfileSyncServiceHarness> timer; |
| 532 timer.Start(FROM_HERE, | 475 timer.Start(FROM_HERE, |
| 533 base::TimeDelta::FromMilliseconds(kSyncOperationTimeoutMs), | 476 base::TimeDelta::FromMilliseconds(kSyncOperationTimeoutMs), |
| 534 base::Bind(&ProfileSyncServiceHarness::QuitMessageLoop, | 477 base::Bind(&ProfileSyncServiceHarness::QuitMessageLoop, |
| 535 base::Unretained(this))); | 478 base::Unretained(this))); |
| 536 { | 479 { |
| 537 base::MessageLoop* loop = base::MessageLoop::current(); | 480 base::MessageLoop* loop = base::MessageLoop::current(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 | 513 |
| 571 bool ProfileSyncServiceHarness::HasAuthError() const { | 514 bool ProfileSyncServiceHarness::HasAuthError() const { |
| 572 return service()->GetAuthError().state() == | 515 return service()->GetAuthError().state() == |
| 573 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || | 516 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || |
| 574 service()->GetAuthError().state() == | 517 service()->GetAuthError().state() == |
| 575 GoogleServiceAuthError::SERVICE_ERROR || | 518 GoogleServiceAuthError::SERVICE_ERROR || |
| 576 service()->GetAuthError().state() == | 519 service()->GetAuthError().state() == |
| 577 GoogleServiceAuthError::REQUEST_CANCELED; | 520 GoogleServiceAuthError::REQUEST_CANCELED; |
| 578 } | 521 } |
| 579 | 522 |
| 580 // We use this function to share code between IsFullySynced and IsDataSynced. | 523 // TODO(sync): Remove this method once we stop relying on self notifications and |
| 581 bool ProfileSyncServiceHarness::IsDataSyncedImpl() const { | 524 // comparing progress markers. |
| 582 return ServiceIsPushingChanges() && | 525 bool ProfileSyncServiceHarness::HasLatestProgressMarkers() const { |
| 583 GetStatus().notifications_enabled && | |
| 584 !service()->HasUnsyncedItems() && | |
| 585 !HasPendingBackendMigration(); | |
| 586 } | |
| 587 | |
| 588 bool ProfileSyncServiceHarness::IsDataSynced() const { | |
| 589 if (service() == NULL) { | |
| 590 DVLOG(1) << GetClientInfoString("IsDataSynced(): false"); | |
| 591 return false; | |
| 592 } | |
| 593 | |
| 594 bool is_data_synced = IsDataSyncedImpl(); | |
| 595 | |
| 596 DVLOG(1) << GetClientInfoString( | |
| 597 is_data_synced ? "IsDataSynced: true" : "IsDataSynced: false"); | |
| 598 return is_data_synced; | |
| 599 } | |
| 600 | |
| 601 bool ProfileSyncServiceHarness::IsFullySynced() const { | |
| 602 if (service() == NULL) { | |
| 603 DVLOG(1) << GetClientInfoString("IsFullySynced: false"); | |
| 604 return false; | |
| 605 } | |
| 606 // If we didn't try to commit anything in the previous cycle, there's a | |
| 607 // good chance that we're now fully up to date. | |
| 608 const SyncSessionSnapshot& snap = GetLastSessionSnapshot(); | 526 const SyncSessionSnapshot& snap = GetLastSessionSnapshot(); |
| 609 bool is_fully_synced = | 527 return snap.model_neutral_state().num_successful_commits == 0 && |
| 610 snap.model_neutral_state().num_successful_commits == 0 | 528 !service()->HasUnsyncedItems(); |
| 611 && snap.model_neutral_state().commit_result == syncer::SYNCER_OK | |
| 612 && IsDataSyncedImpl(); | |
| 613 | |
| 614 DVLOG(1) << GetClientInfoString( | |
| 615 is_fully_synced ? "IsFullySynced: true" : "IsFullySynced: false"); | |
| 616 return is_fully_synced; | |
| 617 } | 529 } |
| 618 | 530 |
| 619 void ProfileSyncServiceHarness::FinishSyncSetup() { | 531 void ProfileSyncServiceHarness::FinishSyncSetup() { |
| 620 service()->SetSetupInProgress(false); | 532 service()->SetSetupInProgress(false); |
| 621 service()->SetSyncSetupCompleted(); | 533 service()->SetSyncSetupCompleted(); |
| 622 } | 534 } |
| 623 | 535 |
| 624 bool ProfileSyncServiceHarness::HasPendingBackendMigration() const { | |
| 625 browser_sync::BackendMigrator* migrator = | |
| 626 service()->GetBackendMigratorForTest(); | |
| 627 return migrator && migrator->state() != browser_sync::BackendMigrator::IDLE; | |
| 628 } | |
| 629 | |
| 630 bool ProfileSyncServiceHarness::AutoStartEnabled() { | 536 bool ProfileSyncServiceHarness::AutoStartEnabled() { |
| 631 return service()->auto_start_enabled(); | 537 return service()->auto_start_enabled(); |
| 632 } | 538 } |
| 633 | 539 |
| 634 bool ProfileSyncServiceHarness::MatchesPartnerClient() const { | 540 bool ProfileSyncServiceHarness::MatchesPartnerClient() const { |
| 635 // TODO(akalin): Shouldn't this belong with the intersection check? | |
| 636 // Otherwise, this function isn't symmetric. | |
| 637 DCHECK(progress_marker_partner_); | 541 DCHECK(progress_marker_partner_); |
| 638 if (!IsFullySynced()) { | |
| 639 DVLOG(2) << profile_debug_name_ << ": not synced, assuming doesn't match"; | |
| 640 return false; | |
| 641 } | |
| 642 | 542 |
| 643 // Only look for a match if we have at least one enabled datatype in | 543 // Only look for a match if we have at least one enabled datatype in |
| 644 // common with the partner client. | 544 // common with the partner client. |
| 645 const syncer::ModelTypeSet common_types = | 545 const syncer::ModelTypeSet common_types = |
| 646 Intersection(service()->GetActiveDataTypes(), | 546 Intersection(service()->GetActiveDataTypes(), |
| 647 progress_marker_partner_->service()->GetActiveDataTypes()); | 547 progress_marker_partner_->service()->GetActiveDataTypes()); |
| 648 | 548 |
| 649 DVLOG(2) << profile_debug_name_ << ", " | 549 DVLOG(2) << profile_debug_name_ << ", " |
| 650 << progress_marker_partner_->profile_debug_name_ | 550 << progress_marker_partner_->profile_debug_name_ |
| 651 << ": common types are " | 551 << ": common types are " |
| 652 << syncer::ModelTypeSetToString(common_types); | 552 << syncer::ModelTypeSetToString(common_types); |
| 653 | 553 |
| 654 if (!common_types.Empty() && !progress_marker_partner_->IsFullySynced()) { | |
| 655 DVLOG(2) << "non-empty common types and " | |
| 656 << progress_marker_partner_->profile_debug_name_ | |
| 657 << " isn't synced"; | |
| 658 return false; | |
| 659 } | |
| 660 | |
| 661 for (syncer::ModelTypeSet::Iterator i = common_types.First(); | 554 for (syncer::ModelTypeSet::Iterator i = common_types.First(); |
| 662 i.Good(); i.Inc()) { | 555 i.Good(); i.Inc()) { |
| 663 const std::string marker = GetSerializedProgressMarker(i.Get()); | 556 const std::string marker = GetSerializedProgressMarker(i.Get()); |
| 664 const std::string partner_marker = | 557 const std::string partner_marker = |
| 665 progress_marker_partner_->GetSerializedProgressMarker(i.Get()); | 558 progress_marker_partner_->GetSerializedProgressMarker(i.Get()); |
| 666 if (marker != partner_marker) { | 559 if (marker != partner_marker) { |
| 667 if (VLOG_IS_ON(2)) { | 560 if (VLOG_IS_ON(2)) { |
| 668 std::string marker_base64, partner_marker_base64; | 561 std::string marker_base64, partner_marker_base64; |
| 669 base::Base64Encode(marker, &marker_base64); | 562 base::Base64Encode(marker, &marker_base64); |
| 670 base::Base64Encode(partner_marker, &partner_marker_base64); | 563 base::Base64Encode(partner_marker, &partner_marker_base64); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 syncer::ModelTypeSet synced_datatypes = service()->GetPreferredDataTypes(); | 599 syncer::ModelTypeSet synced_datatypes = service()->GetPreferredDataTypes(); |
| 707 if (synced_datatypes.Has(datatype)) { | 600 if (synced_datatypes.Has(datatype)) { |
| 708 DVLOG(1) << "EnableSyncForDatatype(): Sync already enabled for datatype " | 601 DVLOG(1) << "EnableSyncForDatatype(): Sync already enabled for datatype " |
| 709 << syncer::ModelTypeToString(datatype) | 602 << syncer::ModelTypeToString(datatype) |
| 710 << " on " << profile_debug_name_ << "."; | 603 << " on " << profile_debug_name_ << "."; |
| 711 return true; | 604 return true; |
| 712 } | 605 } |
| 713 | 606 |
| 714 synced_datatypes.Put(syncer::ModelTypeFromInt(datatype)); | 607 synced_datatypes.Put(syncer::ModelTypeFromInt(datatype)); |
| 715 service()->OnUserChoseDatatypes(false, synced_datatypes); | 608 service()->OnUserChoseDatatypes(false, synced_datatypes); |
| 716 if (AwaitDataSyncCompletion()) { | 609 if (AwaitSyncSetupCompletion()) { |
| 717 DVLOG(1) << "EnableSyncForDatatype(): Enabled sync for datatype " | 610 DVLOG(1) << "EnableSyncForDatatype(): Enabled sync for datatype " |
| 718 << syncer::ModelTypeToString(datatype) | 611 << syncer::ModelTypeToString(datatype) |
| 719 << " on " << profile_debug_name_ << "."; | 612 << " on " << profile_debug_name_ << "."; |
| 720 return true; | 613 return true; |
| 721 } | 614 } |
| 722 | 615 |
| 723 DVLOG(0) << GetClientInfoString("EnableSyncForDatatype failed"); | 616 DVLOG(0) << GetClientInfoString("EnableSyncForDatatype failed"); |
| 724 return false; | 617 return false; |
| 725 } | 618 } |
| 726 | 619 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 739 if (!synced_datatypes.Has(datatype)) { | 632 if (!synced_datatypes.Has(datatype)) { |
| 740 DVLOG(1) << "DisableSyncForDatatype(): Sync already disabled for datatype " | 633 DVLOG(1) << "DisableSyncForDatatype(): Sync already disabled for datatype " |
| 741 << syncer::ModelTypeToString(datatype) | 634 << syncer::ModelTypeToString(datatype) |
| 742 << " on " << profile_debug_name_ << "."; | 635 << " on " << profile_debug_name_ << "."; |
| 743 return true; | 636 return true; |
| 744 } | 637 } |
| 745 | 638 |
| 746 synced_datatypes.RetainAll(syncer::UserSelectableTypes()); | 639 synced_datatypes.RetainAll(syncer::UserSelectableTypes()); |
| 747 synced_datatypes.Remove(datatype); | 640 synced_datatypes.Remove(datatype); |
| 748 service()->OnUserChoseDatatypes(false, synced_datatypes); | 641 service()->OnUserChoseDatatypes(false, synced_datatypes); |
| 749 if (AwaitFullSyncCompletion()) { | 642 if (AwaitSyncSetupCompletion()) { |
| 750 DVLOG(1) << "DisableSyncForDatatype(): Disabled sync for datatype " | 643 DVLOG(1) << "DisableSyncForDatatype(): Disabled sync for datatype " |
| 751 << syncer::ModelTypeToString(datatype) | 644 << syncer::ModelTypeToString(datatype) |
| 752 << " on " << profile_debug_name_ << "."; | 645 << " on " << profile_debug_name_ << "."; |
| 753 return true; | 646 return true; |
| 754 } | 647 } |
| 755 | 648 |
| 756 DVLOG(0) << GetClientInfoString("DisableSyncForDatatype failed"); | 649 DVLOG(0) << GetClientInfoString("DisableSyncForDatatype failed"); |
| 757 return false; | 650 return false; |
| 758 } | 651 } |
| 759 | 652 |
| 760 bool ProfileSyncServiceHarness::EnableSyncForAllDatatypes() { | 653 bool ProfileSyncServiceHarness::EnableSyncForAllDatatypes() { |
| 761 DVLOG(1) << GetClientInfoString("EnableSyncForAllDatatypes"); | 654 DVLOG(1) << GetClientInfoString("EnableSyncForAllDatatypes"); |
| 762 | 655 |
| 763 if (IsSyncDisabled()) | 656 if (IsSyncDisabled()) |
| 764 return SetupSync(); | 657 return SetupSync(); |
| 765 | 658 |
| 766 if (service() == NULL) { | 659 if (service() == NULL) { |
| 767 LOG(ERROR) << "EnableSyncForAllDatatypes(): service() is null."; | 660 LOG(ERROR) << "EnableSyncForAllDatatypes(): service() is null."; |
| 768 return false; | 661 return false; |
| 769 } | 662 } |
| 770 | 663 |
| 771 service()->OnUserChoseDatatypes(true, syncer::ModelTypeSet::All()); | 664 service()->OnUserChoseDatatypes(true, syncer::ModelTypeSet::All()); |
| 772 if (AwaitFullSyncCompletion()) { | 665 if (AwaitSyncSetupCompletion()) { |
| 773 DVLOG(1) << "EnableSyncForAllDatatypes(): Enabled sync for all datatypes " | 666 DVLOG(1) << "EnableSyncForAllDatatypes(): Enabled sync for all datatypes " |
| 774 << "on " << profile_debug_name_ << "."; | 667 << "on " << profile_debug_name_ << "."; |
| 775 return true; | 668 return true; |
| 776 } | 669 } |
| 777 | 670 |
| 778 DVLOG(0) << GetClientInfoString("EnableSyncForAllDatatypes failed"); | 671 DVLOG(0) << GetClientInfoString("EnableSyncForAllDatatypes failed"); |
| 779 return false; | 672 return false; |
| 780 } | 673 } |
| 781 | 674 |
| 782 bool ProfileSyncServiceHarness::DisableSyncForAllDatatypes() { | 675 bool ProfileSyncServiceHarness::DisableSyncForAllDatatypes() { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 798 syncer::ModelType model_type) const { | 691 syncer::ModelType model_type) const { |
| 799 const SyncSessionSnapshot& snap = GetLastSessionSnapshot(); | 692 const SyncSessionSnapshot& snap = GetLastSessionSnapshot(); |
| 800 const syncer::ProgressMarkerMap& markers_map = | 693 const syncer::ProgressMarkerMap& markers_map = |
| 801 snap.download_progress_markers(); | 694 snap.download_progress_markers(); |
| 802 | 695 |
| 803 syncer::ProgressMarkerMap::const_iterator it = | 696 syncer::ProgressMarkerMap::const_iterator it = |
| 804 markers_map.find(model_type); | 697 markers_map.find(model_type); |
| 805 return (it != markers_map.end()) ? it->second : std::string(); | 698 return (it != markers_map.end()) ? it->second : std::string(); |
| 806 } | 699 } |
| 807 | 700 |
| 701 // TODO(sync): Clean up this method in a separate CL. Remove all snapshot fields |
| 702 // and log shorter, more meaningful messages. |
| 808 std::string ProfileSyncServiceHarness::GetClientInfoString( | 703 std::string ProfileSyncServiceHarness::GetClientInfoString( |
| 809 const std::string& message) const { | 704 const std::string& message) const { |
| 810 std::stringstream os; | 705 std::stringstream os; |
| 811 os << profile_debug_name_ << ": " << message << ": "; | 706 os << profile_debug_name_ << ": " << message << ": "; |
| 812 if (service()) { | 707 if (service()) { |
| 813 const SyncSessionSnapshot& snap = GetLastSessionSnapshot(); | 708 const SyncSessionSnapshot& snap = GetLastSessionSnapshot(); |
| 814 const ProfileSyncService::Status& status = GetStatus(); | 709 const ProfileSyncService::Status& status = GetStatus(); |
| 815 // Capture select info from the sync session snapshot and syncer status. | 710 // Capture select info from the sync session snapshot and syncer status. |
| 816 // TODO(rsimha): Audit the list of fields below, and eventually eliminate | |
| 817 // the use of the sync session snapshot. See crbug.com/323380. | |
| 818 os << ", has_unsynced_items: " | 711 os << ", has_unsynced_items: " |
| 819 << (service()->sync_initialized() ? service()->HasUnsyncedItems() : 0) | 712 << (service()->sync_initialized() ? service()->HasUnsyncedItems() : 0) |
| 820 << ", did_commit: " | 713 << ", did_commit: " |
| 821 << (snap.model_neutral_state().num_successful_commits == 0 && | 714 << (snap.model_neutral_state().num_successful_commits == 0 && |
| 822 snap.model_neutral_state().commit_result == syncer::SYNCER_OK) | 715 snap.model_neutral_state().commit_result == syncer::SYNCER_OK) |
| 823 << ", encryption conflicts: " | 716 << ", encryption conflicts: " |
| 824 << snap.num_encryption_conflicts() | 717 << snap.num_encryption_conflicts() |
| 825 << ", hierarchy conflicts: " | 718 << ", hierarchy conflicts: " |
| 826 << snap.num_hierarchy_conflicts() | 719 << snap.num_hierarchy_conflicts() |
| 827 << ", server conflicts: " | 720 << ", server conflicts: " |
| 828 << snap.num_server_conflicts() | 721 << snap.num_server_conflicts() |
| 829 << ", num_updates_downloaded : " | 722 << ", num_updates_downloaded : " |
| 830 << snap.model_neutral_state().num_updates_downloaded_total | 723 << snap.model_neutral_state().num_updates_downloaded_total |
| 831 << ", passphrase_required_reason: " | 724 << ", passphrase_required_reason: " |
| 832 << syncer::PassphraseRequiredReasonToString( | 725 << syncer::PassphraseRequiredReasonToString( |
| 833 service()->passphrase_required_reason()) | 726 service()->passphrase_required_reason()) |
| 834 << ", notifications_enabled: " | 727 << ", notifications_enabled: " |
| 835 << status.notifications_enabled | 728 << status.notifications_enabled |
| 836 << ", service_is_pushing_changes: " | 729 << ", service_is_pushing_changes: " |
| 837 << ServiceIsPushingChanges() | 730 << ServiceIsPushingChanges(); |
| 838 << ", has_pending_backend_migration: " | |
| 839 << HasPendingBackendMigration(); | |
| 840 } else { | 731 } else { |
| 841 os << "Sync service not available"; | 732 os << "Sync service not available"; |
| 842 } | 733 } |
| 843 return os.str(); | 734 return os.str(); |
| 844 } | 735 } |
| 845 | 736 |
| 846 bool ProfileSyncServiceHarness::EnableEncryption() { | 737 bool ProfileSyncServiceHarness::EnableEncryption() { |
| 847 if (IsEncryptionComplete()) | 738 if (IsEncryptionComplete()) |
| 848 return true; | 739 return true; |
| 849 service()->EnableEncryptEverything(); | 740 service()->EnableEncryptEverything(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 | 797 |
| 907 std::string ProfileSyncServiceHarness::GetServiceStatus() { | 798 std::string ProfileSyncServiceHarness::GetServiceStatus() { |
| 908 scoped_ptr<base::DictionaryValue> value( | 799 scoped_ptr<base::DictionaryValue> value( |
| 909 sync_ui_util::ConstructAboutInformation(service())); | 800 sync_ui_util::ConstructAboutInformation(service())); |
| 910 std::string service_status; | 801 std::string service_status; |
| 911 base::JSONWriter::WriteWithOptions(value.get(), | 802 base::JSONWriter::WriteWithOptions(value.get(), |
| 912 base::JSONWriter::OPTIONS_PRETTY_PRINT, | 803 base::JSONWriter::OPTIONS_PRETTY_PRINT, |
| 913 &service_status); | 804 &service_status); |
| 914 return service_status; | 805 return service_status; |
| 915 } | 806 } |
| OLD | NEW |