| 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/glue/autofill_change_processor.h" | 5 #include "chrome/browser/sync/glue/autofill_change_processor.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/tracked.h" | 11 #include "base/tracked.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "chrome/browser/autofill/personal_data_manager.h" | 13 #include "chrome/browser/autofill/personal_data_manager.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/sync/glue/autofill_model_associator.h" | 15 #include "chrome/browser/sync/glue/autofill_model_associator.h" |
| 16 #include "chrome/browser/sync/glue/do_optimistic_refresh_task.h" | 16 #include "chrome/browser/sync/glue/do_optimistic_refresh_task.h" |
| 17 #include "chrome/browser/sync/internal_api/change_record.h" |
| 17 #include "chrome/browser/sync/internal_api/read_node.h" | 18 #include "chrome/browser/sync/internal_api/read_node.h" |
| 18 #include "chrome/browser/sync/internal_api/write_node.h" | 19 #include "chrome/browser/sync/internal_api/write_node.h" |
| 19 #include "chrome/browser/sync/internal_api/write_transaction.h" | 20 #include "chrome/browser/sync/internal_api/write_transaction.h" |
| 20 #include "chrome/browser/sync/profile_sync_service.h" | 21 #include "chrome/browser/sync/profile_sync_service.h" |
| 21 #include "chrome/browser/webdata/autofill_change.h" | 22 #include "chrome/browser/webdata/autofill_change.h" |
| 22 #include "chrome/browser/webdata/autofill_table.h" | 23 #include "chrome/browser/webdata/autofill_table.h" |
| 23 #include "chrome/browser/webdata/web_database.h" | 24 #include "chrome/browser/webdata/web_database.h" |
| 24 #include "chrome/browser/webdata/web_data_service.h" | 25 #include "chrome/browser/webdata/web_data_service.h" |
| 25 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
| 26 #include "chrome/common/guid.h" | 27 #include "chrome/common/guid.h" |
| 27 #include "content/common/notification_service.h" | 28 #include "content/common/notification_service.h" |
| 28 | 29 |
| 29 namespace browser_sync { | 30 namespace browser_sync { |
| 30 | 31 |
| 31 struct AutofillChangeProcessor::AutofillChangeRecord { | 32 struct AutofillChangeProcessor::AutofillChangeRecord { |
| 32 sync_api::SyncManager::ChangeRecord::Action action_; | 33 sync_api::ChangeRecord::Action action_; |
| 33 int64 id_; | 34 int64 id_; |
| 34 sync_pb::AutofillSpecifics autofill_; | 35 sync_pb::AutofillSpecifics autofill_; |
| 35 AutofillChangeRecord(sync_api::SyncManager::ChangeRecord::Action action, | 36 AutofillChangeRecord(sync_api::ChangeRecord::Action action, |
| 36 int64 id, const sync_pb::AutofillSpecifics& autofill) | 37 int64 id, const sync_pb::AutofillSpecifics& autofill) |
| 37 : action_(action), | 38 : action_(action), |
| 38 id_(id), | 39 id_(id), |
| 39 autofill_(autofill) { } | 40 autofill_(autofill) { } |
| 40 }; | 41 }; |
| 41 | 42 |
| 42 AutofillChangeProcessor::AutofillChangeProcessor( | 43 AutofillChangeProcessor::AutofillChangeProcessor( |
| 43 AutofillModelAssociator* model_associator, | 44 AutofillModelAssociator* model_associator, |
| 44 WebDatabase* web_database, | 45 WebDatabase* web_database, |
| 45 PersonalDataManager* personal_data, | 46 PersonalDataManager* personal_data, |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 "Autofill node lookup failed."); | 190 "Autofill node lookup failed."); |
| 190 return; | 191 return; |
| 191 } | 192 } |
| 192 model_associator_->Disassociate(sync_node.GetId()); | 193 model_associator_->Disassociate(sync_node.GetId()); |
| 193 sync_node.Remove(); | 194 sync_node.Remove(); |
| 194 } | 195 } |
| 195 } | 196 } |
| 196 | 197 |
| 197 void AutofillChangeProcessor::ApplyChangesFromSyncModel( | 198 void AutofillChangeProcessor::ApplyChangesFromSyncModel( |
| 198 const sync_api::BaseTransaction* trans, | 199 const sync_api::BaseTransaction* trans, |
| 199 const sync_api::SyncManager::ChangeRecord* changes, | 200 const sync_api::ImmutableChangeRecordList& changes) { |
| 200 int change_count) { | |
| 201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 202 if (!running()) | 202 if (!running()) |
| 203 return; | 203 return; |
| 204 StopObserving(); | 204 StopObserving(); |
| 205 | 205 |
| 206 sync_api::ReadNode autofill_root(trans); | 206 sync_api::ReadNode autofill_root(trans); |
| 207 if (!autofill_root.InitByTagLookup(kAutofillTag)) { | 207 if (!autofill_root.InitByTagLookup(kAutofillTag)) { |
| 208 error_handler()->OnUnrecoverableError(FROM_HERE, | 208 error_handler()->OnUnrecoverableError(FROM_HERE, |
| 209 "Autofill root node lookup failed."); | 209 "Autofill root node lookup failed."); |
| 210 return; | 210 return; |
| 211 } | 211 } |
| 212 | 212 |
| 213 for (int i = 0; i < change_count; ++i) { | 213 for (sync_api::ChangeRecordList::const_iterator it = |
| 214 sync_api::SyncManager::ChangeRecord::Action action(changes[i].action); | 214 changes.Get().begin(); it != changes.Get().end(); ++it) { |
| 215 if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE == action) { | 215 sync_api::ChangeRecord::Action action(it->action); |
| 216 DCHECK(changes[i].specifics.HasExtension(sync_pb::autofill)) | 216 if (sync_api::ChangeRecord::ACTION_DELETE == action) { |
| 217 DCHECK(it->specifics.HasExtension(sync_pb::autofill)) |
| 217 << "Autofill specifics data not present on delete!"; | 218 << "Autofill specifics data not present on delete!"; |
| 218 const sync_pb::AutofillSpecifics& autofill = | 219 const sync_pb::AutofillSpecifics& autofill = |
| 219 changes[i].specifics.GetExtension(sync_pb::autofill); | 220 it->specifics.GetExtension(sync_pb::autofill); |
| 220 if (autofill.has_value()) { | 221 if (autofill.has_value()) { |
| 221 autofill_changes_.push_back(AutofillChangeRecord(changes[i].action, | 222 autofill_changes_.push_back(AutofillChangeRecord(it->action, |
| 222 changes[i].id, | 223 it->id, |
| 223 autofill)); | 224 autofill)); |
| 224 } else if (autofill.has_profile()) { | 225 } else if (autofill.has_profile()) { |
| 225 LOG(WARNING) << "Change for old-style autofill profile being dropped!"; | 226 LOG(WARNING) << "Change for old-style autofill profile being dropped!"; |
| 226 } else { | 227 } else { |
| 227 NOTREACHED() << "Autofill specifics has no data!"; | 228 NOTREACHED() << "Autofill specifics has no data!"; |
| 228 } | 229 } |
| 229 continue; | 230 continue; |
| 230 } | 231 } |
| 231 | 232 |
| 232 // Handle an update or add. | 233 // Handle an update or add. |
| 233 sync_api::ReadNode sync_node(trans); | 234 sync_api::ReadNode sync_node(trans); |
| 234 if (!sync_node.InitByIdLookup(changes[i].id)) { | 235 if (!sync_node.InitByIdLookup(it->id)) { |
| 235 error_handler()->OnUnrecoverableError(FROM_HERE, | 236 error_handler()->OnUnrecoverableError(FROM_HERE, |
| 236 "Autofill node lookup failed."); | 237 "Autofill node lookup failed."); |
| 237 return; | 238 return; |
| 238 } | 239 } |
| 239 | 240 |
| 240 // Check that the changed node is a child of the autofills folder. | 241 // Check that the changed node is a child of the autofills folder. |
| 241 DCHECK(autofill_root.GetId() == sync_node.GetParentId()); | 242 DCHECK(autofill_root.GetId() == sync_node.GetParentId()); |
| 242 DCHECK(syncable::AUTOFILL == sync_node.GetModelType()); | 243 DCHECK(syncable::AUTOFILL == sync_node.GetModelType()); |
| 243 | 244 |
| 244 const sync_pb::AutofillSpecifics& autofill( | 245 const sync_pb::AutofillSpecifics& autofill( |
| 245 sync_node.GetAutofillSpecifics()); | 246 sync_node.GetAutofillSpecifics()); |
| 246 int64 sync_id = sync_node.GetId(); | 247 int64 sync_id = sync_node.GetId(); |
| 247 if (autofill.has_value()) { | 248 if (autofill.has_value()) { |
| 248 autofill_changes_.push_back(AutofillChangeRecord(changes[i].action, | 249 autofill_changes_.push_back(AutofillChangeRecord(it->action, |
| 249 sync_id, autofill)); | 250 sync_id, autofill)); |
| 250 } else if (autofill.has_profile()) { | 251 } else if (autofill.has_profile()) { |
| 251 LOG(WARNING) << "Change for old-style autofill profile being dropped!"; | 252 LOG(WARNING) << "Change for old-style autofill profile being dropped!"; |
| 252 } else { | 253 } else { |
| 253 NOTREACHED() << "Autofill specifics has no data!"; | 254 NOTREACHED() << "Autofill specifics has no data!"; |
| 254 } | 255 } |
| 255 } | 256 } |
| 256 | 257 |
| 257 StartObserving(); | 258 StartObserving(); |
| 258 } | 259 } |
| 259 | 260 |
| 260 void AutofillChangeProcessor::CommitChangesFromSyncModel() { | 261 void AutofillChangeProcessor::CommitChangesFromSyncModel() { |
| 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 262 if (!running()) | 263 if (!running()) |
| 263 return; | 264 return; |
| 264 StopObserving(); | 265 StopObserving(); |
| 265 | 266 |
| 266 std::vector<AutofillEntry> new_entries; | 267 std::vector<AutofillEntry> new_entries; |
| 267 for (unsigned int i = 0; i < autofill_changes_.size(); i++) { | 268 for (unsigned int i = 0; i < autofill_changes_.size(); i++) { |
| 268 // Handle deletions. | 269 // Handle deletions. |
| 269 if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE == | 270 if (sync_api::ChangeRecord::ACTION_DELETE == |
| 270 autofill_changes_[i].action_) { | 271 autofill_changes_[i].action_) { |
| 271 if (autofill_changes_[i].autofill_.has_value()) { | 272 if (autofill_changes_[i].autofill_.has_value()) { |
| 272 ApplySyncAutofillEntryDelete(autofill_changes_[i].autofill_); | 273 ApplySyncAutofillEntryDelete(autofill_changes_[i].autofill_); |
| 273 } else if (autofill_changes_[i].autofill_.has_profile()) { | 274 } else if (autofill_changes_[i].autofill_.has_profile()) { |
| 274 ApplySyncAutofillProfileDelete(autofill_changes_[i].id_); | 275 ApplySyncAutofillProfileDelete(autofill_changes_[i].id_); |
| 275 } else { | 276 } else { |
| 276 NOTREACHED() << "Autofill's CommitChanges received change with no" | 277 NOTREACHED() << "Autofill's CommitChanges received change with no" |
| 277 " data!"; | 278 " data!"; |
| 278 } | 279 } |
| 279 continue; | 280 continue; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 310 const sync_pb::AutofillSpecifics& autofill) { | 311 const sync_pb::AutofillSpecifics& autofill) { |
| 311 if (!web_database_->GetAutofillTable()->RemoveFormElement( | 312 if (!web_database_->GetAutofillTable()->RemoveFormElement( |
| 312 UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()))) { | 313 UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()))) { |
| 313 error_handler()->OnUnrecoverableError(FROM_HERE, | 314 error_handler()->OnUnrecoverableError(FROM_HERE, |
| 314 "Could not remove autofill node."); | 315 "Could not remove autofill node."); |
| 315 return; | 316 return; |
| 316 } | 317 } |
| 317 } | 318 } |
| 318 | 319 |
| 319 void AutofillChangeProcessor::ApplySyncAutofillEntryChange( | 320 void AutofillChangeProcessor::ApplySyncAutofillEntryChange( |
| 320 sync_api::SyncManager::ChangeRecord::Action action, | 321 sync_api::ChangeRecord::Action action, |
| 321 const sync_pb::AutofillSpecifics& autofill, | 322 const sync_pb::AutofillSpecifics& autofill, |
| 322 std::vector<AutofillEntry>* new_entries, | 323 std::vector<AutofillEntry>* new_entries, |
| 323 int64 sync_id) { | 324 int64 sync_id) { |
| 324 DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action); | 325 DCHECK_NE(sync_api::ChangeRecord::ACTION_DELETE, action); |
| 325 | 326 |
| 326 std::vector<base::Time> timestamps; | 327 std::vector<base::Time> timestamps; |
| 327 size_t timestamps_size = autofill.usage_timestamp_size(); | 328 size_t timestamps_size = autofill.usage_timestamp_size(); |
| 328 for (size_t c = 0; c < timestamps_size; ++c) { | 329 for (size_t c = 0; c < timestamps_size; ++c) { |
| 329 timestamps.push_back( | 330 timestamps.push_back( |
| 330 base::Time::FromInternalValue(autofill.usage_timestamp(c))); | 331 base::Time::FromInternalValue(autofill.usage_timestamp(c))); |
| 331 } | 332 } |
| 332 AutofillKey k(UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value())); | 333 AutofillKey k(UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value())); |
| 333 AutofillEntry new_entry(k, timestamps); | 334 AutofillEntry new_entry(k, timestamps); |
| 334 | 335 |
| 335 new_entries->push_back(new_entry); | 336 new_entries->push_back(new_entry); |
| 336 std::string tag(AutofillModelAssociator::KeyToTag(k.name(), k.value())); | 337 std::string tag(AutofillModelAssociator::KeyToTag(k.name(), k.value())); |
| 337 if (action == sync_api::SyncManager::ChangeRecord::ACTION_ADD) | 338 if (action == sync_api::ChangeRecord::ACTION_ADD) |
| 338 model_associator_->Associate(&tag, sync_id); | 339 model_associator_->Associate(&tag, sync_id); |
| 339 } | 340 } |
| 340 | 341 |
| 341 void AutofillChangeProcessor::ApplySyncAutofillProfileChange( | 342 void AutofillChangeProcessor::ApplySyncAutofillProfileChange( |
| 342 sync_api::SyncManager::ChangeRecord::Action action, | 343 sync_api::ChangeRecord::Action action, |
| 343 const sync_pb::AutofillProfileSpecifics& profile, | 344 const sync_pb::AutofillProfileSpecifics& profile, |
| 344 int64 sync_id) { | 345 int64 sync_id) { |
| 345 DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action); | 346 DCHECK_NE(sync_api::ChangeRecord::ACTION_DELETE, action); |
| 346 | 347 |
| 347 switch (action) { | 348 switch (action) { |
| 348 case sync_api::SyncManager::ChangeRecord::ACTION_ADD: { | 349 case sync_api::ChangeRecord::ACTION_ADD: { |
| 349 std::string guid(guid::GenerateGUID()); | 350 std::string guid(guid::GenerateGUID()); |
| 350 if (guid::IsValidGUID(guid) == false) { | 351 if (guid::IsValidGUID(guid) == false) { |
| 351 DCHECK(false) << "Guid generated is invalid " << guid; | 352 DCHECK(false) << "Guid generated is invalid " << guid; |
| 352 return; | 353 return; |
| 353 } | 354 } |
| 354 scoped_ptr<AutofillProfile> p(new AutofillProfile); | 355 scoped_ptr<AutofillProfile> p(new AutofillProfile); |
| 355 p->set_guid(guid); | 356 p->set_guid(guid); |
| 356 AutofillModelAssociator::FillProfileWithServerData(p.get(), | 357 AutofillModelAssociator::FillProfileWithServerData(p.get(), |
| 357 profile); | 358 profile); |
| 358 if (!web_database_->GetAutofillTable()->AddAutofillProfile(*p.get())) { | 359 if (!web_database_->GetAutofillTable()->AddAutofillProfile(*p.get())) { |
| 359 NOTREACHED() << "Couldn't add autofill profile: " << guid; | 360 NOTREACHED() << "Couldn't add autofill profile: " << guid; |
| 360 return; | 361 return; |
| 361 } | 362 } |
| 362 model_associator_->Associate(&guid, sync_id); | 363 model_associator_->Associate(&guid, sync_id); |
| 363 break; | 364 break; |
| 364 } | 365 } |
| 365 case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: { | 366 case sync_api::ChangeRecord::ACTION_UPDATE: { |
| 366 const std::string* guid = model_associator_->GetChromeNodeFromSyncId( | 367 const std::string* guid = model_associator_->GetChromeNodeFromSyncId( |
| 367 sync_id); | 368 sync_id); |
| 368 if (guid == NULL) { | 369 if (guid == NULL) { |
| 369 LOG(ERROR) << " Model association has not happened for " << sync_id; | 370 LOG(ERROR) << " Model association has not happened for " << sync_id; |
| 370 error_handler()->OnUnrecoverableError(FROM_HERE, | 371 error_handler()->OnUnrecoverableError(FROM_HERE, |
| 371 "model association has not happened"); | 372 "model association has not happened"); |
| 372 return; | 373 return; |
| 373 } | 374 } |
| 374 AutofillProfile *temp_ptr; | 375 AutofillProfile *temp_ptr; |
| 375 if (!web_database_->GetAutofillTable()->GetAutofillProfile( | 376 if (!web_database_->GetAutofillTable()->GetAutofillProfile( |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 autofill.set_value(UTF16ToUTF8(entry.key().value())); | 443 autofill.set_value(UTF16ToUTF8(entry.key().value())); |
| 443 const std::vector<base::Time>& ts(entry.timestamps()); | 444 const std::vector<base::Time>& ts(entry.timestamps()); |
| 444 for (std::vector<base::Time>::const_iterator timestamp = ts.begin(); | 445 for (std::vector<base::Time>::const_iterator timestamp = ts.begin(); |
| 445 timestamp != ts.end(); ++timestamp) { | 446 timestamp != ts.end(); ++timestamp) { |
| 446 autofill.add_usage_timestamp(timestamp->ToInternalValue()); | 447 autofill.add_usage_timestamp(timestamp->ToInternalValue()); |
| 447 } | 448 } |
| 448 node->SetAutofillSpecifics(autofill); | 449 node->SetAutofillSpecifics(autofill); |
| 449 } | 450 } |
| 450 | 451 |
| 451 } // namespace browser_sync | 452 } // namespace browser_sync |
| OLD | NEW |