Home | History | Annotate | Download | only in engine
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sync/engine/model_type_entity.h"
      6 #include "sync/syncable/syncable_util.h"
      7 
      8 namespace syncer {
      9 
     10 scoped_ptr<ModelTypeEntity> ModelTypeEntity::NewLocalItem(
     11     const std::string& client_tag,
     12     const sync_pb::EntitySpecifics& specifics,
     13     base::Time now) {
     14   return scoped_ptr<ModelTypeEntity>(new ModelTypeEntity(
     15       1,
     16       0,
     17       0,
     18       kUncommittedVersion,
     19       true,
     20       std::string(),  // Sync thread will assign the initial ID.
     21       syncable::GenerateSyncableHash(GetModelTypeFromSpecifics(specifics),
     22                                      client_tag),
     23       client_tag,  // As non-unique name.
     24       specifics,
     25       false,
     26       now,
     27       now,
     28       std::string()));
     29 }
     30 
     31 scoped_ptr<ModelTypeEntity> ModelTypeEntity::FromServerUpdate(
     32     const std::string& id,
     33     const std::string& client_tag_hash,
     34     const std::string& non_unique_name,
     35     int64 version,
     36     const sync_pb::EntitySpecifics& specifics,
     37     bool deleted,
     38     base::Time ctime,
     39     base::Time mtime,
     40     const std::string& encryption_key_name) {
     41   return scoped_ptr<ModelTypeEntity>(new ModelTypeEntity(0,
     42                                                          0,
     43                                                          0,
     44                                                          version,
     45                                                          true,
     46                                                          id,
     47                                                          client_tag_hash,
     48                                                          non_unique_name,
     49                                                          specifics,
     50                                                          deleted,
     51                                                          ctime,
     52                                                          mtime,
     53                                                          encryption_key_name));
     54 }
     55 
     56 ModelTypeEntity::ModelTypeEntity(int64 sequence_number,
     57                                  int64 commit_requested_sequence_number,
     58                                  int64 acked_sequence_number,
     59                                  int64 base_version,
     60                                  bool is_dirty,
     61                                  const std::string& id,
     62                                  const std::string& client_tag_hash,
     63                                  const std::string& non_unique_name,
     64                                  const sync_pb::EntitySpecifics& specifics,
     65                                  bool deleted,
     66                                  base::Time ctime,
     67                                  base::Time mtime,
     68                                  const std::string& encryption_key_name)
     69     : sequence_number_(sequence_number),
     70       commit_requested_sequence_number_(commit_requested_sequence_number),
     71       acked_sequence_number_(acked_sequence_number),
     72       base_version_(base_version),
     73       is_dirty_(is_dirty),
     74       id_(id),
     75       client_tag_hash_(client_tag_hash),
     76       non_unique_name_(non_unique_name),
     77       specifics_(specifics),
     78       deleted_(deleted),
     79       ctime_(ctime),
     80       mtime_(mtime),
     81       encryption_key_name_(encryption_key_name) {
     82 }
     83 
     84 ModelTypeEntity::~ModelTypeEntity() {
     85 }
     86 
     87 bool ModelTypeEntity::IsWriteRequired() const {
     88   return is_dirty_;
     89 }
     90 
     91 bool ModelTypeEntity::IsUnsynced() const {
     92   return sequence_number_ > acked_sequence_number_;
     93 }
     94 
     95 bool ModelTypeEntity::RequiresCommitRequest() const {
     96   return sequence_number_ > commit_requested_sequence_number_;
     97 }
     98 
     99 bool ModelTypeEntity::UpdateIsReflection(int64 update_version) const {
    100   return base_version_ >= update_version;
    101 }
    102 
    103 bool ModelTypeEntity::UpdateIsInConflict(int64 update_version) const {
    104   return IsUnsynced() && !UpdateIsReflection(update_version);
    105 }
    106 
    107 void ModelTypeEntity::ApplyUpdateFromServer(
    108     int64 update_version,
    109     bool deleted,
    110     const sync_pb::EntitySpecifics& specifics,
    111     base::Time mtime,
    112     const std::string& encryption_key_name) {
    113   // There was a conflict and the server just won it.
    114   // This implicitly acks all outstanding commits because a received update
    115   // will clobber any pending commits on the sync thread.
    116   acked_sequence_number_ = sequence_number_;
    117   commit_requested_sequence_number_ = sequence_number_;
    118 
    119   base_version_ = update_version;
    120   specifics_ = specifics;
    121   mtime_ = mtime;
    122 }
    123 
    124 void ModelTypeEntity::MakeLocalChange(
    125     const sync_pb::EntitySpecifics& specifics) {
    126   sequence_number_++;
    127   specifics_ = specifics;
    128 }
    129 
    130 void ModelTypeEntity::UpdateDesiredEncryptionKey(const std::string& name) {
    131   if (encryption_key_name_ == name)
    132     return;
    133 
    134   DVLOG(2) << id_ << ": Encryption triggered commit: " << encryption_key_name_
    135            << " -> " << name;
    136 
    137   // Schedule commit with the expectation that the worker will re-encrypt with
    138   // the latest encryption key as it does.
    139   sequence_number_++;
    140 }
    141 
    142 void ModelTypeEntity::Delete() {
    143   sequence_number_++;
    144   specifics_.Clear();
    145   deleted_ = true;
    146 }
    147 
    148 void ModelTypeEntity::InitializeCommitRequestData(
    149     CommitRequestData* request) const {
    150   request->id = id_;
    151   request->client_tag_hash = client_tag_hash_;
    152   request->sequence_number = sequence_number_;
    153   request->base_version = base_version_;
    154   request->ctime = ctime_;
    155   request->mtime = mtime_;
    156   request->non_unique_name = non_unique_name_;
    157   request->deleted = deleted_;
    158   request->specifics.CopyFrom(specifics_);
    159 }
    160 
    161 void ModelTypeEntity::SetCommitRequestInProgress() {
    162   commit_requested_sequence_number_ = sequence_number_;
    163 }
    164 
    165 void ModelTypeEntity::ReceiveCommitResponse(
    166     const std::string& id,
    167     int64 sequence_number,
    168     int64 response_version,
    169     const std::string& encryption_key_name) {
    170   id_ = id;  // The server can assign us a new ID in a commit response.
    171   acked_sequence_number_ = sequence_number;
    172   base_version_ = response_version;
    173   encryption_key_name_ = encryption_key_name;
    174 }
    175 
    176 void ModelTypeEntity::ClearTransientSyncState() {
    177   // If we have any unacknowledged commit requests outstatnding, they've been
    178   // dropped and we should forget about them.
    179   commit_requested_sequence_number_ = acked_sequence_number_;
    180 }
    181 
    182 void ModelTypeEntity::ClearSyncState() {
    183   base_version_ = kUncommittedVersion;
    184   is_dirty_ = true;
    185   sequence_number_ = 1;
    186   commit_requested_sequence_number_ = 0;
    187   acked_sequence_number_ = 0;
    188   id_.clear();
    189 }
    190 
    191 }  // namespace syncer
    192