| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "chrome/browser/prefs/pref_service.h" | 11 #include "chrome/browser/prefs/pref_service.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/net/gaia/token_service.h" | 13 #include "chrome/browser/net/gaia/token_service.h" |
| 14 #include "chrome/browser/sync/glue/sync_backend_host.h" | 14 #include "chrome/browser/sync/glue/sync_backend_host.h" |
| 15 #include "chrome/browser/sync/sessions/session_state.h" | 15 #include "chrome/browser/sync/sessions/session_state.h" |
| 16 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
| 17 #include "chrome/common/net/gaia/gaia_constants.h" | 17 #include "chrome/common/net/gaia/gaia_constants.h" |
| 18 #include "chrome/common/net/gaia/google_service_auth_error.h" | 18 #include "chrome/common/net/gaia/google_service_auth_error.h" |
| 19 #include "chrome/common/notification_source.h" | 19 #include "chrome/common/notification_source.h" |
| 20 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
| 21 | 21 |
| 22 // The default value for min_timestamp_needed_ when we're not in the | |
| 23 // WAITING_FOR_UPDATES state. | |
| 24 static const int kMinTimestampNeededNone = -1; | |
| 25 | |
| 26 // The amount of time for which we wait for a live sync operation to complete. | 22 // The amount of time for which we wait for a live sync operation to complete. |
| 27 static const int kLiveSyncOperationTimeoutMs = 30000; | 23 static const int kLiveSyncOperationTimeoutMs = 30000; |
| 28 | 24 |
| 29 // Simple class to implement a timeout using PostDelayedTask. If it is not | 25 // Simple class to implement a timeout using PostDelayedTask. If it is not |
| 30 // aborted before picked up by a message queue, then it asserts with the message | 26 // aborted before picked up by a message queue, then it asserts with the message |
| 31 // provided. This class is not thread safe. | 27 // provided. This class is not thread safe. |
| 32 class StateChangeTimeoutEvent | 28 class StateChangeTimeoutEvent |
| 33 : public base::RefCountedThreadSafe<StateChangeTimeoutEvent> { | 29 : public base::RefCountedThreadSafe<StateChangeTimeoutEvent> { |
| 34 public: | 30 public: |
| 35 StateChangeTimeoutEvent(ProfileSyncServiceHarness* caller, | 31 StateChangeTimeoutEvent(ProfileSyncServiceHarness* caller, |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 LogClientInfo("WAITING_FOR_SYNC_TO_FINISH"); | 249 LogClientInfo("WAITING_FOR_SYNC_TO_FINISH"); |
| 254 if (!IsSynced()) { | 250 if (!IsSynced()) { |
| 255 // The client is not yet fully synced. Continue waiting. | 251 // The client is not yet fully synced. Continue waiting. |
| 256 if (!GetStatus().server_reachable) { | 252 if (!GetStatus().server_reachable) { |
| 257 // The client cannot reach the sync server because the network is | 253 // The client cannot reach the sync server because the network is |
| 258 // disabled. There is no need to wait anymore. | 254 // disabled. There is no need to wait anymore. |
| 259 SignalStateCompleteWithNextState(SERVER_UNREACHABLE); | 255 SignalStateCompleteWithNextState(SERVER_UNREACHABLE); |
| 260 } | 256 } |
| 261 break; | 257 break; |
| 262 } | 258 } |
| 263 GetUpdatedTimestamp(); | |
| 264 SignalStateCompleteWithNextState(FULLY_SYNCED); | 259 SignalStateCompleteWithNextState(FULLY_SYNCED); |
| 265 break; | 260 break; |
| 266 } | 261 } |
| 267 case WAITING_FOR_UPDATES: { | 262 case WAITING_FOR_UPDATES: { |
| 268 LogClientInfo("WAITING_FOR_UPDATES"); | 263 LogClientInfo("WAITING_FOR_UPDATES"); |
| 269 DCHECK(timestamp_match_partner_); | 264 DCHECK(timestamp_match_partner_); |
| 270 if (!MatchesOtherClient(timestamp_match_partner_)) { | 265 if (!MatchesOtherClient(timestamp_match_partner_)) { |
| 271 // The client is not yet fully synced; keep waiting until we converge. | 266 // The client is not yet fully synced; keep waiting until we converge. |
| 272 break; | 267 break; |
| 273 } | 268 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } else if (wait_state_ == SERVER_UNREACHABLE) { | 337 } else if (wait_state_ == SERVER_UNREACHABLE) { |
| 343 // Client is offline; sync was unsuccessful. | 338 // Client is offline; sync was unsuccessful. |
| 344 return false; | 339 return false; |
| 345 } else { | 340 } else { |
| 346 LOG(ERROR) << "Invalid wait state:" << wait_state_; | 341 LOG(ERROR) << "Invalid wait state:" << wait_state_; |
| 347 return false; | 342 return false; |
| 348 } | 343 } |
| 349 } | 344 } |
| 350 } else { | 345 } else { |
| 351 // Client is already synced; don't wait. | 346 // Client is already synced; don't wait. |
| 352 GetUpdatedTimestamp(); | |
| 353 return true; | 347 return true; |
| 354 } | 348 } |
| 355 } | 349 } |
| 356 | 350 |
| 357 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( | 351 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( |
| 358 ProfileSyncServiceHarness* partner) { | 352 ProfileSyncServiceHarness* partner) { |
| 359 LogClientInfo("AwaitMutualSyncCycleCompletion"); | 353 LogClientInfo("AwaitMutualSyncCycleCompletion"); |
| 360 if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) | 354 if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) |
| 361 return false; | 355 return false; |
| 362 return partner->WaitUntilTimestampMatches(this, | 356 return partner->WaitUntilTimestampMatches(this, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 | 462 |
| 469 // Only look for a match if we have at least one enabled datatype in | 463 // Only look for a match if we have at least one enabled datatype in |
| 470 // common with the partner client. | 464 // common with the partner client. |
| 471 syncable::ModelTypeSet types, other_types, intersection_types; | 465 syncable::ModelTypeSet types, other_types, intersection_types; |
| 472 service()->GetPreferredDataTypes(&types); | 466 service()->GetPreferredDataTypes(&types); |
| 473 partner->service()->GetPreferredDataTypes(&other_types); | 467 partner->service()->GetPreferredDataTypes(&other_types); |
| 474 std::set_intersection(types.begin(), types.end(), other_types.begin(), | 468 std::set_intersection(types.begin(), types.end(), other_types.begin(), |
| 475 other_types.end(), | 469 other_types.end(), |
| 476 inserter(intersection_types, | 470 inserter(intersection_types, |
| 477 intersection_types.begin())); | 471 intersection_types.begin())); |
| 478 if (intersection_types.empty()) { | 472 for (syncable::ModelTypeSet::iterator i = intersection_types.begin(); |
| 479 return true; | 473 i != intersection_types.end(); |
| 474 ++i) { |
| 475 if (!partner->IsSynced() || |
| 476 partner->GetUpdatedTimestamp(*i) != GetUpdatedTimestamp(*i)) { |
| 477 return false; |
| 478 } |
| 480 } | 479 } |
| 481 return partner->IsSynced() && | 480 return true; |
| 482 partner->GetUpdatedTimestamp() == GetUpdatedTimestamp(); | |
| 483 } | 481 } |
| 484 | 482 |
| 485 const SyncSessionSnapshot* | 483 const SyncSessionSnapshot* |
| 486 ProfileSyncServiceHarness::GetLastSessionSnapshot() const { | 484 ProfileSyncServiceHarness::GetLastSessionSnapshot() const { |
| 487 DCHECK(service_ != NULL) << "Sync service has not yet been set up."; | 485 DCHECK(service_ != NULL) << "Sync service has not yet been set up."; |
| 488 if (service_->backend()) { | 486 if (service_->backend()) { |
| 489 return service_->backend()->GetLastSessionSnapshot(); | 487 return service_->backend()->GetLastSessionSnapshot(); |
| 490 } | 488 } |
| 491 return NULL; | 489 return NULL; |
| 492 } | 490 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 void ProfileSyncServiceHarness::DisableSyncForAllDatatypes() { | 560 void ProfileSyncServiceHarness::DisableSyncForAllDatatypes() { |
| 563 LogClientInfo("DisableSyncForAllDatatypes"); | 561 LogClientInfo("DisableSyncForAllDatatypes"); |
| 564 DCHECK(service() != NULL) << "EnableSyncForAllDatatypes(): service() is " | 562 DCHECK(service() != NULL) << "EnableSyncForAllDatatypes(): service() is " |
| 565 "null."; | 563 "null."; |
| 566 service()->DisableForUser(); | 564 service()->DisableForUser(); |
| 567 wait_state_ = SYNC_DISABLED; | 565 wait_state_ = SYNC_DISABLED; |
| 568 VLOG(1) << "DisableSyncForAllDatatypes(): Disabled sync for all datatypes on " | 566 VLOG(1) << "DisableSyncForAllDatatypes(): Disabled sync for all datatypes on " |
| 569 "Client " << id_; | 567 "Client " << id_; |
| 570 } | 568 } |
| 571 | 569 |
| 572 int64 ProfileSyncServiceHarness::GetUpdatedTimestamp() { | 570 std::string ProfileSyncServiceHarness::GetUpdatedTimestamp( |
| 571 syncable::ModelType model_type) { |
| 573 const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); | 572 const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); |
| 574 DCHECK(snap != NULL) << "GetUpdatedTimestamp(): Sync snapshot is NULL."; | 573 DCHECK(snap != NULL) << "GetUpdatedTimestamp(): Sync snapshot is NULL."; |
| 575 return snap->max_local_timestamp; | 574 return snap->download_progress_markers[model_type]; |
| 576 } | 575 } |
| 577 | 576 |
| 578 void ProfileSyncServiceHarness::LogClientInfo(std::string message) { | 577 void ProfileSyncServiceHarness::LogClientInfo(std::string message) { |
| 579 if (service()) { | 578 if (service()) { |
| 580 const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); | 579 const SyncSessionSnapshot* snap = GetLastSessionSnapshot(); |
| 581 if (snap) { | 580 if (snap) { |
| 582 VLOG(1) << "Client " << id_ << ": " << message | 581 VLOG(1) << "Client " << id_ << ": " << message |
| 583 << ": max_local_timestamp: " << snap->max_local_timestamp | 582 << ": num_updates_downloaded : " |
| 583 << snap->syncer_status.num_updates_downloaded_total |
| 584 << ", has_more_to_sync: " << snap->has_more_to_sync | 584 << ", has_more_to_sync: " << snap->has_more_to_sync |
| 585 << ", unsynced_count: " << snap->unsynced_count | 585 << ", unsynced_count: " << snap->unsynced_count |
| 586 << ", num_conflicting_updates: " << snap->num_conflicting_updates | 586 << ", num_conflicting_updates: " << snap->num_conflicting_updates |
| 587 << ", has_unsynced_items: " | 587 << ", has_unsynced_items: " |
| 588 << service()->backend()->HasUnsyncedItems() | 588 << service()->backend()->HasUnsyncedItems() |
| 589 << ", observed_passphrase_required: " | 589 << ", observed_passphrase_required: " |
| 590 << service()->observed_passphrase_required() | 590 << service()->observed_passphrase_required() |
| 591 << ", notifications_enabled: " | 591 << ", notifications_enabled: " |
| 592 << GetStatus().notifications_enabled | 592 << GetStatus().notifications_enabled |
| 593 << ", service_is_pushing_changes: " << ServiceIsPushingChanges(); | 593 << ", service_is_pushing_changes: " << ServiceIsPushingChanges(); |
| 594 } else { | 594 } else { |
| 595 VLOG(1) << "Client " << id_ << ": " << message | 595 VLOG(1) << "Client " << id_ << ": " << message |
| 596 << ": Sync session snapshot not available."; | 596 << ": Sync session snapshot not available."; |
| 597 } | 597 } |
| 598 } else { | 598 } else { |
| 599 VLOG(1) << "Client " << id_ << ": " << message | 599 VLOG(1) << "Client " << id_ << ": " << message |
| 600 << ": Sync service not available."; | 600 << ": Sync service not available."; |
| 601 } | 601 } |
| 602 } | 602 } |
| OLD | NEW |