| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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/profile_sync_service_harness.h" | 5 #include "chrome/browser/sync/profile_sync_service_harness.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <iterator> | 9 #include <iterator> |
| 10 #include <ostream> | 10 #include <ostream> |
| 11 #include <set> | 11 #include <set> |
| 12 #include <sstream> | 12 #include <sstream> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/base64.h" |
| 16 #include "base/compiler_specific.h" |
| 15 #include "base/json/json_writer.h" | 17 #include "base/json/json_writer.h" |
| 16 #include "base/logging.h" | 18 #include "base/logging.h" |
| 17 #include "base/memory/ref_counted.h" | 19 #include "base/memory/ref_counted.h" |
| 18 #include "base/message_loop.h" | 20 #include "base/message_loop.h" |
| 19 #include "base/task.h" | 21 #include "base/task.h" |
| 20 #include "base/tracked.h" | 22 #include "base/tracked.h" |
| 21 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 22 #include "chrome/browser/sync/sessions/session_state.h" | 24 #include "chrome/browser/sync/sessions/session_state.h" |
| 23 #include "chrome/browser/sync/signin_manager.h" | 25 #include "chrome/browser/sync/signin_manager.h" |
| 24 #include "chrome/browser/sync/sync_ui_util.h" | 26 #include "chrome/browser/sync/sync_ui_util.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 wait_state_(INITIAL_WAIT_STATE), | 102 wait_state_(INITIAL_WAIT_STATE), |
| 101 profile_(profile), | 103 profile_(profile), |
| 102 service_(NULL), | 104 service_(NULL), |
| 103 timestamp_match_partner_(NULL), | 105 timestamp_match_partner_(NULL), |
| 104 username_(username), | 106 username_(username), |
| 105 password_(password), | 107 password_(password), |
| 106 profile_debug_name_(profile->GetDebugName()) { | 108 profile_debug_name_(profile->GetDebugName()) { |
| 107 if (IsSyncAlreadySetup()) { | 109 if (IsSyncAlreadySetup()) { |
| 108 service_ = profile_->GetProfileSyncService(); | 110 service_ = profile_->GetProfileSyncService(); |
| 109 service_->AddObserver(this); | 111 service_->AddObserver(this); |
| 112 ignore_result(TryListeningToMigrationEvents()); |
| 110 wait_state_ = FULLY_SYNCED; | 113 wait_state_ = FULLY_SYNCED; |
| 111 } | 114 } |
| 112 } | 115 } |
| 113 | 116 |
| 114 ProfileSyncServiceHarness::~ProfileSyncServiceHarness() {} | 117 ProfileSyncServiceHarness::~ProfileSyncServiceHarness() {} |
| 115 | 118 |
| 116 // static | 119 // static |
| 117 ProfileSyncServiceHarness* ProfileSyncServiceHarness::CreateAndAttach( | 120 ProfileSyncServiceHarness* ProfileSyncServiceHarness::CreateAndAttach( |
| 118 Profile* profile) { | 121 Profile* profile) { |
| 119 if (!profile->HasProfileSyncService()) { | 122 if (!profile->HasProfileSyncService()) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 << " seconds."; | 176 << " seconds."; |
| 174 return false; | 177 return false; |
| 175 } | 178 } |
| 176 | 179 |
| 177 // Choose the datatypes to be synced. If all datatypes are to be synced, | 180 // Choose the datatypes to be synced. If all datatypes are to be synced, |
| 178 // set sync_everything to true; otherwise, set it to false. | 181 // set sync_everything to true; otherwise, set it to false. |
| 179 bool sync_everything = (synced_datatypes.size() == | 182 bool sync_everything = (synced_datatypes.size() == |
| 180 (syncable::MODEL_TYPE_COUNT - syncable::FIRST_REAL_MODEL_TYPE)); | 183 (syncable::MODEL_TYPE_COUNT - syncable::FIRST_REAL_MODEL_TYPE)); |
| 181 service()->OnUserChoseDatatypes(sync_everything, synced_datatypes); | 184 service()->OnUserChoseDatatypes(sync_everything, synced_datatypes); |
| 182 | 185 |
| 186 // Subscribe sync client to notifications from the backend migrator |
| 187 // (possible only after choosing data types). |
| 188 if (!TryListeningToMigrationEvents()) { |
| 189 NOTREACHED(); |
| 190 return false; |
| 191 } |
| 192 |
| 183 // Make sure that a partner client hasn't already set an explicit passphrase. | 193 // Make sure that a partner client hasn't already set an explicit passphrase. |
| 184 if (wait_state_ == SET_PASSPHRASE_FAILED) { | 194 if (wait_state_ == SET_PASSPHRASE_FAILED) { |
| 185 LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" | 195 LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" |
| 186 " until SetPassphrase is called."; | 196 " until SetPassphrase is called."; |
| 187 return false; | 197 return false; |
| 188 } | 198 } |
| 189 | 199 |
| 190 // Wait for initial sync cycle to be completed. | 200 // Wait for initial sync cycle to be completed. |
| 191 DCHECK_EQ(wait_state_, WAITING_FOR_INITIAL_SYNC); | 201 DCHECK_EQ(wait_state_, WAITING_FOR_INITIAL_SYNC); |
| 192 if (!AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, | 202 if (!AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 203 " until SetPassphrase is called."; | 213 " until SetPassphrase is called."; |
| 204 return false; | 214 return false; |
| 205 } | 215 } |
| 206 | 216 |
| 207 // Indicate to the browser that sync setup is complete. | 217 // Indicate to the browser that sync setup is complete. |
| 208 service()->SetSyncSetupCompleted(); | 218 service()->SetSyncSetupCompleted(); |
| 209 | 219 |
| 210 return true; | 220 return true; |
| 211 } | 221 } |
| 212 | 222 |
| 223 bool ProfileSyncServiceHarness::TryListeningToMigrationEvents() { |
| 224 browser_sync::BackendMigrator* migrator = |
| 225 service_->GetBackendMigratorForTest(); |
| 226 if (migrator && !migrator->HasMigrationObserver(this)) { |
| 227 migrator->AddMigrationObserver(this); |
| 228 return true; |
| 229 } |
| 230 return false; |
| 231 } |
| 232 |
| 213 void ProfileSyncServiceHarness::SignalStateCompleteWithNextState( | 233 void ProfileSyncServiceHarness::SignalStateCompleteWithNextState( |
| 214 WaitState next_state) { | 234 WaitState next_state) { |
| 215 wait_state_ = next_state; | 235 wait_state_ = next_state; |
| 216 SignalStateComplete(); | 236 SignalStateComplete(); |
| 217 } | 237 } |
| 218 | 238 |
| 219 void ProfileSyncServiceHarness::SignalStateComplete() { | 239 void ProfileSyncServiceHarness::SignalStateComplete() { |
| 220 MessageLoop::current()->Quit(); | 240 MessageLoop::current()->Quit(); |
| 221 } | 241 } |
| 222 | 242 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 VLOG(1) << GetClientInfoString( | 357 VLOG(1) << GetClientInfoString( |
| 338 "WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION"); | 358 "WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION"); |
| 339 const browser_sync::sessions::SyncSessionSnapshot *snap = | 359 const browser_sync::sessions::SyncSessionSnapshot *snap = |
| 340 GetLastSessionSnapshot(); | 360 GetLastSessionSnapshot(); |
| 341 CHECK(snap); | 361 CHECK(snap); |
| 342 retry_verifier_.VerifyRetryInterval(*snap); | 362 retry_verifier_.VerifyRetryInterval(*snap); |
| 343 if (retry_verifier_.done()) | 363 if (retry_verifier_.done()) |
| 344 SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); | 364 SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); |
| 345 break; | 365 break; |
| 346 } | 366 } |
| 367 case WAITING_FOR_MIGRATION_TO_START: { |
| 368 VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_START"); |
| 369 if (HasPendingBackendMigration()) { |
| 370 SignalStateCompleteWithNextState(WAITING_FOR_MIGRATION_TO_FINISH); |
| 371 } |
| 372 break; |
| 373 } |
| 374 case WAITING_FOR_MIGRATION_TO_FINISH: { |
| 375 VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_FINISH"); |
| 376 if (!HasPendingBackendMigration()) { |
| 377 SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); |
| 378 } |
| 379 break; |
| 380 } |
| 347 case SERVER_UNREACHABLE: { | 381 case SERVER_UNREACHABLE: { |
| 348 VLOG(1) << GetClientInfoString("SERVER_UNREACHABLE"); | 382 VLOG(1) << GetClientInfoString("SERVER_UNREACHABLE"); |
| 349 if (GetStatus().server_reachable) { | 383 if (GetStatus().server_reachable) { |
| 350 // The client was offline due to the network being disabled, but is now | 384 // The client was offline due to the network being disabled, but is now |
| 351 // back online. Wait for the pending sync cycle to complete. | 385 // back online. Wait for the pending sync cycle to complete. |
| 352 SignalStateCompleteWithNextState(WAITING_FOR_SYNC_TO_FINISH); | 386 SignalStateCompleteWithNextState(WAITING_FOR_SYNC_TO_FINISH); |
| 353 } | 387 } |
| 354 break; | 388 break; |
| 355 } | 389 } |
| 356 case SET_PASSPHRASE_FAILED: { | 390 case SET_PASSPHRASE_FAILED: { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 380 // classes using the the UI message loop. Defer to their handling. | 414 // classes using the the UI message loop. Defer to their handling. |
| 381 break; | 415 break; |
| 382 } | 416 } |
| 383 return original_wait_state != wait_state_; | 417 return original_wait_state != wait_state_; |
| 384 } | 418 } |
| 385 | 419 |
| 386 void ProfileSyncServiceHarness::OnStateChanged() { | 420 void ProfileSyncServiceHarness::OnStateChanged() { |
| 387 RunStateChangeMachine(); | 421 RunStateChangeMachine(); |
| 388 } | 422 } |
| 389 | 423 |
| 424 void ProfileSyncServiceHarness::OnMigrationStateChange() { |
| 425 // Update migration state. |
| 426 if (HasPendingBackendMigration()) { |
| 427 // Merge current pending migration types into |
| 428 // |pending_migration_types_|. |
| 429 syncable::ModelTypeSet new_pending_migration_types = |
| 430 service()->GetBackendMigratorForTest()-> |
| 431 GetPendingMigrationTypesForTest(); |
| 432 syncable::ModelTypeSet temp; |
| 433 std::set_union(pending_migration_types_.begin(), |
| 434 pending_migration_types_.end(), |
| 435 new_pending_migration_types.begin(), |
| 436 new_pending_migration_types.end(), |
| 437 std::inserter(temp, temp.end())); |
| 438 std::swap(pending_migration_types_, temp); |
| 439 VLOG(1) << profile_debug_name_ << ": new pending migration types " |
| 440 << syncable::ModelTypeSetToString(pending_migration_types_); |
| 441 } else { |
| 442 // Merge just-finished pending migration types into |
| 443 // |migration_types_|. |
| 444 syncable::ModelTypeSet temp; |
| 445 std::set_union(pending_migration_types_.begin(), |
| 446 pending_migration_types_.end(), |
| 447 migrated_types_.begin(), |
| 448 migrated_types_.end(), |
| 449 std::inserter(temp, temp.end())); |
| 450 std::swap(migrated_types_, temp); |
| 451 pending_migration_types_.clear(); |
| 452 VLOG(1) << profile_debug_name_ << ": new migrated types " |
| 453 << syncable::ModelTypeSetToString(migrated_types_); |
| 454 } |
| 455 RunStateChangeMachine(); |
| 456 } |
| 457 |
| 390 bool ProfileSyncServiceHarness::AwaitPassphraseRequired() { | 458 bool ProfileSyncServiceHarness::AwaitPassphraseRequired() { |
| 391 VLOG(1) << GetClientInfoString("AwaitPassphraseRequired"); | 459 VLOG(1) << GetClientInfoString("AwaitPassphraseRequired"); |
| 392 if (wait_state_ == SYNC_DISABLED) { | 460 if (wait_state_ == SYNC_DISABLED) { |
| 393 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | 461 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; |
| 394 return false; | 462 return false; |
| 395 } | 463 } |
| 396 | 464 |
| 397 if (service()->IsPassphraseRequired()) { | 465 if (service()->IsPassphraseRequired()) { |
| 398 // It's already true that a passphrase is required; don't wait. | 466 // It's already true that a passphrase is required; don't wait. |
| 399 return true; | 467 return true; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 if (wait_state_ == SYNC_DISABLED) { | 530 if (wait_state_ == SYNC_DISABLED) { |
| 463 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; | 531 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; |
| 464 return false; | 532 return false; |
| 465 } | 533 } |
| 466 | 534 |
| 467 if (IsSynced()) { | 535 if (IsSynced()) { |
| 468 // Client is already synced; don't wait. | 536 // Client is already synced; don't wait. |
| 469 return true; | 537 return true; |
| 470 } | 538 } |
| 471 | 539 |
| 472 return AwaitSyncCycleCompletionHelper(reason); | |
| 473 } | |
| 474 | |
| 475 bool ProfileSyncServiceHarness::AwaitNextSyncCycleCompletion( | |
| 476 const std::string& reason) { | |
| 477 VLOG(1) << GetClientInfoString("AwaitNextSyncCycleCompletion"); | |
| 478 return AwaitSyncCycleCompletionHelper(reason); | |
| 479 } | |
| 480 | |
| 481 bool ProfileSyncServiceHarness::AwaitSyncCycleCompletionHelper( | |
| 482 const std::string& reason) { | |
| 483 if (wait_state_ == SERVER_UNREACHABLE) { | 540 if (wait_state_ == SERVER_UNREACHABLE) { |
| 484 // Client was offline; wait for it to go online, and then wait for sync. | 541 // Client was offline; wait for it to go online, and then wait for sync. |
| 485 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); | 542 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); |
| 486 DCHECK_EQ(wait_state_, WAITING_FOR_SYNC_TO_FINISH); | 543 DCHECK_EQ(wait_state_, WAITING_FOR_SYNC_TO_FINISH); |
| 487 return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); | 544 return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); |
| 488 } | 545 } |
| 489 | 546 |
| 490 DCHECK(service()->sync_initialized()); | 547 DCHECK(service()->sync_initialized()); |
| 491 wait_state_ = WAITING_FOR_SYNC_TO_FINISH; | 548 wait_state_ = WAITING_FOR_SYNC_TO_FINISH; |
| 492 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); | 549 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 515 const browser_sync::sessions::SyncSessionSnapshot *snap = | 572 const browser_sync::sessions::SyncSessionSnapshot *snap = |
| 516 GetLastSessionSnapshot(); | 573 GetLastSessionSnapshot(); |
| 517 CHECK(snap); | 574 CHECK(snap); |
| 518 retry_verifier_.Initialize(*snap); | 575 retry_verifier_.Initialize(*snap); |
| 519 wait_state_ = WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION; | 576 wait_state_ = WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION; |
| 520 AwaitStatusChangeWithTimeout(kExponentialBackoffVerificationTimeoutMs, | 577 AwaitStatusChangeWithTimeout(kExponentialBackoffVerificationTimeoutMs, |
| 521 "Verify Exponential backoff"); | 578 "Verify Exponential backoff"); |
| 522 return (retry_verifier_.Succeeded()); | 579 return (retry_verifier_.Succeeded()); |
| 523 } | 580 } |
| 524 | 581 |
| 582 bool ProfileSyncServiceHarness::AwaitMigration( |
| 583 const syncable::ModelTypeSet& expected_migrated_types) { |
| 584 VLOG(1) << GetClientInfoString("AwaitMigration"); |
| 585 VLOG(1) << profile_debug_name_ << ": waiting until migration is done for " |
| 586 << syncable::ModelTypeSetToString(expected_migrated_types); |
| 587 while (true) { |
| 588 bool migration_finished = |
| 589 std::includes(migrated_types_.begin(), migrated_types_.end(), |
| 590 expected_migrated_types.begin(), |
| 591 expected_migrated_types.end()); |
| 592 VLOG(1) << "Migrated types " |
| 593 << syncable::ModelTypeSetToString(migrated_types_) |
| 594 << (migration_finished ? " contains " : " does not contain ") |
| 595 << syncable::ModelTypeSetToString(expected_migrated_types); |
| 596 if (migration_finished) { |
| 597 return true; |
| 598 } |
| 599 |
| 600 if (HasPendingBackendMigration()) { |
| 601 wait_state_ = WAITING_FOR_MIGRATION_TO_FINISH; |
| 602 } else { |
| 603 wait_state_ = WAITING_FOR_MIGRATION_TO_START; |
| 604 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, |
| 605 "Wait for migration to start"); |
| 606 if (wait_state_ != WAITING_FOR_MIGRATION_TO_FINISH) { |
| 607 VLOG(1) << profile_debug_name_ |
| 608 << ": wait state = " << wait_state_ |
| 609 << " after migration start is not " |
| 610 << "WAITING_FOR_MIGRATION_TO_FINISH"; |
| 611 return false; |
| 612 } |
| 613 } |
| 614 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, |
| 615 "Wait for migration to finish"); |
| 616 if (wait_state_ != WAITING_FOR_NOTHING) { |
| 617 VLOG(1) << profile_debug_name_ |
| 618 << ": wait state = " << wait_state_ |
| 619 << " after migration finish is not WAITING_FOR_NOTHING"; |
| 620 return false; |
| 621 } |
| 622 if (!AwaitSyncCycleCompletion( |
| 623 "Config sync cycle after migration cycle")) { |
| 624 return false; |
| 625 } |
| 626 } |
| 627 } |
| 628 |
| 525 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( | 629 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( |
| 526 ProfileSyncServiceHarness* partner) { | 630 ProfileSyncServiceHarness* partner) { |
| 527 VLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion"); | 631 VLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion"); |
| 528 if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) | 632 if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) |
| 529 return false; | 633 return false; |
| 530 return partner->WaitUntilTimestampMatches(this, | 634 return partner->WaitUntilTimestampMatches(this, |
| 531 "Sync cycle completion on passive client."); | 635 "Sync cycle completion on passive client."); |
| 532 } | 636 } |
| 533 | 637 |
| 534 bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion( | 638 bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion( |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); | 728 const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); |
| 625 // TODO(rsimha): Remove additional checks of snap->has_more_to_sync and | 729 // TODO(rsimha): Remove additional checks of snap->has_more_to_sync and |
| 626 // snap->unsynced_count once http://crbug.com/48989 is fixed. | 730 // snap->unsynced_count once http://crbug.com/48989 is fixed. |
| 627 bool is_synced = snap && | 731 bool is_synced = snap && |
| 628 snap->num_blocking_conflicting_updates == 0 && | 732 snap->num_blocking_conflicting_updates == 0 && |
| 629 ServiceIsPushingChanges() && | 733 ServiceIsPushingChanges() && |
| 630 GetStatus().notifications_enabled && | 734 GetStatus().notifications_enabled && |
| 631 !service()->HasUnsyncedItems() && | 735 !service()->HasUnsyncedItems() && |
| 632 !snap->has_more_to_sync && | 736 !snap->has_more_to_sync && |
| 633 snap->unsynced_count == 0 && | 737 snap->unsynced_count == 0 && |
| 634 !service()->HasPendingBackendMigration() && | 738 !HasPendingBackendMigration() && |
| 635 service()->passphrase_required_reason() != | 739 service()->passphrase_required_reason() != |
| 636 sync_api::REASON_SET_PASSPHRASE_FAILED; | 740 sync_api::REASON_SET_PASSPHRASE_FAILED; |
| 637 VLOG(1) << GetClientInfoString( | 741 VLOG(1) << GetClientInfoString( |
| 638 is_synced ? "IsSynced: true" : "IsSynced: false"); | 742 is_synced ? "IsSynced: true" : "IsSynced: false"); |
| 639 return is_synced; | 743 return is_synced; |
| 640 } | 744 } |
| 641 | 745 |
| 746 bool ProfileSyncServiceHarness::HasPendingBackendMigration() { |
| 747 browser_sync::BackendMigrator* migrator = |
| 748 service()->GetBackendMigratorForTest(); |
| 749 return migrator && migrator->state() != browser_sync::BackendMigrator::IDLE; |
| 750 } |
| 751 |
| 642 bool ProfileSyncServiceHarness::MatchesOtherClient( | 752 bool ProfileSyncServiceHarness::MatchesOtherClient( |
| 643 ProfileSyncServiceHarness* partner) { | 753 ProfileSyncServiceHarness* partner) { |
| 644 if (!IsSynced()) | 754 // TODO(akalin): Shouldn't this belong with the intersection check? |
| 755 // Otherwise, this function isn't symmetric. |
| 756 if (!IsSynced()) { |
| 757 VLOG(2) << profile_debug_name_ << ": not synced, assuming doesn't match"; |
| 645 return false; | 758 return false; |
| 759 } |
| 646 | 760 |
| 647 // Only look for a match if we have at least one enabled datatype in | 761 // Only look for a match if we have at least one enabled datatype in |
| 648 // common with the partner client. | 762 // common with the partner client. |
| 649 syncable::ModelTypeSet types, other_types, intersection_types; | 763 syncable::ModelTypeSet types, other_types, intersection_types; |
| 650 service()->GetPreferredDataTypes(&types); | 764 service()->GetPreferredDataTypes(&types); |
| 651 partner->service()->GetPreferredDataTypes(&other_types); | 765 partner->service()->GetPreferredDataTypes(&other_types); |
| 652 std::set_intersection(types.begin(), types.end(), other_types.begin(), | 766 std::set_intersection(types.begin(), types.end(), other_types.begin(), |
| 653 other_types.end(), | 767 other_types.end(), |
| 654 inserter(intersection_types, | 768 inserter(intersection_types, |
| 655 intersection_types.begin())); | 769 intersection_types.begin())); |
| 770 |
| 771 VLOG(2) << profile_debug_name_ << ", " << partner->profile_debug_name_ |
| 772 << ": common types are " |
| 773 << syncable::ModelTypeSetToString(intersection_types); |
| 774 |
| 775 if (!intersection_types.empty() && !partner->IsSynced()) { |
| 776 VLOG(2) << "non-empty common types and " |
| 777 << partner->profile_debug_name_ << " isn't synced"; |
| 778 return false; |
| 779 } |
| 780 |
| 656 for (syncable::ModelTypeSet::iterator i = intersection_types.begin(); | 781 for (syncable::ModelTypeSet::iterator i = intersection_types.begin(); |
| 657 i != intersection_types.end(); | 782 i != intersection_types.end(); ++i) { |
| 658 ++i) { | 783 const std::string timestamp = GetUpdatedTimestamp(*i); |
| 659 if (!partner->IsSynced() || | 784 const std::string partner_timestamp = partner->GetUpdatedTimestamp(*i); |
| 660 partner->GetUpdatedTimestamp(*i) != GetUpdatedTimestamp(*i)) { | 785 if (timestamp != partner_timestamp) { |
| 786 if (VLOG_IS_ON(2)) { |
| 787 std::string timestamp_base64, partner_timestamp_base64; |
| 788 if (!base::Base64Encode(timestamp, ×tamp_base64)) { |
| 789 NOTREACHED(); |
| 790 } |
| 791 if (!base::Base64Encode( |
| 792 partner_timestamp, &partner_timestamp_base64)) { |
| 793 NOTREACHED(); |
| 794 } |
| 795 VLOG(2) << syncable::ModelTypeToString(*i) << ": " |
| 796 << profile_debug_name_ << " timestamp = " |
| 797 << timestamp_base64 << ", " |
| 798 << partner->profile_debug_name_ |
| 799 << " partner timestamp = " |
| 800 << partner_timestamp_base64; |
| 801 } |
| 661 return false; | 802 return false; |
| 662 } | 803 } |
| 663 } | 804 } |
| 664 return true; | 805 return true; |
| 665 } | 806 } |
| 666 | 807 |
| 667 const SyncSessionSnapshot* | 808 const SyncSessionSnapshot* |
| 668 ProfileSyncServiceHarness::GetLastSessionSnapshot() const { | 809 ProfileSyncServiceHarness::GetLastSessionSnapshot() const { |
| 669 DCHECK(service_ != NULL) << "Sync service has not yet been set up."; | 810 DCHECK(service_ != NULL) << "Sync service has not yet been set up."; |
| 670 if (service_->sync_initialized()) { | 811 if (service_->sync_initialized()) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 << ", num_updates_downloaded : " | 958 << ", num_updates_downloaded : " |
| 818 << snap->syncer_status.num_updates_downloaded_total | 959 << snap->syncer_status.num_updates_downloaded_total |
| 819 << ", passphrase_required_reason: " | 960 << ", passphrase_required_reason: " |
| 820 << sync_api::PassphraseRequiredReasonToString( | 961 << sync_api::PassphraseRequiredReasonToString( |
| 821 service()->passphrase_required_reason()) | 962 service()->passphrase_required_reason()) |
| 822 << ", notifications_enabled: " | 963 << ", notifications_enabled: " |
| 823 << status.notifications_enabled | 964 << status.notifications_enabled |
| 824 << ", service_is_pushing_changes: " | 965 << ", service_is_pushing_changes: " |
| 825 << ServiceIsPushingChanges() | 966 << ServiceIsPushingChanges() |
| 826 << ", has_pending_backend_migration: " | 967 << ", has_pending_backend_migration: " |
| 827 << service()->HasPendingBackendMigration(); | 968 << HasPendingBackendMigration(); |
| 828 } else { | 969 } else { |
| 829 os << "Sync session snapshot not available"; | 970 os << "Sync session snapshot not available"; |
| 830 } | 971 } |
| 831 } else { | 972 } else { |
| 832 os << "Sync service not available"; | 973 os << "Sync service not available"; |
| 833 } | 974 } |
| 834 return os.str(); | 975 return os.str(); |
| 835 } | 976 } |
| 836 | 977 |
| 837 bool ProfileSyncServiceHarness::EnableEncryptionForType( | 978 bool ProfileSyncServiceHarness::EnableEncryptionForType( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 return (synced_types.count(type) != 0); | 1036 return (synced_types.count(type) != 0); |
| 896 } | 1037 } |
| 897 | 1038 |
| 898 std::string ProfileSyncServiceHarness::GetServiceStatus() { | 1039 std::string ProfileSyncServiceHarness::GetServiceStatus() { |
| 899 DictionaryValue value; | 1040 DictionaryValue value; |
| 900 sync_ui_util::ConstructAboutInformation(service_, &value); | 1041 sync_ui_util::ConstructAboutInformation(service_, &value); |
| 901 std::string service_status; | 1042 std::string service_status; |
| 902 base::JSONWriter::Write(&value, true, &service_status); | 1043 base::JSONWriter::Write(&value, true, &service_status); |
| 903 return service_status; | 1044 return service_status; |
| 904 } | 1045 } |
| OLD | NEW |