Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/engine/process_updates_command.h" | 5 #include "chrome/browser/sync/engine/process_updates_command.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "chrome/browser/sync/engine/syncer.h" | 11 #include "chrome/browser/sync/engine/syncer.h" |
| 12 #include "chrome/browser/sync/engine/syncer_proto_util.h" | 12 #include "chrome/browser/sync/engine/syncer_proto_util.h" |
| 13 #include "chrome/browser/sync/engine/syncer_util.h" | 13 #include "chrome/browser/sync/engine/syncer_util.h" |
| 14 #include "chrome/browser/sync/engine/syncproto.h" | 14 #include "chrome/browser/sync/engine/syncproto.h" |
| 15 #include "chrome/browser/sync/sessions/sync_session.h" | 15 #include "chrome/browser/sync/sessions/sync_session.h" |
| 16 #include "chrome/browser/sync/syncable/directory_manager.h" | 16 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 17 #include "chrome/browser/sync/syncable/syncable.h" | 17 #include "chrome/browser/sync/syncable/syncable.h" |
| 18 #include "chrome/browser/sync/util/cryptographer.h" | |
| 18 | 19 |
| 19 using std::vector; | 20 using std::vector; |
| 20 | 21 |
| 21 namespace browser_sync { | 22 namespace browser_sync { |
| 22 | 23 |
| 23 using sessions::SyncSession; | 24 using sessions::SyncSession; |
| 24 using sessions::StatusController; | 25 using sessions::StatusController; |
| 25 using sessions::UpdateProgress; | 26 using sessions::UpdateProgress; |
| 26 | 27 |
| 27 ProcessUpdatesCommand::ProcessUpdatesCommand() {} | 28 ProcessUpdatesCommand::ProcessUpdatesCommand() {} |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 | 62 |
| 62 syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir); | 63 syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir); |
| 63 vector<sessions::VerifiedUpdate>::const_iterator it; | 64 vector<sessions::VerifiedUpdate>::const_iterator it; |
| 64 for (it = progress->VerifiedUpdatesBegin(); | 65 for (it = progress->VerifiedUpdatesBegin(); |
| 65 it != progress->VerifiedUpdatesEnd(); | 66 it != progress->VerifiedUpdatesEnd(); |
| 66 ++it) { | 67 ++it) { |
| 67 const sync_pb::SyncEntity& update = it->second; | 68 const sync_pb::SyncEntity& update = it->second; |
| 68 | 69 |
| 69 if (it->first != VERIFY_SUCCESS && it->first != VERIFY_UNDELETE) | 70 if (it->first != VERIFY_SUCCESS && it->first != VERIFY_UNDELETE) |
| 70 continue; | 71 continue; |
| 71 switch (ProcessUpdate(dir, update, &trans)) { | 72 switch (ProcessUpdate(dir, update, |
| 73 session->context()->directory_manager()->GetCryptographer(&trans), | |
| 74 &trans)) { | |
| 72 case SUCCESS_PROCESSED: | 75 case SUCCESS_PROCESSED: |
| 73 case SUCCESS_STORED: | 76 case SUCCESS_STORED: |
| 74 break; | 77 break; |
| 75 default: | 78 default: |
| 76 NOTREACHED(); | 79 NOTREACHED(); |
| 77 break; | 80 break; |
| 78 } | 81 } |
| 79 } | 82 } |
| 80 | 83 |
| 81 StatusController* status = session->mutable_status_controller(); | 84 StatusController* status = session->mutable_status_controller(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 98 deleted, | 101 deleted, |
| 99 is_directory, | 102 is_directory, |
| 100 model_type); | 103 model_type); |
| 101 } | 104 } |
| 102 } // namespace | 105 } // namespace |
| 103 | 106 |
| 104 // Process a single update. Will avoid touching global state. | 107 // Process a single update. Will avoid touching global state. |
| 105 ServerUpdateProcessingResult ProcessUpdatesCommand::ProcessUpdate( | 108 ServerUpdateProcessingResult ProcessUpdatesCommand::ProcessUpdate( |
| 106 const syncable::ScopedDirLookup& dir, | 109 const syncable::ScopedDirLookup& dir, |
| 107 const sync_pb::SyncEntity& proto_update, | 110 const sync_pb::SyncEntity& proto_update, |
| 111 const Cryptographer* cryptographer, | |
| 108 syncable::WriteTransaction* const trans) { | 112 syncable::WriteTransaction* const trans) { |
| 109 | 113 |
| 110 const SyncEntity& update = *static_cast<const SyncEntity*>(&proto_update); | 114 const SyncEntity& update = *static_cast<const SyncEntity*>(&proto_update); |
| 111 syncable::Id server_id = update.id(); | 115 syncable::Id server_id = update.id(); |
| 112 const std::string name = SyncerProtoUtil::NameFromSyncEntity(update); | 116 const std::string name = SyncerProtoUtil::NameFromSyncEntity(update); |
| 113 | 117 |
| 114 // Look to see if there's a local item that should recieve this update, | 118 // Look to see if there's a local item that should recieve this update, |
| 115 // maybe due to a duplicate client tag or a lost commit response. | 119 // maybe due to a duplicate client tag or a lost commit response. |
| 116 syncable::Id local_id = SyncerUtil::FindLocalIdToUpdate(trans, update); | 120 syncable::Id local_id = SyncerUtil::FindLocalIdToUpdate(trans, update); |
| 117 | 121 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 // fields for this entry. When BASE_VERSION is positive, consistency is | 155 // fields for this entry. When BASE_VERSION is positive, consistency is |
| 152 // enforced on the client fields at update-application time. Otherwise, | 156 // enforced on the client fields at update-application time. Otherwise, |
| 153 // we leave the BASE_VERSION field alone; it'll get updated the first time | 157 // we leave the BASE_VERSION field alone; it'll get updated the first time |
| 154 // we successfully apply this update. | 158 // we successfully apply this update. |
| 155 target_entry.Put(syncable::BASE_VERSION, update.version()); | 159 target_entry.Put(syncable::BASE_VERSION, update.version()); |
| 156 } | 160 } |
| 157 // Force application of this update, no matter what. | 161 // Force application of this update, no matter what. |
| 158 target_entry.Put(syncable::IS_UNAPPLIED_UPDATE, true); | 162 target_entry.Put(syncable::IS_UNAPPLIED_UPDATE, true); |
| 159 } | 163 } |
| 160 | 164 |
| 165 // If this is a newly received undecryptable update, and the only thing that | |
| 166 // has changed are the specifics, store the original decryptable specifics, | |
| 167 // (on which any current or future local changes are based) before we | |
| 168 // overwrite SERVER_SPECIFICS. | |
| 169 // MTIME, CTIME, and NON_UNIQUE_NAME are not enforced. | |
| 170 if (!update.deleted() && !target_entry.Get(syncable::SERVER_IS_DEL) && | |
| 171 (update.parent_id() == target_entry.Get(syncable::SERVER_PARENT_ID)) && | |
| 172 (update.position_in_parent() == | |
| 173 target_entry.Get(syncable::SERVER_POSITION_IN_PARENT)) && | |
| 174 update.has_specifics() && update.specifics().has_encrypted() && | |
| 175 !cryptographer->CanDecrypt(update.specifics().encrypted())) { | |
|
tim (not reviewing)
2011/12/15 20:55:11
holy crap, complicated
Nicolas Zea
2011/12/16 19:25:14
Yeah :-/ Is there a better way of detecting when o
| |
| 176 sync_pb::EntitySpecifics prev_specifics = | |
| 177 target_entry.Get(syncable::SERVER_SPECIFICS); | |
| 178 // We only store the old specifics if they were decryptable and applied and | |
| 179 // there is no PREV_SERVER_SPECIFICS already. Else do nothing. | |
| 180 if (!target_entry.Get(syncable::IS_UNAPPLIED_UPDATE) && | |
| 181 !syncable::IsRealDataType(syncable::GetModelTypeFromSpecifics( | |
| 182 target_entry.Get(syncable::PREV_SERVER_SPECIFICS))) && | |
| 183 (!prev_specifics.has_encrypted() || | |
| 184 cryptographer->CanDecrypt(prev_specifics.encrypted()))) { | |
| 185 DVLOG(2) << "Storing previous server specifcs: " | |
| 186 << prev_specifics.SerializeAsString(); | |
| 187 target_entry.Put(syncable::PREV_SERVER_SPECIFICS, prev_specifics); | |
|
tim (not reviewing)
2011/12/15 20:55:11
I don't really like PREV_SERVER_SPECIFICS, it's ea
Nicolas Zea
2011/12/22 18:35:28
Done.
| |
| 188 } | |
| 189 } else if (target_entry.Get(syncable::PREV_SERVER_SPECIFICS). | |
| 190 IsInitialized()) { | |
|
tim (not reviewing)
2011/12/15 20:55:11
indent
Nicolas Zea
2011/12/22 18:35:28
Done.
| |
| 191 // We have a PREV_SERVER_SPECIFICS, but a subsequent non-encryption-only | |
|
tim (not reviewing)
2011/12/15 20:55:11
how do we know it is non-encryption only?
Nicolas Zea
2011/12/16 19:25:14
You're right, the comment is inaccurate. This shou
| |
| 192 // change arrived, invalidating PREV_SERVER_SPECIFICS. Clear it, as it's | |
| 193 // no longer safe to assume only the specifics changed. | |
| 194 target_entry.Put(syncable::PREV_SERVER_SPECIFICS, | |
| 195 sync_pb::EntitySpecifics()); | |
| 196 } | |
| 197 | |
| 161 SyncerUtil::UpdateServerFieldsFromUpdate(&target_entry, update, name); | 198 SyncerUtil::UpdateServerFieldsFromUpdate(&target_entry, update, name); |
| 162 | 199 |
| 163 return SUCCESS_PROCESSED; | 200 return SUCCESS_PROCESSED; |
| 164 } | 201 } |
| 165 | 202 |
| 166 } // namespace browser_sync | 203 } // namespace browser_sync |
| OLD | NEW |