summaryrefslogtreecommitdiffstats
path: root/sync/engine/model_type_sync_worker_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sync/engine/model_type_sync_worker_impl.cc')
-rw-r--r--sync/engine/model_type_sync_worker_impl.cc123
1 files changed, 62 insertions, 61 deletions
diff --git a/sync/engine/model_type_sync_worker_impl.cc b/sync/engine/model_type_sync_worker_impl.cc
index a58400f4..5a47f5e 100644
--- a/sync/engine/model_type_sync_worker_impl.cc
+++ b/sync/engine/model_type_sync_worker_impl.cc
@@ -22,13 +22,13 @@ ModelTypeSyncWorkerImpl::ModelTypeSyncWorkerImpl(
ModelType type,
const DataTypeState& initial_state,
const UpdateResponseDataList& saved_pending_updates,
- CryptographerProvider* cryptographer_provider,
+ scoped_ptr<Cryptographer> cryptographer,
NudgeHandler* nudge_handler,
scoped_ptr<ModelTypeSyncProxy> type_sync_proxy)
: type_(type),
data_type_state_(initial_state),
type_sync_proxy_(type_sync_proxy.Pass()),
- cryptographer_provider_(cryptographer_provider),
+ cryptographer_(cryptographer.Pass()),
nudge_handler_(nudge_handler),
entities_deleter_(&entities_),
weak_ptr_factory_(this) {
@@ -47,7 +47,11 @@ ModelTypeSyncWorkerImpl::ModelTypeSyncWorkerImpl(
entities_.insert(std::make_pair(it->client_tag_hash, entity_tracker));
}
- TryDecryptPendingUpdates();
+ if (cryptographer_) {
+ DVLOG(1) << ModelTypeToString(type_) << ": Starting with encryption key "
+ << cryptographer_->GetDefaultNigoriKeyName();
+ OnCryptographerUpdated();
+ }
}
ModelTypeSyncWorkerImpl::~ModelTypeSyncWorkerImpl() {
@@ -59,29 +63,19 @@ ModelType ModelTypeSyncWorkerImpl::GetModelType() const {
}
bool ModelTypeSyncWorkerImpl::IsEncryptionRequired() const {
- return !data_type_state_.encryption_key_name.empty();
+ return !!cryptographer_;
}
-void ModelTypeSyncWorkerImpl::SetEncryptionKeyName(const std::string& name) {
- if (data_type_state_.encryption_key_name == name)
- return;
-
- data_type_state_.encryption_key_name = name;
-
- // Pretend to send an update. This will cause the TypeSyncProxy to notice
- // the new encryption key and take appropriate action.
- type_sync_proxy_->OnUpdateReceived(
- data_type_state_, UpdateResponseDataList(), UpdateResponseDataList());
-}
+void ModelTypeSyncWorkerImpl::UpdateCryptographer(
+ scoped_ptr<Cryptographer> cryptographer) {
+ DCHECK(cryptographer);
+ cryptographer_ = cryptographer.Pass();
-void ModelTypeSyncWorkerImpl::OnCryptographerStateChanged() {
- TryDecryptPendingUpdates();
+ // Update our state and that of the proxy.
+ OnCryptographerUpdated();
- ScopedCryptographerRef scoped_cryptographer_ref;
- cryptographer_provider_->InitScopedCryptographerRef(
- &scoped_cryptographer_ref);
- Cryptographer* cryptographer = scoped_cryptographer_ref.Get();
- if (CanCommitItems(cryptographer))
+ // Nudge the scheduler if we're now allowed to commit.
+ if (CanCommitItems())
nudge_handler_->NudgeForCommit(type_);
}
@@ -109,12 +103,6 @@ SyncerError ModelTypeSyncWorkerImpl::ProcessGetUpdatesResponse(
data_type_state_.type_context = mutated_context;
data_type_state_.progress_marker = progress_marker;
- ScopedCryptographerRef scoped_cryptographer_ref;
- cryptographer_provider_->InitScopedCryptographerRef(
- &scoped_cryptographer_ref);
- Cryptographer* cryptographer = scoped_cryptographer_ref.Get();
- DCHECK(cryptographer);
-
UpdateResponseDataList response_datas;
UpdateResponseDataList pending_updates;
@@ -166,17 +154,18 @@ SyncerError ModelTypeSyncWorkerImpl::ProcessGetUpdatesResponse(
entity_tracker->ReceiveUpdate(update_entity->version());
response_data.specifics = specifics;
response_datas.push_back(response_data);
- } else if (specifics.has_encrypted() &&
- cryptographer->CanDecrypt(specifics.encrypted())) {
+ } else if (specifics.has_encrypted() && cryptographer_ &&
+ cryptographer_->CanDecrypt(specifics.encrypted())) {
// Encrypted, but we know the key.
if (DecryptSpecifics(
- cryptographer, specifics, &response_data.specifics)) {
+ cryptographer_.get(), specifics, &response_data.specifics)) {
entity_tracker->ReceiveUpdate(update_entity->version());
response_data.encryption_key_name = specifics.encrypted().key_name();
response_datas.push_back(response_data);
}
} else if (specifics.has_encrypted() &&
- !cryptographer->CanDecrypt(specifics.encrypted())) {
+ (!cryptographer_ ||
+ !cryptographer_->CanDecrypt(specifics.encrypted()))) {
// Can't decrypt right now. Ask the entity tracker to handle it.
response_data.specifics = specifics;
if (entity_tracker->ReceivePendingUpdate(response_data)) {
@@ -188,6 +177,12 @@ SyncerError ModelTypeSyncWorkerImpl::ProcessGetUpdatesResponse(
}
}
+ DVLOG(1) << ModelTypeToString(type_) << ": "
+ << base::StringPrintf(
+ "Delivering %zd applicable and %zd pending updates.",
+ response_datas.size(),
+ pending_updates.size());
+
// Forward these updates to the model thread so it can do the rest.
type_sync_proxy_->OnUpdateReceived(
data_type_state_, response_datas, pending_updates);
@@ -202,6 +197,8 @@ void ModelTypeSyncWorkerImpl::ApplyUpdates(sessions::StatusController* status) {
// cycle, we should update our state so the ModelTypeSyncProxy knows that
// it's safe to commit items now.
if (!data_type_state_.initial_sync_done) {
+ DVLOG(1) << "Delivering 'initial sync done' ping.";
+
data_type_state_.initial_sync_done = true;
type_sync_proxy_->OnUpdateReceived(
@@ -230,11 +227,7 @@ void ModelTypeSyncWorkerImpl::EnqueueForCommit(
StorePendingCommit(*it);
}
- ScopedCryptographerRef scoped_cryptographer_ref;
- cryptographer_provider_->InitScopedCryptographerRef(
- &scoped_cryptographer_ref);
- Cryptographer* cryptographer = scoped_cryptographer_ref.Get();
- if (CanCommitItems(cryptographer))
+ if (CanCommitItems())
nudge_handler_->NudgeForCommit(type_);
}
@@ -247,12 +240,7 @@ scoped_ptr<CommitContribution> ModelTypeSyncWorkerImpl::GetContribution(
std::vector<int64> sequence_numbers;
google::protobuf::RepeatedPtrField<sync_pb::SyncEntity> commit_entities;
- ScopedCryptographerRef scoped_cryptographer_ref;
- cryptographer_provider_->InitScopedCryptographerRef(
- &scoped_cryptographer_ref);
- Cryptographer* cryptographer = scoped_cryptographer_ref.Get();
-
- if (!CanCommitItems(cryptographer))
+ if (!CanCommitItems())
return scoped_ptr<CommitContribution>();
// TODO(rlarocque): Avoid iterating here.
@@ -265,7 +253,7 @@ scoped_ptr<CommitContribution> ModelTypeSyncWorkerImpl::GetContribution(
int64 sequence_number = -1;
entity->PrepareCommitProto(commit_entity, &sequence_number);
- HelpInitializeCommitEntity(cryptographer, commit_entity);
+ HelpInitializeCommitEntity(commit_entity);
sequence_numbers.push_back(sequence_number);
space_remaining--;
@@ -350,17 +338,15 @@ bool ModelTypeSyncWorkerImpl::IsTypeInitialized() const {
data_type_state_.initial_sync_done;
}
-bool ModelTypeSyncWorkerImpl::CanCommitItems(
- Cryptographer* cryptographer) const {
+bool ModelTypeSyncWorkerImpl::CanCommitItems() const {
// We can't commit anything until we know the type's parent node.
// We'll get it in the first update response.
if (!IsTypeInitialized())
return false;
// Don't commit if we should be encrypting but don't have the required keys.
- if (IsEncryptionRequired() && (!cryptographer || !cryptographer->is_ready() ||
- cryptographer->GetDefaultNigoriKeyName() !=
- data_type_state_.encryption_key_name)) {
+ if (IsEncryptionRequired() &&
+ (!cryptographer_ || !cryptographer_->is_ready())) {
return false;
}
@@ -368,8 +354,9 @@ bool ModelTypeSyncWorkerImpl::CanCommitItems(
}
void ModelTypeSyncWorkerImpl::HelpInitializeCommitEntity(
- Cryptographer* cryptographer,
sync_pb::SyncEntity* sync_entity) {
+ DCHECK(CanCommitItems());
+
// Initial commits need our help to generate a client ID.
if (!sync_entity->has_id_string()) {
DCHECK_EQ(kUncommittedVersion, sync_entity->version());
@@ -380,9 +367,12 @@ void ModelTypeSyncWorkerImpl::HelpInitializeCommitEntity(
// Encrypt the specifics and hide the title if necessary.
if (IsEncryptionRequired()) {
+ // IsEncryptionRequired() && CanCommitItems() implies
+ // that the cryptographer is valid and ready to encrypt.
sync_pb::EntitySpecifics encrypted_specifics;
- cryptographer->Encrypt(sync_entity->specifics(),
- encrypted_specifics.mutable_encrypted());
+ bool result = cryptographer_->Encrypt(
+ sync_entity->specifics(), encrypted_specifics.mutable_encrypted());
+ DCHECK(result);
sync_entity->mutable_specifics()->CopyFrom(encrypted_specifics);
sync_entity->set_name("encrypted");
}
@@ -395,14 +385,21 @@ void ModelTypeSyncWorkerImpl::HelpInitializeCommitEntity(
sync_entity->set_parent_id_string(data_type_state_.type_root_id);
}
-void ModelTypeSyncWorkerImpl::TryDecryptPendingUpdates() {
+void ModelTypeSyncWorkerImpl::OnCryptographerUpdated() {
+ DCHECK(cryptographer_);
+
+ bool new_encryption_key = false;
UpdateResponseDataList response_datas;
- ScopedCryptographerRef scoped_cryptographer_ref;
- cryptographer_provider_->InitScopedCryptographerRef(
- &scoped_cryptographer_ref);
- Cryptographer* cryptographer = scoped_cryptographer_ref.Get();
- DCHECK(cryptographer);
+ const std::string& new_key_name = cryptographer_->GetDefaultNigoriKeyName();
+
+ // Handle a change in encryption key.
+ if (data_type_state_.encryption_key_name != new_key_name) {
+ DVLOG(1) << ModelTypeToString(type_) << ": Updating encryption key "
+ << data_type_state_.encryption_key_name << " -> " << new_key_name;
+ data_type_state_.encryption_key_name = new_key_name;
+ new_encryption_key = true;
+ }
for (EntityMap::const_iterator it = entities_.begin(); it != entities_.end();
++it) {
@@ -413,9 +410,9 @@ void ModelTypeSyncWorkerImpl::TryDecryptPendingUpdates() {
// don't have the key.
DCHECK(saved_pending.specifics.has_encrypted());
- if (cryptographer->CanDecrypt(saved_pending.specifics.encrypted())) {
+ if (cryptographer_->CanDecrypt(saved_pending.specifics.encrypted())) {
UpdateResponseData decrypted_response = saved_pending;
- if (DecryptSpecifics(cryptographer,
+ if (DecryptSpecifics(cryptographer_.get(),
saved_pending.specifics,
&decrypted_response.specifics)) {
decrypted_response.encryption_key_name =
@@ -428,7 +425,11 @@ void ModelTypeSyncWorkerImpl::TryDecryptPendingUpdates() {
}
}
- if (!response_datas.empty()) {
+ if (new_encryption_key || response_datas.size() > 0) {
+ DVLOG(1) << ModelTypeToString(type_) << ": "
+ << base::StringPrintf(
+ "Delivering encryption key and %zd decrypted updates.",
+ response_datas.size());
type_sync_proxy_->OnUpdateReceived(
data_type_state_, response_datas, UpdateResponseDataList());
}