sync_backend_registrar.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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,
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop* sync_loop) :
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_(name),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_(profile),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_loop_(sync_loop),
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ui_worker_(new UIModelWorker(this)),
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_);
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  workers_[syncer::GROUP_DB] = new DatabaseModelWorker(this);
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  workers_[syncer::GROUP_FILE] = new FileModelWorker(this);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  workers_[syncer::GROUP_UI] = ui_worker_;
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  workers_[syncer::GROUP_PASSIVE] = new syncer::PassiveModelWorker(sync_loop_,
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                                                   this);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* history_service =
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HistoryServiceFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (history_service) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_[syncer::GROUP_HISTORY] =
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new HistoryModelWorker(history_service->AsWeakPtr(), this);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PasswordStore> password_store =
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PasswordStoreFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (password_store.get()) {
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    workers_[syncer::GROUP_PASSWORD] =
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new PasswordModelWorker(password_store, this);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::SetInitialTypes(syncer::ModelTypeSet initial_types) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function should be called only once, shortly after construction.  The
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // routing info at that point is expected to be emtpy.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(routing_info_.empty());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set our initial state to reflect the current status of the sync directory.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will ensure that our calculations in ConfigureDataTypes() will always
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return correct results.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::ModelTypeSet::Iterator it = initial_types.First();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it.Good(); it.Inc()) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[it.Get()] = syncer::GROUP_PASSIVE;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!workers_.count(syncer::GROUP_HISTORY)) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(WARNING, initial_types.Has(syncer::TYPED_URLS))
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "History store disabled, cannot sync Omnibox History";
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_.erase(syncer::TYPED_URLS);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!workers_.count(syncer::GROUP_PASSWORD)) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(WARNING, initial_types.Has(syncer::PASSWORDS))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Password store not initialized, cannot sync passwords";
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_.erase(syncer::PASSWORDS);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncBackendRegistrar::~SyncBackendRegistrar() {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(stopped_on_ui_thread_);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncBackendRegistrar::IsNigoriEnabled() const {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return routing_info_.find(syncer::NIGORI) != routing_info_.end();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::ModelTypeSet SyncBackendRegistrar::ConfigureDataTypes(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelTypeSet types_to_add,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelTypeSet types_to_remove) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(Intersection(types_to_add, types_to_remove).Empty());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelTypeSet filtered_types_to_add = types_to_add;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (workers_.count(syncer::GROUP_HISTORY) == 0) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "No history worker -- removing TYPED_URLS";
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filtered_types_to_add.Remove(syncer::TYPED_URLS);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (workers_.count(syncer::GROUP_PASSWORD) == 0) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "No password worker -- removing PASSWORDS";
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filtered_types_to_add.Remove(syncer::PASSWORDS);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelTypeSet newly_added_types;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::ModelTypeSet::Iterator it =
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           filtered_types_to_add.First();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it.Good(); it.Inc()) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add a newly specified data type as syncer::GROUP_PASSIVE into the
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // routing_info, if it does not already exist.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (routing_info_.count(it.Get()) == 0) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      routing_info_[it.Get()] = syncer::GROUP_PASSIVE;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      newly_added_types.Put(it.Get());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::ModelTypeSet::Iterator it = types_to_remove.First();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it.Good(); it.Inc()) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_.erase(it.Get());
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Use SVLOG/SLOG if we add any more logging.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << name_ << ": Adding types "
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << syncer::ModelTypeSetToString(types_to_add)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " (with newly-added types "
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << syncer::ModelTypeSetToString(newly_added_types)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << ") and removing types "
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << syncer::ModelTypeSetToString(types_to_remove)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " to get new routing info "
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           <<syncer::ModelSafeRoutingInfoToString(routing_info_);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return newly_added_types;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::StopOnUIThread() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!stopped_on_ui_thread_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_worker_->Stop();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stopped_on_ui_thread_ = true;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::OnSyncerShutdownComplete() {
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_worker_->OnSyncerShutdownComplete();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::ActivateDataType(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelSafeGroup group,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChangeProcessor* change_processor,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::UserShare* user_share) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(IsOnThreadForGroup(type, group));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the given data type is in the PASSIVE group.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelSafeRoutingInfo::iterator i = routing_info_.find(type);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(i != routing_info_.end());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(i->second, syncer::GROUP_PASSIVE);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  routing_info_[type] = group;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(IsCurrentThreadSafeForModel(type));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the data type's change processor to the list of change
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processors so it can receive updates.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(processors_.count(type), 0U);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processors_[type] = change_processor;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the change processor.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_processor->Start(profile_, user_share);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(GetProcessorUnsafe(type));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::DeactivateDataType(syncer::ModelType type) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || IsControlType(type));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  routing_info_.erase(type);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ignore_result(processors_.erase(type));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!GetProcessorUnsafe(type));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncBackendRegistrar::IsTypeActivatedForTest(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetProcessor(type) != NULL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::OnChangesApplied(
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType model_type,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 model_version,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::BaseTransaction* trans,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::ImmutableChangeRecordList& changes) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChangeProcessor* processor = GetProcessor(model_type);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!processor)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor->ApplyChangesFromSyncModel(trans, model_version, changes);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::OnChangesComplete(syncer::ModelType model_type) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChangeProcessor* processor = GetProcessor(model_type);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!processor)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This call just notifies the processor that it can commit; it
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already buffered any changes it plans to makes so needs no
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // further information.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor->CommitChangesFromSyncModel();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::GetWorkers(
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<syncer::ModelSafeWorker*>* out) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->clear();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (WorkerMap::const_iterator it = workers_.begin();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != workers_.end(); ++it) {
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    out->push_back(it->second.get());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncBackendRegistrar::GetModelSafeRoutingInfo(
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelSafeRoutingInfo* out) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::ModelSafeRoutingInfo copy(routing_info_);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->swap(copy);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChangeProcessor* SyncBackendRegistrar::GetProcessor(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock lock(lock_);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChangeProcessor* processor = GetProcessorUnsafe(type);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!processor)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can only check if |processor| exists, as otherwise the type is
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mapped to syncer::GROUP_PASSIVE.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(IsCurrentThreadSafeForModel(type));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return processor;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChangeProcessor* SyncBackendRegistrar::GetProcessorUnsafe(
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<syncer::ModelType, ChangeProcessor*>::const_iterator it =
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      processors_.find(type);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Until model association happens for a datatype, it will not
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // appear in the processors list.  During this time, it is OK to
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drop changes on the floor (since model association has not
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happened yet).  When the data type is activated, model
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // association takes place then the change processor is added to the
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |processors_| list.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == processors_.end())
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it->second;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncBackendRegistrar::IsCurrentThreadSafeForModel(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType model_type) const {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IsOnThreadForGroup(model_type,
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            GetGroupForModelType(model_type, routing_info_));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void SyncBackendRegistrar::OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) {
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Do nothing for now.
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace browser_sync
305