15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/backend_migrator.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/configure_reason.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/read_transaction.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/directory.h" // TODO(tim): Bug 131130. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::ModelTypeSet; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::ModelTypeToString; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MigrationObserver::~MigrationObserver() {} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackendMigrator::BackendMigrator(const std::string& name, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::UserShare* user_share, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* service, 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::DataTypeManager* manager, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure &migration_done_callback) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : name_(name), user_share_(user_share), service_(service), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_(manager), state_(IDLE), 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) migration_done_callback_(migration_done_callback), 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackendMigrator::~BackendMigrator() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macros to log with the syncer thread name; useful when there 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are multiple syncer threads involved. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SLOG(severity) LOG(severity) << name_ << ": " 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::MigrateTypes(syncer::ModelTypeSet types) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelTypeSet old_to_migrate = to_migrate_; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_migrate_.PutAll(types); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "MigrateTypes called with " << ModelTypeSetToString(types) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", old_to_migrate = " << ModelTypeSetToString(old_to_migrate) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", to_migrate_ = " << ModelTypeSetToString(to_migrate_); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_to_migrate.Equals(to_migrate_)) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "MigrateTypes called with no new types; ignoring"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == IDLE) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeState(WAITING_TO_START); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == WAITING_TO_START) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TryStart()) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "Manager not configured; waiting"; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(state_, WAITING_TO_START); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're already migrating, interrupt the current migration. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartMigration(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::AddMigrationObserver(MigrationObserver* observer) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) migration_observers_.AddObserver(observer); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BackendMigrator::HasMigrationObserver( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MigrationObserver* observer) const { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return migration_observers_.HasObserver(observer); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::RemoveMigrationObserver(MigrationObserver* observer) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) migration_observers_.RemoveObserver(observer); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::ChangeState(State new_state) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = new_state; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(MigrationObserver, migration_observers_, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnMigrationStateChange()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BackendMigrator::TryStart() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, WAITING_TO_START); 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (manager_->state() == sync_driver::DataTypeManager::CONFIGURED) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartMigration(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::RestartMigration() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll now disable any running types that need to be migrated. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeState(DISABLING_TYPES); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "BackendMigrator disabling types " 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ModelTypeSetToString(to_migrate_); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->PurgeForMigration(to_migrate_, syncer::CONFIGURE_REASON_MIGRATION); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::OnConfigureDone( 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const sync_driver::DataTypeManager::ConfigureResult& result) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == IDLE) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |manager_|'s methods aren't re-entrant, and we're notified from 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them, so post a task to avoid problems. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "Posting OnConfigureDoneImpl"; 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BackendMigrator::OnConfigureDoneImpl, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), result)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::ModelTypeSet GetUnsyncedDataTypes(syncer::UserShare* user_share) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::ReadTransaction trans(FROM_HERE, user_share); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::ModelTypeSet unsynced_data_types; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = syncer::FIRST_REAL_MODEL_TYPE; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i < syncer::MODEL_TYPE_COUNT; ++i) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::ModelType type = syncer::ModelTypeFromInt(i); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::DataTypeProgressMarker progress_marker; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trans.GetDirectory()->GetDownloadProgress(type, &progress_marker); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (progress_marker.token().empty()) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsynced_data_types.Put(type); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return unsynced_data_types; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackendMigrator::OnConfigureDoneImpl( 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const sync_driver::DataTypeManager::ConfigureResult& result) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "OnConfigureDone with requested types " 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ModelTypeSetToString(result.requested_types) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", status " << result.status 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", and to_migrate_ = " << ModelTypeSetToString(to_migrate_); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == WAITING_TO_START) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TryStart()) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "Manager still not configured; still waiting"; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(state_, WAITING_TO_START); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelTypeSet intersection = 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Intersection(result.requested_types, to_migrate_); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This intersection check is to determine if our disable request 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was interrupted by a user changing preferred types. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == DISABLING_TYPES && !intersection.Empty()) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "Disable request interrupted by user changing types"; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartMigration(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (result.status != sync_driver::DataTypeManager::OK) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this fails, and we're disabling types, a type may or may not be 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disabled until the user restarts the browser. If this wasn't an abort, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any failure will be reported as an unrecoverable error to the UI. If it 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was an abort, then typically things are shutting down anyway. There isn't 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // much we can do in any case besides wait until a restart to try again. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The server will send down MIGRATION_DONE again for types needing 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // migration as the type will still be enabled on restart. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SLOG(WARNING) << "Unable to migrate, configuration failed!"; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeState(IDLE); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_migrate_.Clear(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == DISABLING_TYPES) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::ModelTypeSet unsynced_types = 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUnsyncedDataTypes(user_share_); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!unsynced_types.HasAll(to_migrate_)) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SLOG(WARNING) << "Set of unsynced types: " 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << syncer::ModelTypeSetToString(unsynced_types) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " does not contain types to migrate: " 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << syncer::ModelTypeSetToString(to_migrate_) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "; not re-enabling yet"; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeState(REENABLING_TYPES); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't use |to_migrate_| for the re-enabling because the user 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may have chosen to disable types during the migration. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelTypeSet full_set = service_->GetPreferredDataTypes(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "BackendMigrator re-enabling types: " 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << syncer::ModelTypeSetToString(full_set); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->Configure(full_set, syncer::CONFIGURE_REASON_MIGRATION); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (state_ == REENABLING_TYPES) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're done! 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeState(IDLE); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDVLOG(1) << "BackendMigrator: Migration complete for: " 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << syncer::ModelTypeSetToString(to_migrate_); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_migrate_.Clear(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!migration_done_callback_.is_null()) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) migration_done_callback_.Run(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackendMigrator::State BackendMigrator::state() const { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state_; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::ModelTypeSet BackendMigrator::GetPendingMigrationTypesForTest() const { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return to_migrate_; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef SDVLOG 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef SLOG 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; // namespace browser_sync 226