| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/autofill/core/browser/personal_data_manager.h" | 5 #include "components/autofill/core/browser/personal_data_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> | 10 #include <list> |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 | 367 |
| 368 switch (result->GetType()) { | 368 switch (result->GetType()) { |
| 369 case AUTOFILL_PROFILES_RESULT: | 369 case AUTOFILL_PROFILES_RESULT: |
| 370 if (h == pending_profiles_query_) { | 370 if (h == pending_profiles_query_) { |
| 371 ReceiveLoadedDbValues(h, result.get(), &pending_profiles_query_, | 371 ReceiveLoadedDbValues(h, result.get(), &pending_profiles_query_, |
| 372 &web_profiles_); | 372 &web_profiles_); |
| 373 LogProfileCount(); // This only logs local profiles. | 373 LogProfileCount(); // This only logs local profiles. |
| 374 } else { | 374 } else { |
| 375 ReceiveLoadedDbValues(h, result.get(), &pending_server_profiles_query_, | 375 ReceiveLoadedDbValues(h, result.get(), &pending_server_profiles_query_, |
| 376 &server_profiles_); | 376 &server_profiles_); |
| 377 | |
| 378 if (!server_profiles_.empty()) { | |
| 379 std::string account_id = signin_manager_->GetAuthenticatedAccountId(); | |
| 380 base::string16 email = | |
| 381 base::UTF8ToUTF16( | |
| 382 account_tracker_->GetAccountInfo(account_id).email); | |
| 383 | |
| 384 // User may have signed out during the fulfillment of the web data | |
| 385 // request, in which case there is no point updating | |
| 386 // |server_profiles_| as it will be cleared. | |
| 387 if (!email.empty()) { | |
| 388 for (auto& profile : server_profiles_) | |
| 389 profile->SetRawInfo(EMAIL_ADDRESS, email); | |
| 390 } | |
| 391 } | |
| 392 } | 377 } |
| 393 break; | 378 break; |
| 394 case AUTOFILL_CREDITCARDS_RESULT: | 379 case AUTOFILL_CREDITCARDS_RESULT: |
| 395 if (h == pending_creditcards_query_) { | 380 if (h == pending_creditcards_query_) { |
| 396 ReceiveLoadedDbValues(h, result.get(), &pending_creditcards_query_, | 381 ReceiveLoadedDbValues(h, result.get(), &pending_creditcards_query_, |
| 397 &local_credit_cards_); | 382 &local_credit_cards_); |
| 398 LogLocalCreditCardCount(); | 383 LogLocalCreditCardCount(); |
| 399 } else { | 384 } else { |
| 400 ReceiveLoadedDbValues(h, result.get(), | 385 ReceiveLoadedDbValues(h, result.get(), |
| 401 &pending_server_creditcards_query_, | 386 &pending_server_creditcards_query_, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 417 if (pending_profiles_query_ == 0 && | 402 if (pending_profiles_query_ == 0 && |
| 418 pending_creditcards_query_ == 0 && | 403 pending_creditcards_query_ == 0 && |
| 419 pending_server_profiles_query_ == 0 && | 404 pending_server_profiles_query_ == 0 && |
| 420 pending_server_creditcards_query_ == 0) { | 405 pending_server_creditcards_query_ == 0) { |
| 421 is_data_loaded_ = true; | 406 is_data_loaded_ = true; |
| 422 NotifyPersonalDataChanged(); | 407 NotifyPersonalDataChanged(); |
| 423 } | 408 } |
| 424 } | 409 } |
| 425 | 410 |
| 426 void PersonalDataManager::AutofillMultipleChanged() { | 411 void PersonalDataManager::AutofillMultipleChanged() { |
| 412 has_synced_new_data_ = true; |
| 427 Refresh(); | 413 Refresh(); |
| 428 } | 414 } |
| 429 | 415 |
| 430 void PersonalDataManager::SyncStarted(syncer::ModelType model_type) { | 416 void PersonalDataManager::SyncStarted(syncer::ModelType model_type) { |
| 431 if (model_type == syncer::AUTOFILL_PROFILE && | 417 if (model_type == syncer::AUTOFILL_PROFILE && |
| 432 is_autofill_profile_cleanup_pending_) { | 418 is_autofill_profile_cleanup_pending_) { |
| 433 // This runs as a one-time fix, tracked in syncable prefs. If it has already | 419 // This runs as a one-time fix, tracked in syncable prefs. If it has already |
| 434 // run, it is a NOP (other than checking the pref). | 420 // run, it is a NOP (other than checking the pref). |
| 435 ApplyProfileUseDatesFix(); | 421 ApplyProfileUseDatesFix(); |
| 436 | 422 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 return GetProfiles(false); | 732 return GetProfiles(false); |
| 747 } | 733 } |
| 748 | 734 |
| 749 std::vector<AutofillProfile*> PersonalDataManager::web_profiles() const { | 735 std::vector<AutofillProfile*> PersonalDataManager::web_profiles() const { |
| 750 std::vector<AutofillProfile*> result; | 736 std::vector<AutofillProfile*> result; |
| 751 for (const auto& profile : web_profiles_) | 737 for (const auto& profile : web_profiles_) |
| 752 result.push_back(profile.get()); | 738 result.push_back(profile.get()); |
| 753 return result; | 739 return result; |
| 754 } | 740 } |
| 755 | 741 |
| 742 std::vector<AutofillProfile*> PersonalDataManager::GetServerProfiles() const { |
| 743 std::vector<AutofillProfile*> result; |
| 744 for (const auto& profile : server_profiles_) |
| 745 result.push_back(profile.get()); |
| 746 return result; |
| 747 } |
| 748 |
| 756 std::vector<CreditCard*> PersonalDataManager::GetLocalCreditCards() const { | 749 std::vector<CreditCard*> PersonalDataManager::GetLocalCreditCards() const { |
| 757 std::vector<CreditCard*> result; | 750 std::vector<CreditCard*> result; |
| 758 for (const auto& card : local_credit_cards_) | 751 for (const auto& card : local_credit_cards_) |
| 759 result.push_back(card.get()); | 752 result.push_back(card.get()); |
| 760 return result; | 753 return result; |
| 761 } | 754 } |
| 762 | 755 |
| 763 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { | 756 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { |
| 764 credit_cards_.clear(); | 757 credit_cards_.clear(); |
| 765 for (const auto& card : local_credit_cards_) | 758 for (const auto& card : local_credit_cards_) |
| 766 credit_cards_.push_back(card.get()); | 759 credit_cards_.push_back(card.get()); |
| 767 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 760 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
| 768 for (const auto& card : server_credit_cards_) | 761 for (const auto& card : server_credit_cards_) |
| 769 credit_cards_.push_back(card.get()); | 762 credit_cards_.push_back(card.get()); |
| 770 } | 763 } |
| 771 return credit_cards_; | 764 return credit_cards_; |
| 772 } | 765 } |
| 773 | 766 |
| 774 bool PersonalDataManager::HasServerData() const { | |
| 775 return !server_credit_cards_.empty() || !server_profiles_.empty(); | |
| 776 } | |
| 777 | |
| 778 void PersonalDataManager::Refresh() { | 767 void PersonalDataManager::Refresh() { |
| 779 LoadProfiles(); | 768 LoadProfiles(); |
| 780 LoadCreditCards(); | 769 LoadCreditCards(); |
| 781 } | 770 } |
| 782 | 771 |
| 783 const std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest() | 772 const std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest() |
| 784 const { | 773 const { |
| 785 std::vector<AutofillProfile*> profiles = GetProfiles(true); | 774 std::vector<AutofillProfile*> profiles = GetProfiles(true); |
| 786 | 775 |
| 787 // Rank the suggestions by frecency (see AutofillDataModel for details). | 776 // Rank the suggestions by frecency (see AutofillDataModel for details). |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 database_->CancelRequest(*handle); | 1222 database_->CancelRequest(*handle); |
| 1234 } | 1223 } |
| 1235 *handle = 0; | 1224 *handle = 0; |
| 1236 } | 1225 } |
| 1237 | 1226 |
| 1238 std::string PersonalDataManager::SaveImportedProfile( | 1227 std::string PersonalDataManager::SaveImportedProfile( |
| 1239 const AutofillProfile& imported_profile) { | 1228 const AutofillProfile& imported_profile) { |
| 1240 if (is_off_the_record_) | 1229 if (is_off_the_record_) |
| 1241 return std::string(); | 1230 return std::string(); |
| 1242 | 1231 |
| 1243 // Don't save a web profile if the data in the profile is a subset of a | |
| 1244 // server profile, but do record the fact that it was used. | |
| 1245 for (const auto& profile : server_profiles_) { | |
| 1246 if (imported_profile.IsSubsetOf(*profile, app_locale_)) { | |
| 1247 RecordUseOf(*profile); | |
| 1248 return profile->guid(); | |
| 1249 } | |
| 1250 } | |
| 1251 | |
| 1252 std::vector<AutofillProfile> profiles; | 1232 std::vector<AutofillProfile> profiles; |
| 1253 std::string guid = | 1233 std::string guid = |
| 1254 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles); | 1234 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles); |
| 1255 SetProfiles(&profiles); | 1235 SetProfiles(&profiles); |
| 1256 return guid; | 1236 return guid; |
| 1257 } | 1237 } |
| 1258 | 1238 |
| 1259 void PersonalDataManager::NotifyPersonalDataChanged() { | 1239 void PersonalDataManager::NotifyPersonalDataChanged() { |
| 1260 for (PersonalDataManagerObserver& observer : observers_) | 1240 for (PersonalDataManagerObserver& observer : observers_) |
| 1261 observer.OnPersonalDataChanged(); | 1241 observer.OnPersonalDataChanged(); |
| 1242 |
| 1243 // If new data was synced, try to convert new server profiles. |
| 1244 if (has_synced_new_data_) { |
| 1245 has_synced_new_data_ = false; |
| 1246 ConvertWalletAddressesToLocalProfiles(); |
| 1247 } |
| 1262 } | 1248 } |
| 1263 | 1249 |
| 1264 std::string PersonalDataManager::SaveImportedCreditCard( | 1250 std::string PersonalDataManager::SaveImportedCreditCard( |
| 1265 const CreditCard& imported_card) { | 1251 const CreditCard& imported_card) { |
| 1266 DCHECK(!imported_card.number().empty()); | 1252 DCHECK(!imported_card.number().empty()); |
| 1267 if (is_off_the_record_) | 1253 if (is_off_the_record_) |
| 1268 return std::string(); | 1254 return std::string(); |
| 1269 | 1255 |
| 1270 // Set to true if |imported_card| is merged into the credit card list. | 1256 // Set to true if |imported_card| is merged into the credit card list. |
| 1271 bool merged = false; | 1257 bool merged = false; |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 | 1555 |
| 1570 imported_credit_card->reset(new CreditCard(candidate_credit_card)); | 1556 imported_credit_card->reset(new CreditCard(candidate_credit_card)); |
| 1571 return true; | 1557 return true; |
| 1572 } | 1558 } |
| 1573 | 1559 |
| 1574 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles( | 1560 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles( |
| 1575 bool record_metrics) const { | 1561 bool record_metrics) const { |
| 1576 profiles_.clear(); | 1562 profiles_.clear(); |
| 1577 for (const auto& profile : web_profiles_) | 1563 for (const auto& profile : web_profiles_) |
| 1578 profiles_.push_back(profile.get()); | 1564 profiles_.push_back(profile.get()); |
| 1579 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | |
| 1580 for (const auto& profile : server_profiles_) | |
| 1581 profiles_.push_back(profile.get()); | |
| 1582 } | |
| 1583 return profiles_; | 1565 return profiles_; |
| 1584 } | 1566 } |
| 1585 | 1567 |
| 1586 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( | 1568 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( |
| 1587 const AutofillType& type, | 1569 const AutofillType& type, |
| 1588 const base::string16& field_contents, | 1570 const base::string16& field_contents, |
| 1589 const std::vector<CreditCard*>& cards_to_suggest) const { | 1571 const std::vector<CreditCard*>& cards_to_suggest) const { |
| 1590 std::vector<Suggestion> suggestions; | 1572 std::vector<Suggestion> suggestions; |
| 1591 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); | 1573 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); |
| 1592 for (const CreditCard* credit_card : cards_to_suggest) { | 1574 for (const CreditCard* credit_card : cards_to_suggest) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1850 // If the card was modified, apply the changes to the database. | 1832 // If the card was modified, apply the changes to the database. |
| 1851 if (was_modified) { | 1833 if (was_modified) { |
| 1852 if (credit_card->record_type() == CreditCard::LOCAL_CARD) | 1834 if (credit_card->record_type() == CreditCard::LOCAL_CARD) |
| 1853 database_->UpdateCreditCard(*credit_card); | 1835 database_->UpdateCreditCard(*credit_card); |
| 1854 else | 1836 else |
| 1855 database_->UpdateServerCardMetadata(*credit_card); | 1837 database_->UpdateServerCardMetadata(*credit_card); |
| 1856 } | 1838 } |
| 1857 } | 1839 } |
| 1858 } | 1840 } |
| 1859 | 1841 |
| 1842 void PersonalDataManager::ConvertWalletAddressesToLocalProfiles() { |
| 1843 // Copy the local profiles into a vector<AutofillProfile>. Theses are the |
| 1844 // existing profiles. Get them sorted in decreasing order of frecency, so the |
| 1845 // "best" profiles are checked first. Put the verified profiles last so the |
| 1846 // server addresses have a chance to merge into the non-verified local |
| 1847 // profiles. |
| 1848 std::vector<AutofillProfile> local_profiles; |
| 1849 for (AutofillProfile* existing_profile : GetProfilesToSuggest()) { |
| 1850 local_profiles.push_back(*existing_profile); |
| 1851 } |
| 1852 |
| 1853 // Create the map used to update credit card's billing addresses after the |
| 1854 // convertion/merge. |
| 1855 std::unordered_map<std::string, std::string> guids_merge_map; |
| 1856 |
| 1857 bool has_converted_addresses = false; |
| 1858 for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) { |
| 1859 // If the address has not been converted yet, convert it. |
| 1860 if (!wallet_address->has_converted()) { |
| 1861 // Try to merge the server address into a similar local profile, or create |
| 1862 // a new local profile if no similar profile is found. |
| 1863 std::string address_guid = |
| 1864 MergeServerAddressesIntoProfiles(*wallet_address, &local_profiles); |
| 1865 |
| 1866 // Update the map to transfer the billing address relationship from the |
| 1867 // server address to the converted/merged local profile. |
| 1868 guids_merge_map.insert(std::pair<std::string, std::string>( |
| 1869 wallet_address->server_id(), address_guid)); |
| 1870 |
| 1871 // Update the wallet addresses metadata to record the conversion. |
| 1872 wallet_address->set_has_converted(true); |
| 1873 database_->UpdateServerAddressMetadata(*wallet_address); |
| 1874 |
| 1875 has_converted_addresses = true; |
| 1876 } |
| 1877 } |
| 1878 |
| 1879 if (has_converted_addresses) { |
| 1880 // Save the local profiles to the DB. |
| 1881 SetProfiles(&local_profiles); |
| 1882 |
| 1883 // Update the credit cards billing address relationship. |
| 1884 UpdateCardsBillingAddressReference(guids_merge_map); |
| 1885 |
| 1886 // Force a reload of the profiles and cards. |
| 1887 Refresh(); |
| 1888 } |
| 1889 } |
| 1890 |
| 1891 // TODO(crbug.com/687975): Reuse MergeProfiles in this function. |
| 1892 std::string PersonalDataManager::MergeServerAddressesIntoProfiles( |
| 1893 const AutofillProfile& server_address, |
| 1894 std::vector<AutofillProfile>* existing_profiles) { |
| 1895 // Set to true if |existing_profiles| already contains an equivalent profile. |
| 1896 bool matching_profile_found = false; |
| 1897 std::string guid = server_address.guid(); |
| 1898 |
| 1899 // If there is already a local profile that is very similar, merge in any |
| 1900 // missing values. Only merge with the first match. |
| 1901 AutofillProfileComparator comparator(app_locale_); |
| 1902 for (auto& local_profile : *existing_profiles) { |
| 1903 if (!matching_profile_found && |
| 1904 comparator.AreMergeable(server_address, local_profile) && |
| 1905 local_profile.SaveAdditionalInfo(server_address, app_locale_)) { |
| 1906 matching_profile_found = true; |
| 1907 local_profile.set_modification_date(AutofillClock::Now()); |
| 1908 guid = local_profile.guid(); |
| 1909 AutofillMetrics::LogWalletAddressConversionType( |
| 1910 AutofillMetrics::CONVERTED_ADDRESS_MERGED); |
| 1911 } |
| 1912 } |
| 1913 |
| 1914 // If the server address was not merged with a local profile, add it to the |
| 1915 // list. |
| 1916 if (!matching_profile_found) { |
| 1917 existing_profiles->push_back(server_address); |
| 1918 // Set the profile as being local. |
| 1919 existing_profiles->back().set_record_type(AutofillProfile::LOCAL_PROFILE); |
| 1920 existing_profiles->back().set_modification_date(AutofillClock::Now()); |
| 1921 AutofillMetrics::LogWalletAddressConversionType( |
| 1922 AutofillMetrics::CONVERTED_ADDRESS_ADDED); |
| 1923 } |
| 1924 |
| 1925 return guid; |
| 1926 } |
| 1927 |
| 1860 } // namespace autofill | 1928 } // namespace autofill |
| OLD | NEW |