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