| 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/webdata/autofill_profile_syncable_service.h" | 5 #include "chrome/browser/webdata/autofill_profile_syncable_service.h" |
| 6 | 6 |
| 7 #include "base/guid.h" | 7 #include "base/guid.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 } | 312 } |
| 313 return success; | 313 return success; |
| 314 } | 314 } |
| 315 | 315 |
| 316 // static | 316 // static |
| 317 bool AutofillProfileSyncableService::OverwriteProfileWithServerData( | 317 bool AutofillProfileSyncableService::OverwriteProfileWithServerData( |
| 318 const sync_pb::AutofillProfileSpecifics& specifics, | 318 const sync_pb::AutofillProfileSpecifics& specifics, |
| 319 AutofillProfile* profile, | 319 AutofillProfile* profile, |
| 320 const std::string& app_locale) { | 320 const std::string& app_locale) { |
| 321 bool diff = false; | 321 bool diff = false; |
| 322 if (profile->origin() != specifics.origin()) { |
| 323 bool was_verified = profile->IsVerified(); |
| 324 profile->set_origin(specifics.origin()); |
| 325 diff = true; |
| 326 |
| 327 // Verified profiles should never be overwritten by unverified ones. |
| 328 DCHECK(!was_verified || profile->IsVerified()); |
| 329 } |
| 330 |
| 322 diff = UpdateMultivaluedField(autofill::NAME_FIRST, | 331 diff = UpdateMultivaluedField(autofill::NAME_FIRST, |
| 323 specifics.name_first(), profile) || diff; | 332 specifics.name_first(), profile) || diff; |
| 324 diff = UpdateMultivaluedField(autofill::NAME_MIDDLE, | 333 diff = UpdateMultivaluedField(autofill::NAME_MIDDLE, |
| 325 specifics.name_middle(), profile) || diff; | 334 specifics.name_middle(), profile) || diff; |
| 326 diff = UpdateMultivaluedField(autofill::NAME_LAST, | 335 diff = UpdateMultivaluedField(autofill::NAME_LAST, |
| 327 specifics.name_last(), profile) || diff; | 336 specifics.name_last(), profile) || diff; |
| 328 diff = UpdateField(autofill::ADDRESS_HOME_LINE1, | 337 diff = UpdateField(autofill::ADDRESS_HOME_LINE1, |
| 329 specifics.address_home_line1(), profile) || diff; | 338 specifics.address_home_line1(), profile) || diff; |
| 330 diff = UpdateField(autofill::ADDRESS_HOME_LINE2, | 339 diff = UpdateField(autofill::ADDRESS_HOME_LINE2, |
| 331 specifics.address_home_line2(), profile) || diff; | 340 specifics.address_home_line2(), profile) || diff; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 361 DCHECK(base::IsValidGUID(profile.guid())); | 370 DCHECK(base::IsValidGUID(profile.guid())); |
| 362 | 371 |
| 363 // Reset all multi-valued fields in the protobuf. | 372 // Reset all multi-valued fields in the protobuf. |
| 364 specifics->clear_name_first(); | 373 specifics->clear_name_first(); |
| 365 specifics->clear_name_middle(); | 374 specifics->clear_name_middle(); |
| 366 specifics->clear_name_last(); | 375 specifics->clear_name_last(); |
| 367 specifics->clear_email_address(); | 376 specifics->clear_email_address(); |
| 368 specifics->clear_phone_home_whole_number(); | 377 specifics->clear_phone_home_whole_number(); |
| 369 | 378 |
| 370 specifics->set_guid(profile.guid()); | 379 specifics->set_guid(profile.guid()); |
| 380 specifics->set_origin(profile.origin()); |
| 381 |
| 371 std::vector<string16> values; | 382 std::vector<string16> values; |
| 372 profile.GetRawMultiInfo(autofill::NAME_FIRST, &values); | 383 profile.GetRawMultiInfo(autofill::NAME_FIRST, &values); |
| 373 for (size_t i = 0; i < values.size(); ++i) { | 384 for (size_t i = 0; i < values.size(); ++i) { |
| 374 specifics->add_name_first(LimitData(UTF16ToUTF8(values[i]))); | 385 specifics->add_name_first(LimitData(UTF16ToUTF8(values[i]))); |
| 375 } | 386 } |
| 376 | 387 |
| 377 profile.GetRawMultiInfo(autofill::NAME_MIDDLE, &values); | 388 profile.GetRawMultiInfo(autofill::NAME_MIDDLE, &values); |
| 378 for (size_t i = 0; i < values.size(); ++i) { | 389 for (size_t i = 0; i < values.size(); ++i) { |
| 379 specifics->add_name_middle(LimitData(UTF16ToUTF8(values[i]))); | 390 specifics->add_name_middle(LimitData(UTF16ToUTF8(values[i]))); |
| 380 } | 391 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 DataBundle* bundle) { | 439 DataBundle* bundle) { |
| 429 DCHECK(profile_map); | 440 DCHECK(profile_map); |
| 430 DCHECK(bundle); | 441 DCHECK(bundle); |
| 431 | 442 |
| 432 DCHECK_EQ(syncer::AUTOFILL_PROFILE, data.GetDataType()); | 443 DCHECK_EQ(syncer::AUTOFILL_PROFILE, data.GetDataType()); |
| 433 | 444 |
| 434 const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); | 445 const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); |
| 435 const sync_pb::AutofillProfileSpecifics& autofill_specifics( | 446 const sync_pb::AutofillProfileSpecifics& autofill_specifics( |
| 436 specifics.autofill_profile()); | 447 specifics.autofill_profile()); |
| 437 | 448 |
| 438 GUIDToProfileMap::iterator it = profile_map->find( | 449 GUIDToProfileMap::iterator existing_profile = profile_map->find( |
| 439 autofill_specifics.guid()); | 450 autofill_specifics.guid()); |
| 440 if (it != profile_map->end()) { | 451 if (existing_profile != profile_map->end()) { |
| 441 // Some profile that already present is synced. | 452 // The synced profile already exists locally. It might need to be updated. |
| 442 if (OverwriteProfileWithServerData( | 453 if (OverwriteProfileWithServerData( |
| 443 autofill_specifics, it->second, app_locale_)) { | 454 autofill_specifics, existing_profile->second, app_locale_)) { |
| 444 bundle->profiles_to_update.push_back(it->second); | 455 bundle->profiles_to_update.push_back(existing_profile->second); |
| 445 } | 456 } |
| 446 } else { | 457 return existing_profile; |
| 447 // New profile synced. | 458 } |
| 448 // TODO(isherman): Read the origin from |autofill_specifics|. | |
| 449 AutofillProfile* new_profile( | |
| 450 new AutofillProfile(autofill_specifics.guid(), std::string())); | |
| 451 OverwriteProfileWithServerData( | |
| 452 autofill_specifics, new_profile, app_locale_); | |
| 453 | 459 |
| 454 // Check if profile appears under a different guid. | 460 |
| 455 for (GUIDToProfileMap::iterator i = profile_map->begin(); | 461 // New profile synced. |
| 456 i != profile_map->end(); ++i) { | 462 AutofillProfile* new_profile = new AutofillProfile( |
| 457 if (i->second->Compare(*new_profile) == 0) { | 463 autofill_specifics.guid(), autofill_specifics.origin()); |
| 458 bundle->profiles_to_delete.push_back(i->second->guid()); | 464 OverwriteProfileWithServerData(autofill_specifics, new_profile, app_locale_); |
| 459 DVLOG(2) << "[AUTOFILL SYNC]" | 465 |
| 460 << "Found in sync db but with a different guid: " | 466 // Check if profile appears under a different guid. |
| 461 << UTF16ToUTF8(i->second->GetRawInfo(autofill::NAME_FIRST)) | 467 // Unverified profiles should never overwrite verified ones. |
| 462 << UTF16ToUTF8(i->second->GetRawInfo(autofill::NAME_LAST)) | 468 for (GUIDToProfileMap::iterator it = profile_map->begin(); |
| 463 << "New guid " << new_profile->guid() | 469 it != profile_map->end(); ++it) { |
| 464 << ". Profile to be deleted " << i->second->guid(); | 470 AutofillProfile* local_profile = it->second; |
| 465 profile_map->erase(i); | 471 if (local_profile->Compare(*new_profile) == 0) { |
| 466 break; | 472 // Ensure that a verified profile can never revert back to an unverified |
| 467 } else if (!i->second->PrimaryValue().empty() && | 473 // one. |
| 468 i->second->PrimaryValue() == new_profile->PrimaryValue()) { | 474 if (local_profile->IsVerified() && !new_profile->IsVerified()) { |
| 469 // Add it to candidates for merge - if there is no profile with this | 475 new_profile->set_origin(local_profile->origin()); |
| 470 // guid we will merge them. | 476 bundle->profiles_to_sync_back.push_back(new_profile); |
| 471 bundle->candidates_to_merge.insert(std::make_pair(i->second->guid(), | |
| 472 new_profile)); | |
| 473 } | 477 } |
| 478 |
| 479 bundle->profiles_to_delete.push_back(local_profile->guid()); |
| 480 DVLOG(2) << "[AUTOFILL SYNC]" |
| 481 << "Found in sync db but with a different guid: " |
| 482 << UTF16ToUTF8(local_profile->GetRawInfo(autofill::NAME_FIRST)) |
| 483 << UTF16ToUTF8(local_profile->GetRawInfo(autofill::NAME_LAST)) |
| 484 << "New guid " << new_profile->guid() |
| 485 << ". Profile to be deleted " << local_profile->guid(); |
| 486 profile_map->erase(it); |
| 487 break; |
| 488 } else if (!local_profile->IsVerified() && |
| 489 !new_profile->IsVerified() && |
| 490 !local_profile->PrimaryValue().empty() && |
| 491 local_profile->PrimaryValue() == new_profile->PrimaryValue()) { |
| 492 // Add it to candidates for merge - if there is no profile with this |
| 493 // guid we will merge them. |
| 494 bundle->candidates_to_merge.insert( |
| 495 std::make_pair(local_profile->guid(), new_profile)); |
| 474 } | 496 } |
| 475 profiles_.push_back(new_profile); | 497 } |
| 476 it = profile_map->insert(std::make_pair(new_profile->guid(), | 498 profiles_.push_back(new_profile); |
| 499 bundle->profiles_to_add.push_back(new_profile); |
| 500 return profile_map->insert(std::make_pair(new_profile->guid(), |
| 477 new_profile)).first; | 501 new_profile)).first; |
| 478 bundle->profiles_to_add.push_back(new_profile); | |
| 479 } | |
| 480 return it; | |
| 481 } | 502 } |
| 482 | 503 |
| 483 void AutofillProfileSyncableService::ActOnChange( | 504 void AutofillProfileSyncableService::ActOnChange( |
| 484 const AutofillProfileChange& change) { | 505 const AutofillProfileChange& change) { |
| 485 DCHECK((change.type() == AutofillProfileChange::REMOVE && | 506 DCHECK((change.type() == AutofillProfileChange::REMOVE && |
| 486 !change.profile()) || | 507 !change.profile()) || |
| 487 (change.type() != AutofillProfileChange::REMOVE && change.profile())); | 508 (change.type() != AutofillProfileChange::REMOVE && change.profile())); |
| 488 DCHECK(sync_processor_.get()); | 509 DCHECK(sync_processor_.get()); |
| 489 syncer::SyncChangeList new_changes; | 510 syncer::SyncChangeList new_changes; |
| 490 DataBundle bundle; | 511 DataBundle bundle; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 if (changed) | 596 if (changed) |
| 576 autofill_profile->SetRawMultiInfo(field_type, values); | 597 autofill_profile->SetRawMultiInfo(field_type, values); |
| 577 return changed; | 598 return changed; |
| 578 } | 599 } |
| 579 | 600 |
| 580 bool AutofillProfileSyncableService::MergeProfile( | 601 bool AutofillProfileSyncableService::MergeProfile( |
| 581 const AutofillProfile& merge_from, | 602 const AutofillProfile& merge_from, |
| 582 AutofillProfile* merge_into, | 603 AutofillProfile* merge_into, |
| 583 const std::string& app_locale) { | 604 const std::string& app_locale) { |
| 584 merge_into->OverwriteWithOrAddTo(merge_from, app_locale); | 605 merge_into->OverwriteWithOrAddTo(merge_from, app_locale); |
| 585 return (merge_into->Compare(merge_from) != 0); | 606 return (merge_into->Compare(merge_from) != 0 || |
| 607 merge_into->origin() != merge_from.origin()); |
| 586 } | 608 } |
| 587 | 609 |
| 588 AutofillTable* AutofillProfileSyncableService::GetAutofillTable() const { | 610 AutofillTable* AutofillProfileSyncableService::GetAutofillTable() const { |
| 589 return AutofillTable::FromWebDatabase(webdata_backend_->GetDatabase()); | 611 return AutofillTable::FromWebDatabase(webdata_backend_->GetDatabase()); |
| 590 } | 612 } |
| 591 | 613 |
| 592 void AutofillProfileSyncableService::InjectStartSyncFlare( | 614 void AutofillProfileSyncableService::InjectStartSyncFlare( |
| 593 const syncer::SyncableService::StartSyncFlare& flare) { | 615 const syncer::SyncableService::StartSyncFlare& flare) { |
| 594 flare_ = flare; | 616 flare_ = flare; |
| 595 } | 617 } |
| 596 | 618 |
| 597 AutofillProfileSyncableService::DataBundle::DataBundle() {} | 619 AutofillProfileSyncableService::DataBundle::DataBundle() {} |
| 598 | 620 |
| 599 AutofillProfileSyncableService::DataBundle::~DataBundle() {} | 621 AutofillProfileSyncableService::DataBundle::~DataBundle() {} |
| OLD | NEW |