blob: 830ca782f36e49c20aa983ce0cd0b40ed826d7a4 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/sync/engine/model_type_registry.h"
#include <stddef.h>
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "components/sync/engine/data_type_activation_response.h"
#include "components/sync/engine/model_type_processor.h"
#include "components/sync/engine/model_type_worker.h"
#include "components/sync/engine/nigori/cryptographer.h"
#include "components/sync/engine/nigori/keystore_keys_handler.h"
namespace syncer {
ModelTypeRegistry::ModelTypeRegistry(
NudgeHandler* nudge_handler,
CancelationSignal* cancelation_signal,
SyncEncryptionHandler* sync_encryption_handler)
: nudge_handler_(nudge_handler),
cancelation_signal_(cancelation_signal),
sync_encryption_handler_(sync_encryption_handler) {
sync_encryption_handler_->AddObserver(this);
}
ModelTypeRegistry::~ModelTypeRegistry() {
sync_encryption_handler_->RemoveObserver(this);
}
void ModelTypeRegistry::ConnectDataType(
ModelType type,
std::unique_ptr<DataTypeActivationResponse> activation_response) {
DCHECK(ProtocolTypes().Has(type));
DCHECK(update_handler_map_.find(type) == update_handler_map_.end());
DCHECK(commit_contributor_map_.find(type) == commit_contributor_map_.end());
DCHECK(activation_response);
DCHECK(!activation_response->skip_engine_connection);
DCHECK(activation_response->type_processor);
DVLOG(1) << "Enabling an off-thread sync type: " << ModelTypeToString(type);
auto worker = std::make_unique<ModelTypeWorker>(
type, activation_response->model_type_state,
sync_encryption_handler_->GetCryptographer(),
sync_encryption_handler_->GetEncryptedTypes().Has(type),
sync_encryption_handler_->GetPassphraseType(), nudge_handler_,
cancelation_signal_);
// Save a raw pointer and add the worker to our structures.
ModelTypeWorker* worker_ptr = worker.get();
connected_model_type_workers_.push_back(std::move(worker));
update_handler_map_.insert(std::make_pair(type, worker_ptr));
commit_contributor_map_.insert(std::make_pair(type, worker_ptr));
worker_ptr->ConnectSync(std::move(activation_response->type_processor));
}
void ModelTypeRegistry::DisconnectDataType(ModelType type) {
if (update_handler_map_.count(type) == 0) {
// Type not connected. Simply ignore.
return;
}
DVLOG(1) << "Disabling an off-thread sync type: " << ModelTypeToString(type);
DCHECK(ProtocolTypes().Has(type));
DCHECK(update_handler_map_.find(type) != update_handler_map_.end());
DCHECK(commit_contributor_map_.find(type) != commit_contributor_map_.end());
size_t updaters_erased = update_handler_map_.erase(type);
size_t committers_erased = commit_contributor_map_.erase(type);
DCHECK_EQ(1U, updaters_erased);
DCHECK_EQ(1U, committers_erased);
auto iter = connected_model_type_workers_.begin();
while (iter != connected_model_type_workers_.end()) {
if ((*iter)->GetModelType() == type) {
iter = connected_model_type_workers_.erase(iter);
} else {
++iter;
}
}
}
void ModelTypeRegistry::SetProxyTabsDatatypeEnabled(bool enabled) {
proxy_tabs_datatype_enabled_ = enabled;
}
ModelTypeSet ModelTypeRegistry::GetConnectedTypes() const {
ModelTypeSet types;
for (const auto& worker : connected_model_type_workers_) {
types.Put(worker->GetModelType());
}
return types;
}
bool ModelTypeRegistry::proxy_tabs_datatype_enabled() const {
return proxy_tabs_datatype_enabled_;
}
ModelTypeSet ModelTypeRegistry::GetInitialSyncEndedTypes() const {
ModelTypeSet result;
for (const auto& [type, update_handler] : update_handler_map_) {
if (update_handler->IsInitialSyncEnded())
result.Put(type);
}
return result;
}
const UpdateHandler* ModelTypeRegistry::GetUpdateHandler(ModelType type) const {
auto it = update_handler_map_.find(type);
return it == update_handler_map_.end() ? nullptr : it->second;
}
UpdateHandlerMap* ModelTypeRegistry::update_handler_map() {
return &update_handler_map_;
}
CommitContributorMap* ModelTypeRegistry::commit_contributor_map() {
return &commit_contributor_map_;
}
KeystoreKeysHandler* ModelTypeRegistry::keystore_keys_handler() {
return sync_encryption_handler_->GetKeystoreKeysHandler();
}
bool ModelTypeRegistry::HasUnsyncedItems() const {
// For model type workers, we ask them individually.
for (const auto& worker : connected_model_type_workers_) {
if (worker->HasLocalChangesForTest()) {
return true;
}
}
return false;
}
base::WeakPtr<ModelTypeConnector> ModelTypeRegistry::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void ModelTypeRegistry::OnPassphraseRequired(
const KeyDerivationParams& key_derivation_params,
const sync_pb::EncryptedData& pending_keys) {}
void ModelTypeRegistry::OnPassphraseAccepted() {}
void ModelTypeRegistry::OnTrustedVaultKeyRequired() {}
void ModelTypeRegistry::OnTrustedVaultKeyAccepted() {}
void ModelTypeRegistry::OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
bool encrypt_everything) {
// This does NOT support disabling encryption without reconnecting the
// type, i.e. recreating its ModelTypeWorker.
for (const auto& worker : connected_model_type_workers_) {
if (encrypted_types.Has(worker->GetModelType())) {
// No-op if the type was already encrypted.
worker->EnableEncryption();
}
}
}
void ModelTypeRegistry::OnCryptographerStateChanged(
Cryptographer* cryptographer,
bool has_pending_keys) {
for (const auto& worker : connected_model_type_workers_) {
worker->OnCryptographerChange();
}
}
void ModelTypeRegistry::OnPassphraseTypeChanged(PassphraseType type,
base::Time passphrase_time) {
for (const auto& worker : connected_model_type_workers_) {
worker->UpdatePassphraseType(type);
}
}
} // namespace syncer