Chromium Code Reviews| Index: sync/engine/model_type_sync_proxy_impl.cc |
| diff --git a/sync/engine/model_type_sync_proxy_impl.cc b/sync/engine/model_type_sync_proxy_impl.cc |
| index 7b2148ace0c6fec764697d8b2699d5afbc5b1458..20b7c2eb076362297f7ee0d73bcc35ebabcc3a48 100644 |
| --- a/sync/engine/model_type_sync_proxy_impl.cc |
| +++ b/sync/engine/model_type_sync_proxy_impl.cc |
| @@ -18,6 +18,7 @@ ModelTypeSyncProxyImpl::ModelTypeSyncProxyImpl(ModelType type) |
| is_preferred_(false), |
| is_connected_(false), |
| entities_deleter_(&entities_), |
| + inapplicable_updates_deleter_(&inapplicable_updates_), |
| weak_ptr_factory_for_ui_(this), |
| weak_ptr_factory_for_sync_(this) { |
| } |
| @@ -51,10 +52,12 @@ void ModelTypeSyncProxyImpl::Enable( |
| data_type_state_.progress_marker.set_data_type_id( |
| GetSpecificsFieldNumberFromModelType(type_)); |
| + UpdateResponseDataList saved_inapplicable_updates = GetInapplicableUpdates(); |
| sync_context_proxy_ = sync_context_proxy.Pass(); |
| sync_context_proxy_->ConnectTypeToSync( |
| GetModelType(), |
| data_type_state_, |
| + saved_inapplicable_updates, |
| weak_ptr_factory_for_sync_.GetWeakPtr()); |
| } |
| @@ -180,16 +183,18 @@ void ModelTypeSyncProxyImpl::OnCommitCompleted( |
| } else { |
| it->second->ReceiveCommitResponse(response_data.id, |
| response_data.sequence_number, |
| - response_data.response_version); |
| + response_data.response_version, |
| + data_type_state_.encryption_key_name); |
| } |
| } |
| } |
| void ModelTypeSyncProxyImpl::OnUpdateReceived( |
| const DataTypeState& data_type_state, |
| - const UpdateResponseDataList& response_list) { |
| - bool initial_sync_just_finished = |
| - !data_type_state_.initial_sync_done && data_type_state.initial_sync_done; |
| + const UpdateResponseDataList& response_list, |
| + const UpdateResponseDataList& inapplicable_updates) { |
|
Nicolas Zea
2014/07/30 00:34:16
I find it confusing that this type is a list, whil
rlarocque
2014/07/30 21:56:01
How about new_inapplicable_updates?
Nicolas Zea
2014/07/31 18:06:26
Or just naming the member variable inapplicable_up
rlarocque
2014/07/31 18:54:04
Done.
|
| + bool got_new_encryption_requirements = data_type_state_.encryption_key_name != |
| + data_type_state.encryption_key_name; |
| data_type_state_ = data_type_state; |
| @@ -199,6 +204,14 @@ void ModelTypeSyncProxyImpl::OnUpdateReceived( |
| const UpdateResponseData& response_data = *list_it; |
| const std::string& client_tag_hash = response_data.client_tag_hash; |
| + UpdateMap::iterator old_it = inapplicable_updates_.find(client_tag_hash); |
| + if (old_it != inapplicable_updates_.end()) { |
| + // If we're being asked to apply an update to this entity, this overrides |
| + // the previous inapplicable updates. |
| + delete old_it->second; |
| + inapplicable_updates_.erase(old_it); |
| + } |
| + |
| EntityMap::iterator it = entities_.find(client_tag_hash); |
| if (it == entities_.end()) { |
| scoped_ptr<ModelTypeEntity> entity = |
| @@ -209,22 +222,73 @@ void ModelTypeSyncProxyImpl::OnUpdateReceived( |
| response_data.specifics, |
| response_data.deleted, |
| response_data.ctime, |
| - response_data.mtime); |
| + response_data.mtime, |
| + response_data.encryption_key_name); |
| entities_.insert(std::make_pair(client_tag_hash, entity.release())); |
| } else { |
| ModelTypeEntity* entity = it->second; |
| entity->ApplyUpdateFromServer(response_data.response_version, |
| response_data.deleted, |
| response_data.specifics, |
| - response_data.mtime); |
| + response_data.mtime, |
| + response_data.encryption_key_name); |
| + |
| // TODO: Do something special when conflicts are detected. |
| } |
| + |
| + // If the received entity has out of date encryption, we schedule another |
| + // commit to fix it. |
| + if (data_type_state_.encryption_key_name != |
| + response_data.encryption_key_name) { |
| + EntityMap::iterator it2 = entities_.find(client_tag_hash); |
| + it2->second->RequireEncryptionKey(data_type_state_.encryption_key_name); |
| + } |
| } |
| - if (initial_sync_just_finished) |
| - FlushPendingCommitRequests(); |
| + // Save inapplicable updates in the appropriate data structure. |
| + for (UpdateResponseDataList::const_iterator list_it = |
| + inapplicable_updates.begin(); |
| + list_it != inapplicable_updates.end(); |
| + ++list_it) { |
| + const UpdateResponseData& update = *list_it; |
| + const std::string& client_tag_hash = update.client_tag_hash; |
| + |
| + UpdateMap::iterator lookup_it = inapplicable_updates_.find(client_tag_hash); |
| + if (lookup_it == inapplicable_updates_.end()) { |
| + inapplicable_updates_.insert( |
| + std::make_pair(client_tag_hash, new UpdateResponseData(update))); |
| + } else if (lookup_it->second->response_version <= update.response_version) { |
| + delete lookup_it->second; |
| + inapplicable_updates_.erase(lookup_it); |
| + inapplicable_updates_.insert( |
| + std::make_pair(client_tag_hash, new UpdateResponseData(update))); |
| + } else { |
| + // Received update is stale, do not overwrite existing. |
| + } |
| + } |
| + |
| + if (got_new_encryption_requirements) { |
| + for (EntityMap::iterator it = entities_.begin(); it != entities_.end(); |
| + ++it) { |
| + it->second->RequireEncryptionKey(data_type_state_.encryption_key_name); |
| + } |
| + } |
| + |
| + // We may have new reasons to commit by the time this function is done. |
| + FlushPendingCommitRequests(); |
| // TODO: Inform the model of the new or updated data. |
| + // TODO: Persist the new data on disk. |
| +} |
| + |
| +UpdateResponseDataList ModelTypeSyncProxyImpl::GetInapplicableUpdates() { |
| + UpdateResponseDataList inapplicable_updates_list; |
| + for (UpdateMap::const_iterator it = inapplicable_updates_.begin(); |
| + it != inapplicable_updates_.end(); |
| + ++it) { |
| + inapplicable_updates_list.push_back(*it->second); |
| + } |
| + return inapplicable_updates_list; |
| } |
| void ModelTypeSyncProxyImpl::ClearTransientSyncState() { |
| @@ -240,6 +304,9 @@ void ModelTypeSyncProxyImpl::ClearSyncState() { |
| it->second->ClearSyncState(); |
| } |
| + STLDeleteValues(&inapplicable_updates_); |
| + inapplicable_updates_.clear(); |
|
Nicolas Zea
2014/07/30 00:34:16
STLDeleteValues calls clear for you.
rlarocque
2014/07/30 21:56:01
Fixed.
|
| + |
| data_type_state_ = DataTypeState(); |
| } |