Index: sync/engine/model_type_sync_worker_impl.cc |
diff --git a/sync/engine/model_type_sync_worker_impl.cc b/sync/engine/model_type_sync_worker_impl.cc |
index a58400f456679b388fb4aa3c6bbdb96b3acfa5ee..95720fbd0f7a08e79d02f5939a416bc2f8dff210 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,18 @@ 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) { |
+ 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 +102,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 +153,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 +176,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 +196,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 +226,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 +239,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 +252,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,25 +337,21 @@ 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; |
- } |
return true; |
} |
void ModelTypeSyncWorkerImpl::HelpInitializeCommitEntity( |
- Cryptographer* cryptographer, |
sync_pb::SyncEntity* sync_entity) { |
// Initial commits need our help to generate a client ID. |
if (!sync_entity->has_id_string()) { |
@@ -380,9 +363,11 @@ void ModelTypeSyncWorkerImpl::HelpInitializeCommitEntity( |
// Encrypt the specifics and hide the title if necessary. |
if (IsEncryptionRequired()) { |
+ // IsEncryptionRequired() && CanCommitItems() implies !!cryptographer_. |
+ DCHECK(CanCommitItems()); |
sync_pb::EntitySpecifics encrypted_specifics; |
- cryptographer->Encrypt(sync_entity->specifics(), |
- encrypted_specifics.mutable_encrypted()); |
+ cryptographer_->Encrypt(sync_entity->specifics(), |
+ encrypted_specifics.mutable_encrypted()); |
sync_entity->mutable_specifics()->CopyFrom(encrypted_specifics); |
sync_entity->set_name("encrypted"); |
} |
@@ -395,14 +380,23 @@ 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 != |
+ cryptographer_->GetDefaultNigoriKeyName()) { |
stanisc
2014/08/11 21:05:42
Should this be using new_key_name instead of crypt
rlarocque
2014/08/11 21:50:22
Good point. It shouldn't make a difference, but t
|
+ DVLOG(1) << ModelTypeToString(type_) << ": Updating encryption key " |
+ << data_type_state_.encryption_key_name << " -> " << new_key_name; |
+ data_type_state_.encryption_key_name = |
+ cryptographer_->GetDefaultNigoriKeyName(); |
+ new_encryption_key = true; |
+ } |
for (EntityMap::const_iterator it = entities_.begin(); it != entities_.end(); |
++it) { |
@@ -413,9 +407,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 +422,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()); |
} |