sync_backend_registrar.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/glue/sync_backend_registrar.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstddef>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_factory.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/browser_thread_model_worker.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/change_processor.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/history_model_worker.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/password_model_worker.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/ui_model_worker.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/passive_model_worker.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the current thread is the native thread for the
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// given group (or if it is undeterminable).
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsOnThreadForGroup(syncer::ModelType type, syncer::ModelSafeGroup group) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (group) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::GROUP_PASSIVE:
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return IsControlType(type);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::GROUP_UI:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return BrowserThread::CurrentlyOn(BrowserThread::UI);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::GROUP_DB:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return BrowserThread::CurrentlyOn(BrowserThread::DB);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::GROUP_FILE:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return BrowserThread::CurrentlyOn(BrowserThread::FILE);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::GROUP_HISTORY:
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(sync): How to check we're on the right thread?
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return type == syncer::TYPED_URLS;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::GROUP_PASSWORD:
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(sync): How to check we're on the right thread?
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return type == syncer::PASSWORDS;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case syncer::MODEL_SAFE_GROUP_COUNT:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncBackendRegistrar::SyncBackendRegistrar(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name, Profile* profile,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessageLoop* sync_loop) :
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_(name),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_(profile),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_loop_(sync_loop),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_worker_(new UIModelWorker()),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stopped_on_ui_thread_(false) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(profile_);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sync_loop_);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  workers_[syncer::GROUP_DB] = new DatabaseModelWorker();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  workers_[syncer::GROUP_FILE] = new FileModelWorker();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  workers_[syncer::GROUP_UI] = ui_worker_;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  workers_[syncer::GROUP_PASSIVE] = new syncer::PassiveModelWorker(sync_loop_);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* history_service =
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HistoryServiceFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_[syncer::GROUP_HISTORY] =
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new HistoryModelWorker(history_service->AsWeakPtr());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PasswordStore> password_store =
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PasswordStoreFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (password_store.get()) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_[syncer::GROUP_PASSWORD] = new PasswordModelWorker(password_store);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::SetInitialTypes(syncer::ModelTypeSet initial_types) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function should be called only once, shortly after construction.  The
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // routing info at that point is expected to be emtpy.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(routing_info_.empty());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set our initial state to reflect the current status of the sync directory.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will ensure that our calculations in ConfigureDataTypes() will always
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return correct results.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::ModelTypeSet::Iterator it = initial_types.First();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it.Good(); it.Inc()) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[it.Get()] = syncer::GROUP_PASSIVE;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!workers_.count(syncer::GROUP_HISTORY)) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(WARNING, initial_types.Has(syncer::TYPED_URLS))
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "History store disabled, cannot sync Omnibox History";
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_.erase(syncer::TYPED_URLS);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!workers_.count(syncer::GROUP_PASSWORD)) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(WARNING, initial_types.Has(syncer::PASSWORDS))
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Password store not initialized, cannot sync passwords";
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_.erase(syncer::PASSWORDS);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncBackendRegistrar::~SyncBackendRegistrar() {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(stopped_on_ui_thread_);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncBackendRegistrar::IsNigoriEnabled() const {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return routing_info_.find(syncer::NIGORI) != routing_info_.end();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::ModelTypeSet SyncBackendRegistrar::ConfigureDataTypes(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelTypeSet types_to_add,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelTypeSet types_to_remove) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(Intersection(types_to_add, types_to_remove).Empty());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelTypeSet filtered_types_to_add = types_to_add;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (workers_.count(syncer::GROUP_HISTORY) == 0) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "No history worker -- removing TYPED_URLS";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filtered_types_to_add.Remove(syncer::TYPED_URLS);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (workers_.count(syncer::GROUP_PASSWORD) == 0) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "No password worker -- removing PASSWORDS";
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filtered_types_to_add.Remove(syncer::PASSWORDS);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelTypeSet newly_added_types;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::ModelTypeSet::Iterator it =
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           filtered_types_to_add.First();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it.Good(); it.Inc()) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add a newly specified data type as syncer::GROUP_PASSIVE into the
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // routing_info, if it does not already exist.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (routing_info_.count(it.Get()) == 0) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      routing_info_[it.Get()] = syncer::GROUP_PASSIVE;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      newly_added_types.Put(it.Get());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::ModelTypeSet::Iterator it = types_to_remove.First();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it.Good(); it.Inc()) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_.erase(it.Get());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Use SVLOG/SLOG if we add any more logging.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << name_ << ": Adding types "
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << syncer::ModelTypeSetToString(types_to_add)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " (with newly-added types "
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << syncer::ModelTypeSetToString(newly_added_types)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << ") and removing types "
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << syncer::ModelTypeSetToString(types_to_remove)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " to get new routing info "
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           <<syncer::ModelSafeRoutingInfoToString(routing_info_);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return newly_added_types;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::StopOnUIThread() {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!stopped_on_ui_thread_);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_worker_->Stop();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stopped_on_ui_thread_ = true;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::OnSyncerShutdownComplete() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(MessageLoop::current(), sync_loop_);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_worker_->OnSyncerShutdownComplete();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::ActivateDataType(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelSafeGroup group,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChangeProcessor* change_processor,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::UserShare* user_share) {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(IsOnThreadForGroup(type, group));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the given data type is in the PASSIVE group.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelSafeRoutingInfo::iterator i = routing_info_.find(type);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(i != routing_info_.end());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(i->second, syncer::GROUP_PASSIVE);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  routing_info_[type] = group;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(IsCurrentThreadSafeForModel(type));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the data type's change processor to the list of change
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processors so it can receive updates.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(processors_.count(type), 0U);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processors_[type] = change_processor;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the change processor.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_processor->Start(profile_, user_share);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(GetProcessorUnsafe(type));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::DeactivateDataType(syncer::ModelType type) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || IsControlType(type));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  routing_info_.erase(type);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ignore_result(processors_.erase(type));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!GetProcessorUnsafe(type));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncBackendRegistrar::IsTypeActivatedForTest(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetProcessor(type) != NULL;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::OnChangesApplied(
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType model_type,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 model_version,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::BaseTransaction* trans,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::ImmutableChangeRecordList& changes) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChangeProcessor* processor = GetProcessor(model_type);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!processor)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor->ApplyChangesFromSyncModel(trans, model_version, changes);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::OnChangesComplete(syncer::ModelType model_type) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChangeProcessor* processor = GetProcessor(model_type);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!processor)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This call just notifies the processor that it can commit; it
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already buffered any changes it plans to makes so needs no
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // further information.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor->CommitChangesFromSyncModel();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::GetWorkers(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<syncer::ModelSafeWorker*>* out) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->clear();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (WorkerMap::const_iterator it = workers_.begin();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != workers_.end(); ++it) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->push_back(it->second);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::GetModelSafeRoutingInfo(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelSafeRoutingInfo* out) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelSafeRoutingInfo copy(routing_info_);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->swap(copy);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChangeProcessor* SyncBackendRegistrar::GetProcessor(
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChangeProcessor* processor = GetProcessorUnsafe(type);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!processor)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can only check if |processor| exists, as otherwise the type is
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mapped to syncer::GROUP_PASSIVE.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(IsCurrentThreadSafeForModel(type));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return processor;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChangeProcessor* SyncBackendRegistrar::GetProcessorUnsafe(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<syncer::ModelType, ChangeProcessor*>::const_iterator it =
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      processors_.find(type);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Until model association happens for a datatype, it will not
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // appear in the processors list.  During this time, it is OK to
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drop changes on the floor (since model association has not
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happened yet).  When the data type is activated, model
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // association takes place then the change processor is added to the
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |processors_| list.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == processors_.end())
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it->second;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncBackendRegistrar::IsCurrentThreadSafeForModel(
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType model_type) const {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IsOnThreadForGroup(model_type,
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            GetGroupForModelType(model_type, routing_info_));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace browser_sync
299