1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/engine/model_type_entity.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/syncable/syncable_util.h"
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace syncer {
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_ptr<ModelTypeEntity> ModelTypeEntity::NewLocalItem(
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& client_tag,
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const sync_pb::EntitySpecifics& specifics,
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::Time now) {
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return scoped_ptr<ModelTypeEntity>(new ModelTypeEntity(
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      1,
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      0,
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      0,
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      kUncommittedVersion,
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      true,
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      std::string(),  // Sync thread will assign the initial ID.
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      syncable::GenerateSyncableHash(GetModelTypeFromSpecifics(specifics),
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     client_tag),
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      client_tag,  // As non-unique name.
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      specifics,
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      false,
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      now,
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      now,
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::string()));
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_ptr<ModelTypeEntity> ModelTypeEntity::FromServerUpdate(
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& id,
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& client_tag_hash,
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& non_unique_name,
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int64 version,
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const sync_pb::EntitySpecifics& specifics,
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool deleted,
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::Time ctime,
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::Time mtime,
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& encryption_key_name) {
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return scoped_ptr<ModelTypeEntity>(new ModelTypeEntity(0,
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         0,
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         0,
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         version,
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         true,
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         id,
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         client_tag_hash,
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         non_unique_name,
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         specifics,
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         deleted,
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         ctime,
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                         mtime,
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                         encryption_key_name));
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
56116680a4aac90f2aa7413d9095a592090648e557Ben MurdochModelTypeEntity::ModelTypeEntity(int64 sequence_number,
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 int64 commit_requested_sequence_number,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 int64 acked_sequence_number,
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 int64 base_version,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 bool is_dirty,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const std::string& id,
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const std::string& client_tag_hash,
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const std::string& non_unique_name,
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const sync_pb::EntitySpecifics& specifics,
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 bool deleted,
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 base::Time ctime,
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 base::Time mtime,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 const std::string& encryption_key_name)
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : sequence_number_(sequence_number),
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      commit_requested_sequence_number_(commit_requested_sequence_number),
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      acked_sequence_number_(acked_sequence_number),
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base_version_(base_version),
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_dirty_(is_dirty),
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      id_(id),
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      client_tag_hash_(client_tag_hash),
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      non_unique_name_(non_unique_name),
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      specifics_(specifics),
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      deleted_(deleted),
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ctime_(ctime),
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      mtime_(mtime),
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      encryption_key_name_(encryption_key_name) {
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
84116680a4aac90f2aa7413d9095a592090648e557Ben MurdochModelTypeEntity::~ModelTypeEntity() {
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ModelTypeEntity::IsWriteRequired() const {
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return is_dirty_;
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ModelTypeEntity::IsUnsynced() const {
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return sequence_number_ > acked_sequence_number_;
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ModelTypeEntity::RequiresCommitRequest() const {
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return sequence_number_ > commit_requested_sequence_number_;
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ModelTypeEntity::UpdateIsReflection(int64 update_version) const {
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return base_version_ >= update_version;
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ModelTypeEntity::UpdateIsInConflict(int64 update_version) const {
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return IsUnsynced() && !UpdateIsReflection(update_version);
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::ApplyUpdateFromServer(
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int64 update_version,
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool deleted,
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const sync_pb::EntitySpecifics& specifics,
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::Time mtime,
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& encryption_key_name) {
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // There was a conflict and the server just won it.
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This implicitly acks all outstanding commits because a received update
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // will clobber any pending commits on the sync thread.
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  acked_sequence_number_ = sequence_number_;
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  commit_requested_sequence_number_ = sequence_number_;
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base_version_ = update_version;
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  specifics_ = specifics;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mtime_ = mtime;
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::MakeLocalChange(
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const sync_pb::EntitySpecifics& specifics) {
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sequence_number_++;
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  specifics_ = specifics;
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ModelTypeEntity::UpdateDesiredEncryptionKey(const std::string& name) {
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (encryption_key_name_ == name)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DVLOG(2) << id_ << ": Encryption triggered commit: " << encryption_key_name_
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)           << " -> " << name;
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Schedule commit with the expectation that the worker will re-encrypt with
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the latest encryption key as it does.
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sequence_number_++;
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::Delete() {
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sequence_number_++;
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  specifics_.Clear();
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  deleted_ = true;
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::InitializeCommitRequestData(
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CommitRequestData* request) const {
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->id = id_;
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->client_tag_hash = client_tag_hash_;
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->sequence_number = sequence_number_;
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->base_version = base_version_;
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->ctime = ctime_;
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->mtime = mtime_;
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->non_unique_name = non_unique_name_;
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->deleted = deleted_;
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request->specifics.CopyFrom(specifics_);
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::SetCommitRequestInProgress() {
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  commit_requested_sequence_number_ = sequence_number_;
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ModelTypeEntity::ReceiveCommitResponse(
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& id,
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int64 sequence_number,
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int64 response_version,
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& encryption_key_name) {
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  id_ = id;  // The server can assign us a new ID in a commit response.
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  acked_sequence_number_ = sequence_number;
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base_version_ = response_version;
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  encryption_key_name_ = encryption_key_name;
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::ClearTransientSyncState() {
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If we have any unacknowledged commit requests outstatnding, they've been
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // dropped and we should forget about them.
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  commit_requested_sequence_number_ = acked_sequence_number_;
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ModelTypeEntity::ClearSyncState() {
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base_version_ = kUncommittedVersion;
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  is_dirty_ = true;
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sequence_number_ = 1;
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  commit_requested_sequence_number_ = 0;
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  acked_sequence_number_ = 0;
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  id_.clear();
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace syncer
192