| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/glue/generic_change_processor.h" | 5 #include "chrome/browser/sync/glue/generic_change_processor.h" |
| 6 | 6 |
| 7 #include "base/location.h" | 7 #include "base/location.h" |
| 8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| 11 #include "sync/api/sync_change.h" | 11 #include "sync/api/sync_change.h" |
| 12 #include "sync/api/sync_error.h" | 12 #include "sync/api/sync_error.h" |
| 13 #include "sync/api/syncable_service.h" | 13 #include "sync/api/syncable_service.h" |
| 14 #include "sync/internal_api/public/base_node.h" | 14 #include "sync/internal_api/public/base_node.h" |
| 15 #include "sync/internal_api/public/change_record.h" | 15 #include "sync/internal_api/public/change_record.h" |
| 16 #include "sync/internal_api/public/read_node.h" | 16 #include "sync/internal_api/public/read_node.h" |
| 17 #include "sync/internal_api/public/read_transaction.h" | 17 #include "sync/internal_api/public/read_transaction.h" |
| 18 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" | 18 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" |
| 19 #include "sync/internal_api/public/write_node.h" | 19 #include "sync/internal_api/public/write_node.h" |
| 20 #include "sync/internal_api/public/write_transaction.h" | 20 #include "sync/internal_api/public/write_transaction.h" |
| 21 #include "sync/syncable/entry.h" // TODO(tim): Bug 123674. | 21 #include "sync/syncable/entry.h" // TODO(tim): Bug 123674. |
| 22 | 22 |
| 23 using content::BrowserThread; | 23 using content::BrowserThread; |
| 24 | 24 |
| 25 namespace browser_sync { | 25 namespace browser_sync { |
| 26 | 26 |
| 27 GenericChangeProcessor::GenericChangeProcessor( | 27 GenericChangeProcessor::GenericChangeProcessor( |
| 28 DataTypeErrorHandler* error_handler, | 28 DataTypeErrorHandler* error_handler, |
| 29 const base::WeakPtr<csync::SyncableService>& local_service, | 29 const base::WeakPtr<syncer::SyncableService>& local_service, |
| 30 csync::UserShare* user_share) | 30 syncer::UserShare* user_share) |
| 31 : ChangeProcessor(error_handler), | 31 : ChangeProcessor(error_handler), |
| 32 local_service_(local_service), | 32 local_service_(local_service), |
| 33 share_handle_(user_share) { | 33 share_handle_(user_share) { |
| 34 DCHECK(CalledOnValidThread()); | 34 DCHECK(CalledOnValidThread()); |
| 35 } | 35 } |
| 36 | 36 |
| 37 GenericChangeProcessor::~GenericChangeProcessor() { | 37 GenericChangeProcessor::~GenericChangeProcessor() { |
| 38 DCHECK(CalledOnValidThread()); | 38 DCHECK(CalledOnValidThread()); |
| 39 } | 39 } |
| 40 | 40 |
| 41 void GenericChangeProcessor::ApplyChangesFromSyncModel( | 41 void GenericChangeProcessor::ApplyChangesFromSyncModel( |
| 42 const csync::BaseTransaction* trans, | 42 const syncer::BaseTransaction* trans, |
| 43 const csync::ImmutableChangeRecordList& changes) { | 43 const syncer::ImmutableChangeRecordList& changes) { |
| 44 DCHECK(CalledOnValidThread()); | 44 DCHECK(CalledOnValidThread()); |
| 45 DCHECK(running()); | 45 DCHECK(running()); |
| 46 DCHECK(syncer_changes_.empty()); | 46 DCHECK(syncer_changes_.empty()); |
| 47 for (csync::ChangeRecordList::const_iterator it = | 47 for (syncer::ChangeRecordList::const_iterator it = |
| 48 changes.Get().begin(); it != changes.Get().end(); ++it) { | 48 changes.Get().begin(); it != changes.Get().end(); ++it) { |
| 49 if (it->action == csync::ChangeRecord::ACTION_DELETE) { | 49 if (it->action == syncer::ChangeRecord::ACTION_DELETE) { |
| 50 syncer_changes_.push_back( | 50 syncer_changes_.push_back( |
| 51 csync::SyncChange(csync::SyncChange::ACTION_DELETE, | 51 syncer::SyncChange( |
| 52 csync::SyncData::CreateRemoteData(it->id, it->specifics))); | 52 syncer::SyncChange::ACTION_DELETE, |
| 53 syncer::SyncData::CreateRemoteData(it->id, it->specifics))); |
| 53 } else { | 54 } else { |
| 54 csync::SyncChange::SyncChangeType action = | 55 syncer::SyncChange::SyncChangeType action = |
| 55 (it->action == csync::ChangeRecord::ACTION_ADD) ? | 56 (it->action == syncer::ChangeRecord::ACTION_ADD) ? |
| 56 csync::SyncChange::ACTION_ADD : csync::SyncChange::ACTION_UPDATE; | 57 syncer::SyncChange::ACTION_ADD : syncer::SyncChange::ACTION_UPDATE; |
| 57 // Need to load specifics from node. | 58 // Need to load specifics from node. |
| 58 csync::ReadNode read_node(trans); | 59 syncer::ReadNode read_node(trans); |
| 59 if (read_node.InitByIdLookup(it->id) != csync::BaseNode::INIT_OK) { | 60 if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { |
| 60 error_handler()->OnSingleDatatypeUnrecoverableError( | 61 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 61 FROM_HERE, | 62 FROM_HERE, |
| 62 "Failed to look up data for received change with id " + | 63 "Failed to look up data for received change with id " + |
| 63 base::Int64ToString(it->id)); | 64 base::Int64ToString(it->id)); |
| 64 return; | 65 return; |
| 65 } | 66 } |
| 66 syncer_changes_.push_back( | 67 syncer_changes_.push_back( |
| 67 csync::SyncChange(action, | 68 syncer::SyncChange(action, |
| 68 csync::SyncData::CreateRemoteData( | 69 syncer::SyncData::CreateRemoteData( |
| 69 it->id, read_node.GetEntitySpecifics()))); | 70 it->id, read_node.GetEntitySpecifics()))); |
| 70 } | 71 } |
| 71 } | 72 } |
| 72 } | 73 } |
| 73 | 74 |
| 74 void GenericChangeProcessor::CommitChangesFromSyncModel() { | 75 void GenericChangeProcessor::CommitChangesFromSyncModel() { |
| 75 DCHECK(CalledOnValidThread()); | 76 DCHECK(CalledOnValidThread()); |
| 76 if (!running()) | 77 if (!running()) |
| 77 return; | 78 return; |
| 78 if (syncer_changes_.empty()) | 79 if (syncer_changes_.empty()) |
| 79 return; | 80 return; |
| 80 if (!local_service_) { | 81 if (!local_service_) { |
| 81 syncable::ModelType type = syncer_changes_[0].sync_data().GetDataType(); | 82 syncable::ModelType type = syncer_changes_[0].sync_data().GetDataType(); |
| 82 csync::SyncError error(FROM_HERE, "Local service destroyed.", type); | 83 syncer::SyncError error(FROM_HERE, "Local service destroyed.", type); |
| 83 error_handler()->OnSingleDatatypeUnrecoverableError(error.location(), | 84 error_handler()->OnSingleDatatypeUnrecoverableError(error.location(), |
| 84 error.message()); | 85 error.message()); |
| 85 return; | 86 return; |
| 86 } | 87 } |
| 87 csync::SyncError error = local_service_->ProcessSyncChanges(FROM_HERE, | 88 syncer::SyncError error = local_service_->ProcessSyncChanges(FROM_HERE, |
| 88 syncer_changes_); | 89 syncer_changes_); |
| 89 syncer_changes_.clear(); | 90 syncer_changes_.clear(); |
| 90 if (error.IsSet()) { | 91 if (error.IsSet()) { |
| 91 error_handler()->OnSingleDatatypeUnrecoverableError( | 92 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 92 error.location(), error.message()); | 93 error.location(), error.message()); |
| 93 } | 94 } |
| 94 } | 95 } |
| 95 | 96 |
| 96 csync::SyncError GenericChangeProcessor::GetSyncDataForType( | 97 syncer::SyncError GenericChangeProcessor::GetSyncDataForType( |
| 97 syncable::ModelType type, | 98 syncable::ModelType type, |
| 98 csync::SyncDataList* current_sync_data) { | 99 syncer::SyncDataList* current_sync_data) { |
| 99 DCHECK(CalledOnValidThread()); | 100 DCHECK(CalledOnValidThread()); |
| 100 std::string type_name = syncable::ModelTypeToString(type); | 101 std::string type_name = syncable::ModelTypeToString(type); |
| 101 csync::ReadTransaction trans(FROM_HERE, share_handle()); | 102 syncer::ReadTransaction trans(FROM_HERE, share_handle()); |
| 102 csync::ReadNode root(&trans); | 103 syncer::ReadNode root(&trans); |
| 103 if (root.InitByTagLookup(syncable::ModelTypeToRootTag(type)) != | 104 if (root.InitByTagLookup(syncable::ModelTypeToRootTag(type)) != |
| 104 csync::BaseNode::INIT_OK) { | 105 syncer::BaseNode::INIT_OK) { |
| 105 csync::SyncError error(FROM_HERE, | 106 syncer::SyncError error(FROM_HERE, |
| 106 "Server did not create the top-level " + type_name + | 107 "Server did not create the top-level " + type_name + |
| 107 " node. We might be running against an out-of-date server.", | 108 " node. We might be running against an out-of-date server.", |
| 108 type); | 109 type); |
| 109 return error; | 110 return error; |
| 110 } | 111 } |
| 111 | 112 |
| 112 // TODO(akalin): We'll have to do a tree traversal for bookmarks. | 113 // TODO(akalin): We'll have to do a tree traversal for bookmarks. |
| 113 DCHECK_NE(type, syncable::BOOKMARKS); | 114 DCHECK_NE(type, syncable::BOOKMARKS); |
| 114 | 115 |
| 115 int64 sync_child_id = root.GetFirstChildId(); | 116 int64 sync_child_id = root.GetFirstChildId(); |
| 116 while (sync_child_id != csync::kInvalidId) { | 117 while (sync_child_id != syncer::kInvalidId) { |
| 117 csync::ReadNode sync_child_node(&trans); | 118 syncer::ReadNode sync_child_node(&trans); |
| 118 if (sync_child_node.InitByIdLookup(sync_child_id) != | 119 if (sync_child_node.InitByIdLookup(sync_child_id) != |
| 119 csync::BaseNode::INIT_OK) { | 120 syncer::BaseNode::INIT_OK) { |
| 120 csync::SyncError error(FROM_HERE, | 121 syncer::SyncError error(FROM_HERE, |
| 121 "Failed to fetch child node for type " + type_name + ".", | 122 "Failed to fetch child node for type " + type_name + ".", |
| 122 type); | 123 type); |
| 123 return error; | 124 return error; |
| 124 } | 125 } |
| 125 current_sync_data->push_back(csync::SyncData::CreateRemoteData( | 126 current_sync_data->push_back(syncer::SyncData::CreateRemoteData( |
| 126 sync_child_node.GetId(), sync_child_node.GetEntitySpecifics())); | 127 sync_child_node.GetId(), sync_child_node.GetEntitySpecifics())); |
| 127 sync_child_id = sync_child_node.GetSuccessorId(); | 128 sync_child_id = sync_child_node.GetSuccessorId(); |
| 128 } | 129 } |
| 129 return csync::SyncError(); | 130 return syncer::SyncError(); |
| 130 } | 131 } |
| 131 | 132 |
| 132 namespace { | 133 namespace { |
| 133 | 134 |
| 134 // TODO(isherman): Investigating http://crbug.com/121592 | 135 // TODO(isherman): Investigating http://crbug.com/121592 |
| 135 // WARNING: this code is sensitive to compiler optimizations. Be careful | 136 // WARNING: this code is sensitive to compiler optimizations. Be careful |
| 136 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else | 137 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else |
| 137 // the compiler attempts to merge it with other calls, losing useful information | 138 // the compiler attempts to merge it with other calls, losing useful information |
| 138 // in breakpad uploads. | 139 // in breakpad uploads. |
| 139 csync::SyncError LogLookupFailure( | 140 syncer::SyncError LogLookupFailure( |
| 140 csync::BaseNode::InitByLookupResult lookup_result, | 141 syncer::BaseNode::InitByLookupResult lookup_result, |
| 141 const tracked_objects::Location& from_here, | 142 const tracked_objects::Location& from_here, |
| 142 const std::string& error_prefix, | 143 const std::string& error_prefix, |
| 143 syncable::ModelType type, | 144 syncable::ModelType type, |
| 144 DataTypeErrorHandler* error_handler) { | 145 DataTypeErrorHandler* error_handler) { |
| 145 switch (lookup_result) { | 146 switch (lookup_result) { |
| 146 case csync::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD: { | 147 case syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD: { |
| 147 csync::SyncError error; | 148 syncer::SyncError error; |
| 148 error.Reset(from_here, | 149 error.Reset(from_here, |
| 149 error_prefix + | 150 error_prefix + |
| 150 "could not find entry matching the lookup criteria.", | 151 "could not find entry matching the lookup criteria.", |
| 151 type); | 152 type); |
| 152 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 153 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 153 error.message()); | 154 error.message()); |
| 154 LOG(ERROR) << "Delete: Bad entry."; | 155 LOG(ERROR) << "Delete: Bad entry."; |
| 155 return error; | 156 return error; |
| 156 } | 157 } |
| 157 case csync::BaseNode::INIT_FAILED_ENTRY_IS_DEL: { | 158 case syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL: { |
| 158 csync::SyncError error; | 159 syncer::SyncError error; |
| 159 error.Reset(from_here, error_prefix + "entry is already deleted.", type); | 160 error.Reset(from_here, error_prefix + "entry is already deleted.", type); |
| 160 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 161 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 161 error.message()); | 162 error.message()); |
| 162 LOG(ERROR) << "Delete: Deleted entry."; | 163 LOG(ERROR) << "Delete: Deleted entry."; |
| 163 return error; | 164 return error; |
| 164 } | 165 } |
| 165 case csync::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: { | 166 case syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: { |
| 166 csync::SyncError error; | 167 syncer::SyncError error; |
| 167 error.Reset(from_here, error_prefix + "unable to decrypt", type); | 168 error.Reset(from_here, error_prefix + "unable to decrypt", type); |
| 168 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 169 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 169 error.message()); | 170 error.message()); |
| 170 LOG(ERROR) << "Delete: Undecryptable entry."; | 171 LOG(ERROR) << "Delete: Undecryptable entry."; |
| 171 return error; | 172 return error; |
| 172 } | 173 } |
| 173 case csync::BaseNode::INIT_FAILED_PRECONDITION: { | 174 case syncer::BaseNode::INIT_FAILED_PRECONDITION: { |
| 174 csync::SyncError error; | 175 syncer::SyncError error; |
| 175 error.Reset(from_here, | 176 error.Reset(from_here, |
| 176 error_prefix + "a precondition was not met for calling init.", | 177 error_prefix + "a precondition was not met for calling init.", |
| 177 type); | 178 type); |
| 178 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 179 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 179 error.message()); | 180 error.message()); |
| 180 LOG(ERROR) << "Delete: Failed precondition."; | 181 LOG(ERROR) << "Delete: Failed precondition."; |
| 181 return error; | 182 return error; |
| 182 } | 183 } |
| 183 default: { | 184 default: { |
| 184 csync::SyncError error; | 185 syncer::SyncError error; |
| 185 // Should have listed all the possible error cases above. | 186 // Should have listed all the possible error cases above. |
| 186 error.Reset(from_here, error_prefix + "unknown error", type); | 187 error.Reset(from_here, error_prefix + "unknown error", type); |
| 187 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 188 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 188 error.message()); | 189 error.message()); |
| 189 LOG(ERROR) << "Delete: Unknown error."; | 190 LOG(ERROR) << "Delete: Unknown error."; |
| 190 return error; | 191 return error; |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 } | 194 } |
| 194 | 195 |
| 195 csync::SyncError AttemptDelete(const csync::SyncChange& change, | 196 syncer::SyncError AttemptDelete(const syncer::SyncChange& change, |
| 196 syncable::ModelType type, | 197 syncable::ModelType type, |
| 197 const std::string& type_str, | 198 const std::string& type_str, |
| 198 csync::WriteNode* node, | 199 syncer::WriteNode* node, |
| 199 DataTypeErrorHandler* error_handler) { | 200 DataTypeErrorHandler* error_handler) { |
| 200 DCHECK_EQ(change.change_type(), csync::SyncChange::ACTION_DELETE); | 201 DCHECK_EQ(change.change_type(), syncer::SyncChange::ACTION_DELETE); |
| 201 if (change.sync_data().IsLocal()) { | 202 if (change.sync_data().IsLocal()) { |
| 202 const std::string& tag = change.sync_data().GetTag(); | 203 const std::string& tag = change.sync_data().GetTag(); |
| 203 if (tag.empty()) { | 204 if (tag.empty()) { |
| 204 csync::SyncError error( | 205 syncer::SyncError error( |
| 205 FROM_HERE, | 206 FROM_HERE, |
| 206 "Failed to delete " + type_str + " node. Local data, empty tag.", | 207 "Failed to delete " + type_str + " node. Local data, empty tag.", |
| 207 type); | 208 type); |
| 208 error_handler->OnSingleDatatypeUnrecoverableError(error.location(), | 209 error_handler->OnSingleDatatypeUnrecoverableError(error.location(), |
| 209 error.message()); | 210 error.message()); |
| 210 NOTREACHED(); | 211 NOTREACHED(); |
| 211 return error; | 212 return error; |
| 212 } | 213 } |
| 213 | 214 |
| 214 csync::BaseNode::InitByLookupResult result = | 215 syncer::BaseNode::InitByLookupResult result = |
| 215 node->InitByClientTagLookup(change.sync_data().GetDataType(), tag); | 216 node->InitByClientTagLookup(change.sync_data().GetDataType(), tag); |
| 216 if (result != csync::BaseNode::INIT_OK) { | 217 if (result != syncer::BaseNode::INIT_OK) { |
| 217 return LogLookupFailure( | 218 return LogLookupFailure( |
| 218 result, FROM_HERE, | 219 result, FROM_HERE, |
| 219 "Failed to delete " + type_str + " node. Local data, ", | 220 "Failed to delete " + type_str + " node. Local data, ", |
| 220 type, error_handler); | 221 type, error_handler); |
| 221 } | 222 } |
| 222 } else { | 223 } else { |
| 223 csync::BaseNode::InitByLookupResult result = | 224 syncer::BaseNode::InitByLookupResult result = |
| 224 node->InitByIdLookup(change.sync_data().GetRemoteId()); | 225 node->InitByIdLookup(change.sync_data().GetRemoteId()); |
| 225 if (result != csync::BaseNode::INIT_OK) { | 226 if (result != syncer::BaseNode::INIT_OK) { |
| 226 return LogLookupFailure( | 227 return LogLookupFailure( |
| 227 result, FROM_HERE, | 228 result, FROM_HERE, |
| 228 "Failed to delete " + type_str + " node. Non-local data, ", | 229 "Failed to delete " + type_str + " node. Non-local data, ", |
| 229 type, error_handler); | 230 type, error_handler); |
| 230 } | 231 } |
| 231 } | 232 } |
| 232 node->Remove(); | 233 node->Remove(); |
| 233 return csync::SyncError(); | 234 return syncer::SyncError(); |
| 234 } | 235 } |
| 235 | 236 |
| 236 } // namespace | 237 } // namespace |
| 237 | 238 |
| 238 // WARNING: this code is sensitive to compiler optimizations. Be careful | 239 // WARNING: this code is sensitive to compiler optimizations. Be careful |
| 239 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else | 240 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else |
| 240 // the compiler attempts to merge it with other calls, losing useful information | 241 // the compiler attempts to merge it with other calls, losing useful information |
| 241 // in breakpad uploads. | 242 // in breakpad uploads. |
| 242 csync::SyncError GenericChangeProcessor::ProcessSyncChanges( | 243 syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( |
| 243 const tracked_objects::Location& from_here, | 244 const tracked_objects::Location& from_here, |
| 244 const csync::SyncChangeList& list_of_changes) { | 245 const syncer::SyncChangeList& list_of_changes) { |
| 245 DCHECK(CalledOnValidThread()); | 246 DCHECK(CalledOnValidThread()); |
| 246 csync::WriteTransaction trans(from_here, share_handle()); | 247 syncer::WriteTransaction trans(from_here, share_handle()); |
| 247 | 248 |
| 248 for (csync::SyncChangeList::const_iterator iter = list_of_changes.begin(); | 249 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); |
| 249 iter != list_of_changes.end(); | 250 iter != list_of_changes.end(); |
| 250 ++iter) { | 251 ++iter) { |
| 251 const csync::SyncChange& change = *iter; | 252 const syncer::SyncChange& change = *iter; |
| 252 DCHECK_NE(change.sync_data().GetDataType(), syncable::UNSPECIFIED); | 253 DCHECK_NE(change.sync_data().GetDataType(), syncable::UNSPECIFIED); |
| 253 syncable::ModelType type = change.sync_data().GetDataType(); | 254 syncable::ModelType type = change.sync_data().GetDataType(); |
| 254 std::string type_str = syncable::ModelTypeToString(type); | 255 std::string type_str = syncable::ModelTypeToString(type); |
| 255 csync::WriteNode sync_node(&trans); | 256 syncer::WriteNode sync_node(&trans); |
| 256 if (change.change_type() == csync::SyncChange::ACTION_DELETE) { | 257 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { |
| 257 csync::SyncError error = AttemptDelete(change, type, type_str, &sync_node, | 258 syncer::SyncError error = |
| 258 error_handler()); | 259 AttemptDelete(change, type, type_str, &sync_node, |
| 260 error_handler()); |
| 259 if (error.IsSet()) { | 261 if (error.IsSet()) { |
| 260 NOTREACHED(); | 262 NOTREACHED(); |
| 261 return error; | 263 return error; |
| 262 } | 264 } |
| 263 } else if (change.change_type() == csync::SyncChange::ACTION_ADD) { | 265 } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { |
| 264 // TODO(sync): Handle other types of creation (custom parents, folders, | 266 // TODO(sync): Handle other types of creation (custom parents, folders, |
| 265 // etc.). | 267 // etc.). |
| 266 csync::ReadNode root_node(&trans); | 268 syncer::ReadNode root_node(&trans); |
| 267 if (root_node.InitByTagLookup( | 269 if (root_node.InitByTagLookup( |
| 268 syncable::ModelTypeToRootTag(change.sync_data().GetDataType())) != | 270 syncable::ModelTypeToRootTag(change.sync_data().GetDataType())) != |
| 269 csync::BaseNode::INIT_OK) { | 271 syncer::BaseNode::INIT_OK) { |
| 270 csync::SyncError error(FROM_HERE, | 272 syncer::SyncError error(FROM_HERE, |
| 271 "Failed to look up root node for type " + type_str, | 273 "Failed to look up root node for type " + type_str, |
| 272 type); | 274 type); |
| 273 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 275 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 274 error.message()); | 276 error.message()); |
| 275 NOTREACHED(); | 277 NOTREACHED(); |
| 276 LOG(ERROR) << "Create: no root node."; | 278 LOG(ERROR) << "Create: no root node."; |
| 277 return error; | 279 return error; |
| 278 } | 280 } |
| 279 csync::WriteNode::InitUniqueByCreationResult result = | 281 syncer::WriteNode::InitUniqueByCreationResult result = |
| 280 sync_node.InitUniqueByCreation(change.sync_data().GetDataType(), | 282 sync_node.InitUniqueByCreation(change.sync_data().GetDataType(), |
| 281 root_node, | 283 root_node, |
| 282 change.sync_data().GetTag()); | 284 change.sync_data().GetTag()); |
| 283 if (result != csync::WriteNode::INIT_SUCCESS) { | 285 if (result != syncer::WriteNode::INIT_SUCCESS) { |
| 284 std::string error_prefix = "Failed to create " + type_str + " node: "; | 286 std::string error_prefix = "Failed to create " + type_str + " node: "; |
| 285 switch (result) { | 287 switch (result) { |
| 286 case csync::WriteNode::INIT_FAILED_EMPTY_TAG: { | 288 case syncer::WriteNode::INIT_FAILED_EMPTY_TAG: { |
| 287 csync::SyncError error; | 289 syncer::SyncError error; |
| 288 error.Reset(FROM_HERE, error_prefix + "empty tag", type); | 290 error.Reset(FROM_HERE, error_prefix + "empty tag", type); |
| 289 error_handler()->OnSingleDatatypeUnrecoverableError( | 291 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 290 FROM_HERE, error.message()); | 292 FROM_HERE, error.message()); |
| 291 LOG(ERROR) << "Create: Empty tag."; | 293 LOG(ERROR) << "Create: Empty tag."; |
| 292 return error; | 294 return error; |
| 293 } | 295 } |
| 294 case csync::WriteNode::INIT_FAILED_ENTRY_ALREADY_EXISTS: { | 296 case syncer::WriteNode::INIT_FAILED_ENTRY_ALREADY_EXISTS: { |
| 295 csync::SyncError error; | 297 syncer::SyncError error; |
| 296 error.Reset(FROM_HERE, error_prefix + "entry already exists", type); | 298 error.Reset(FROM_HERE, error_prefix + "entry already exists", type); |
| 297 error_handler()->OnSingleDatatypeUnrecoverableError( | 299 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 298 FROM_HERE, error.message()); | 300 FROM_HERE, error.message()); |
| 299 LOG(ERROR) << "Create: Entry exists."; | 301 LOG(ERROR) << "Create: Entry exists."; |
| 300 return error; | 302 return error; |
| 301 } | 303 } |
| 302 case csync::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: { | 304 case syncer::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: { |
| 303 csync::SyncError error; | 305 syncer::SyncError error; |
| 304 error.Reset(FROM_HERE, error_prefix + "failed to create entry", | 306 error.Reset(FROM_HERE, error_prefix + "failed to create entry", |
| 305 type); | 307 type); |
| 306 error_handler()->OnSingleDatatypeUnrecoverableError( | 308 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 307 FROM_HERE, error.message()); | 309 FROM_HERE, error.message()); |
| 308 LOG(ERROR) << "Create: Could not create entry."; | 310 LOG(ERROR) << "Create: Could not create entry."; |
| 309 return error; | 311 return error; |
| 310 } | 312 } |
| 311 case csync::WriteNode::INIT_FAILED_SET_PREDECESSOR: { | 313 case syncer::WriteNode::INIT_FAILED_SET_PREDECESSOR: { |
| 312 csync::SyncError error; | 314 syncer::SyncError error; |
| 313 error.Reset(FROM_HERE, error_prefix + "failed to set predecessor", | 315 error.Reset(FROM_HERE, error_prefix + "failed to set predecessor", |
| 314 type); | 316 type); |
| 315 error_handler()->OnSingleDatatypeUnrecoverableError( | 317 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 316 FROM_HERE, error.message()); | 318 FROM_HERE, error.message()); |
| 317 LOG(ERROR) << "Create: Bad predecessor."; | 319 LOG(ERROR) << "Create: Bad predecessor."; |
| 318 return error; | 320 return error; |
| 319 } | 321 } |
| 320 default: { | 322 default: { |
| 321 csync::SyncError error; | 323 syncer::SyncError error; |
| 322 error.Reset(FROM_HERE, error_prefix + "unknown error", type); | 324 error.Reset(FROM_HERE, error_prefix + "unknown error", type); |
| 323 error_handler()->OnSingleDatatypeUnrecoverableError( | 325 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 324 FROM_HERE, error.message()); | 326 FROM_HERE, error.message()); |
| 325 LOG(ERROR) << "Create: Unknown error."; | 327 LOG(ERROR) << "Create: Unknown error."; |
| 326 return error; | 328 return error; |
| 327 } | 329 } |
| 328 } | 330 } |
| 329 } | 331 } |
| 330 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); | 332 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); |
| 331 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); | 333 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); |
| 332 } else if (change.change_type() == csync::SyncChange::ACTION_UPDATE) { | 334 } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) { |
| 333 // TODO(zea): consider having this logic for all possible changes? | 335 // TODO(zea): consider having this logic for all possible changes? |
| 334 csync::BaseNode::InitByLookupResult result = | 336 syncer::BaseNode::InitByLookupResult result = |
| 335 sync_node.InitByClientTagLookup(change.sync_data().GetDataType(), | 337 sync_node.InitByClientTagLookup(change.sync_data().GetDataType(), |
| 336 change.sync_data().GetTag()); | 338 change.sync_data().GetTag()); |
| 337 if (result != csync::BaseNode::INIT_OK) { | 339 if (result != syncer::BaseNode::INIT_OK) { |
| 338 if (result == csync::BaseNode::INIT_FAILED_PRECONDITION) { | 340 if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) { |
| 339 csync::SyncError error; | 341 syncer::SyncError error; |
| 340 error.Reset(FROM_HERE, | 342 error.Reset(FROM_HERE, |
| 341 "Failed to load entry w/empty tag for " + type_str + ".", | 343 "Failed to load entry w/empty tag for " + type_str + ".", |
| 342 type); | 344 type); |
| 343 error_handler()->OnSingleDatatypeUnrecoverableError( | 345 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 344 FROM_HERE, error.message()); | 346 FROM_HERE, error.message()); |
| 345 LOG(ERROR) << "Update: Empty tag."; | 347 LOG(ERROR) << "Update: Empty tag."; |
| 346 return error; | 348 return error; |
| 347 } else if (result == csync::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) { | 349 } else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) { |
| 348 csync::SyncError error; | 350 syncer::SyncError error; |
| 349 error.Reset(FROM_HERE, | 351 error.Reset(FROM_HERE, |
| 350 "Failed to load bad entry for " + type_str + ".", | 352 "Failed to load bad entry for " + type_str + ".", |
| 351 type); | 353 type); |
| 352 error_handler()->OnSingleDatatypeUnrecoverableError( | 354 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 353 FROM_HERE, error.message()); | 355 FROM_HERE, error.message()); |
| 354 LOG(ERROR) << "Update: bad entry."; | 356 LOG(ERROR) << "Update: bad entry."; |
| 355 return error; | 357 return error; |
| 356 } else if (result == csync::BaseNode::INIT_FAILED_ENTRY_IS_DEL) { | 358 } else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL) { |
| 357 csync::SyncError error; | 359 syncer::SyncError error; |
| 358 error.Reset(FROM_HERE, | 360 error.Reset(FROM_HERE, |
| 359 "Failed to load deleted entry for " + type_str + ".", | 361 "Failed to load deleted entry for " + type_str + ".", |
| 360 type); | 362 type); |
| 361 error_handler()->OnSingleDatatypeUnrecoverableError( | 363 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 362 FROM_HERE, error.message()); | 364 FROM_HERE, error.message()); |
| 363 LOG(ERROR) << "Update: deleted entry."; | 365 LOG(ERROR) << "Update: deleted entry."; |
| 364 return error; | 366 return error; |
| 365 } else { | 367 } else { |
| 366 csync::Cryptographer* crypto = trans.GetCryptographer(); | 368 syncer::Cryptographer* crypto = trans.GetCryptographer(); |
| 367 syncable::ModelTypeSet encrypted_types(crypto->GetEncryptedTypes()); | 369 syncable::ModelTypeSet encrypted_types(crypto->GetEncryptedTypes()); |
| 368 const sync_pb::EntitySpecifics& specifics = | 370 const sync_pb::EntitySpecifics& specifics = |
| 369 sync_node.GetEntry()->Get(syncable::SPECIFICS); | 371 sync_node.GetEntry()->Get(syncable::SPECIFICS); |
| 370 CHECK(specifics.has_encrypted()); | 372 CHECK(specifics.has_encrypted()); |
| 371 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted()); | 373 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted()); |
| 372 const bool agreement = encrypted_types.Has(type); | 374 const bool agreement = encrypted_types.Has(type); |
| 373 if (!agreement && !can_decrypt) { | 375 if (!agreement && !can_decrypt) { |
| 374 csync::SyncError error; | 376 syncer::SyncError error; |
| 375 error.Reset(FROM_HERE, | 377 error.Reset(FROM_HERE, |
| 376 "Failed to load encrypted entry, missing key and " | 378 "Failed to load encrypted entry, missing key and " |
| 377 "nigori mismatch for " + type_str + ".", | 379 "nigori mismatch for " + type_str + ".", |
| 378 type); | 380 type); |
| 379 error_handler()->OnSingleDatatypeUnrecoverableError( | 381 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 380 FROM_HERE, error.message()); | 382 FROM_HERE, error.message()); |
| 381 LOG(ERROR) << "Update: encr case 1."; | 383 LOG(ERROR) << "Update: encr case 1."; |
| 382 return error; | 384 return error; |
| 383 } else if (agreement && can_decrypt) { | 385 } else if (agreement && can_decrypt) { |
| 384 csync::SyncError error; | 386 syncer::SyncError error; |
| 385 error.Reset(FROM_HERE, | 387 error.Reset(FROM_HERE, |
| 386 "Failed to load encrypted entry, we have the key " | 388 "Failed to load encrypted entry, we have the key " |
| 387 "and the nigori matches (?!) for " + type_str + ".", | 389 "and the nigori matches (?!) for " + type_str + ".", |
| 388 type); | 390 type); |
| 389 error_handler()->OnSingleDatatypeUnrecoverableError( | 391 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 390 FROM_HERE, error.message()); | 392 FROM_HERE, error.message()); |
| 391 LOG(ERROR) << "Update: encr case 2."; | 393 LOG(ERROR) << "Update: encr case 2."; |
| 392 return error; | 394 return error; |
| 393 } else if (agreement) { | 395 } else if (agreement) { |
| 394 csync::SyncError error; | 396 syncer::SyncError error; |
| 395 error.Reset(FROM_HERE, | 397 error.Reset(FROM_HERE, |
| 396 "Failed to load encrypted entry, missing key and " | 398 "Failed to load encrypted entry, missing key and " |
| 397 "the nigori matches for " + type_str + ".", | 399 "the nigori matches for " + type_str + ".", |
| 398 type); | 400 type); |
| 399 error_handler()->OnSingleDatatypeUnrecoverableError( | 401 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 400 FROM_HERE, error.message()); | 402 FROM_HERE, error.message()); |
| 401 LOG(ERROR) << "Update: encr case 3."; | 403 LOG(ERROR) << "Update: encr case 3."; |
| 402 return error; | 404 return error; |
| 403 } else { | 405 } else { |
| 404 csync::SyncError error; | 406 syncer::SyncError error; |
| 405 error.Reset(FROM_HERE, | 407 error.Reset(FROM_HERE, |
| 406 "Failed to load encrypted entry, we have the key" | 408 "Failed to load encrypted entry, we have the key" |
| 407 "(?!) and nigori mismatch for " + type_str + ".", | 409 "(?!) and nigori mismatch for " + type_str + ".", |
| 408 type); | 410 type); |
| 409 error_handler()->OnSingleDatatypeUnrecoverableError( | 411 error_handler()->OnSingleDatatypeUnrecoverableError( |
| 410 FROM_HERE, error.message()); | 412 FROM_HERE, error.message()); |
| 411 LOG(ERROR) << "Update: encr case 4."; | 413 LOG(ERROR) << "Update: encr case 4."; |
| 412 return error; | 414 return error; |
| 413 } | 415 } |
| 414 } | 416 } |
| 415 } else { | 417 } else { |
| 416 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); | 418 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); |
| 417 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); | 419 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); |
| 418 // TODO(sync): Support updating other parts of the sync node (title, | 420 // TODO(sync): Support updating other parts of the sync node (title, |
| 419 // successor, parent, etc.). | 421 // successor, parent, etc.). |
| 420 } | 422 } |
| 421 } else { | 423 } else { |
| 422 csync::SyncError error( | 424 syncer::SyncError error( |
| 423 FROM_HERE, | 425 FROM_HERE, |
| 424 "Received unset csync::SyncChange in the change processor.", | 426 "Received unset syncer::SyncChange in the change processor.", |
| 425 type); | 427 type); |
| 426 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 428 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
| 427 error.message()); | 429 error.message()); |
| 428 NOTREACHED(); | 430 NOTREACHED(); |
| 429 LOG(ERROR) << "Unset sync change."; | 431 LOG(ERROR) << "Unset sync change."; |
| 430 return error; | 432 return error; |
| 431 } | 433 } |
| 432 } | 434 } |
| 433 return csync::SyncError(); | 435 return syncer::SyncError(); |
| 434 } | 436 } |
| 435 | 437 |
| 436 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( | 438 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( |
| 437 syncable::ModelType type, | 439 syncable::ModelType type, |
| 438 bool* has_nodes) { | 440 bool* has_nodes) { |
| 439 DCHECK(CalledOnValidThread()); | 441 DCHECK(CalledOnValidThread()); |
| 440 DCHECK(has_nodes); | 442 DCHECK(has_nodes); |
| 441 DCHECK_NE(type, syncable::UNSPECIFIED); | 443 DCHECK_NE(type, syncable::UNSPECIFIED); |
| 442 std::string type_name = syncable::ModelTypeToString(type); | 444 std::string type_name = syncable::ModelTypeToString(type); |
| 443 std::string err_str = "Server did not create the top-level " + type_name + | 445 std::string err_str = "Server did not create the top-level " + type_name + |
| 444 " node. We might be running against an out-of-date server."; | 446 " node. We might be running against an out-of-date server."; |
| 445 *has_nodes = false; | 447 *has_nodes = false; |
| 446 csync::ReadTransaction trans(FROM_HERE, share_handle()); | 448 syncer::ReadTransaction trans(FROM_HERE, share_handle()); |
| 447 csync::ReadNode type_root_node(&trans); | 449 syncer::ReadNode type_root_node(&trans); |
| 448 if (type_root_node.InitByTagLookup(syncable::ModelTypeToRootTag(type)) != | 450 if (type_root_node.InitByTagLookup(syncable::ModelTypeToRootTag(type)) != |
| 449 csync::BaseNode::INIT_OK) { | 451 syncer::BaseNode::INIT_OK) { |
| 450 LOG(ERROR) << err_str; | 452 LOG(ERROR) << err_str; |
| 451 return false; | 453 return false; |
| 452 } | 454 } |
| 453 | 455 |
| 454 // The sync model has user created nodes if the type's root node has any | 456 // The sync model has user created nodes if the type's root node has any |
| 455 // children. | 457 // children. |
| 456 *has_nodes = type_root_node.HasChildren(); | 458 *has_nodes = type_root_node.HasChildren(); |
| 457 return true; | 459 return true; |
| 458 } | 460 } |
| 459 | 461 |
| 460 bool GenericChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) { | 462 bool GenericChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) { |
| 461 DCHECK(CalledOnValidThread()); | 463 DCHECK(CalledOnValidThread()); |
| 462 DCHECK_NE(type, syncable::UNSPECIFIED); | 464 DCHECK_NE(type, syncable::UNSPECIFIED); |
| 463 // We only access the cryptographer while holding a transaction. | 465 // We only access the cryptographer while holding a transaction. |
| 464 csync::ReadTransaction trans(FROM_HERE, share_handle()); | 466 syncer::ReadTransaction trans(FROM_HERE, share_handle()); |
| 465 const syncable::ModelTypeSet encrypted_types = GetEncryptedTypes(&trans); | 467 const syncable::ModelTypeSet encrypted_types = GetEncryptedTypes(&trans); |
| 466 return !encrypted_types.Has(type) || | 468 return !encrypted_types.Has(type) || |
| 467 trans.GetCryptographer()->is_ready(); | 469 trans.GetCryptographer()->is_ready(); |
| 468 } | 470 } |
| 469 | 471 |
| 470 void GenericChangeProcessor::StartImpl(Profile* profile) { | 472 void GenericChangeProcessor::StartImpl(Profile* profile) { |
| 471 DCHECK(CalledOnValidThread()); | 473 DCHECK(CalledOnValidThread()); |
| 472 } | 474 } |
| 473 | 475 |
| 474 void GenericChangeProcessor::StopImpl() { | 476 void GenericChangeProcessor::StopImpl() { |
| 475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 476 } | 478 } |
| 477 | 479 |
| 478 csync::UserShare* GenericChangeProcessor::share_handle() const { | 480 syncer::UserShare* GenericChangeProcessor::share_handle() const { |
| 479 DCHECK(CalledOnValidThread()); | 481 DCHECK(CalledOnValidThread()); |
| 480 return share_handle_; | 482 return share_handle_; |
| 481 } | 483 } |
| 482 | 484 |
| 483 } // namespace browser_sync | 485 } // namespace browser_sync |
| OLD | NEW |