| 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> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "base/i18n/case_conversion.h" | 15 #include "base/i18n/case_conversion.h" |
| 16 #include "base/i18n/timezone.h" | 16 #include "base/i18n/timezone.h" |
| 17 #include "base/memory/ptr_util.h" |
| 17 #include "base/profiler/scoped_tracker.h" | 18 #include "base/profiler/scoped_tracker.h" |
| 18 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 21 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 22 #include "components/autofill/core/browser/address_i18n.h" | 23 #include "components/autofill/core/browser/address_i18n.h" |
| 23 #include "components/autofill/core/browser/autofill-inl.h" | 24 #include "components/autofill/core/browser/autofill-inl.h" |
| 24 #include "components/autofill/core/browser/autofill_country.h" | 25 #include "components/autofill/core/browser/autofill_country.h" |
| 25 #include "components/autofill/core/browser/autofill_experiments.h" | 26 #include "components/autofill/core/browser/autofill_experiments.h" |
| 26 #include "components/autofill/core/browser/autofill_field.h" | 27 #include "components/autofill/core/browser/autofill_field.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 } | 62 } |
| 62 | 63 |
| 63 bool operator()(const T& form_group) { | 64 bool operator()(const T& form_group) { |
| 64 return form_group.guid() == guid_; | 65 return form_group.guid() == guid_; |
| 65 } | 66 } |
| 66 | 67 |
| 67 bool operator()(const T* form_group) { | 68 bool operator()(const T* form_group) { |
| 68 return form_group->guid() == guid_; | 69 return form_group->guid() == guid_; |
| 69 } | 70 } |
| 70 | 71 |
| 72 bool operator()(const std::unique_ptr<T>& form_group) { |
| 73 return form_group->guid() == guid_; |
| 74 } |
| 75 |
| 71 private: | 76 private: |
| 72 const std::string guid_; | 77 const std::string guid_; |
| 73 }; | 78 }; |
| 74 | 79 |
| 75 template<typename T, typename C> | 80 template<typename T, typename C> |
| 76 typename C::const_iterator FindElementByGUID(const C& container, | 81 typename C::const_iterator FindElementByGUID(const C& container, |
| 77 const std::string& guid) { | 82 const std::string& guid) { |
| 78 return std::find_if(container.begin(), | 83 return std::find_if(container.begin(), |
| 79 container.end(), | 84 container.end(), |
| 80 FormGroupMatchesByGUIDFunctor<T>(guid)); | 85 FormGroupMatchesByGUIDFunctor<T>(guid)); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 178 |
| 174 return profile->GetInfo(type, app_locale); | 179 return profile->GetInfo(type, app_locale); |
| 175 } | 180 } |
| 176 | 181 |
| 177 // Receives the loaded profiles from the web data service and stores them in | 182 // Receives the loaded profiles from the web data service and stores them in |
| 178 // |*dest|. The pending handle is the address of the pending handle | 183 // |*dest|. The pending handle is the address of the pending handle |
| 179 // corresponding to this request type. This function is used to save both | 184 // corresponding to this request type. This function is used to save both |
| 180 // server and local profiles and credit cards. | 185 // server and local profiles and credit cards. |
| 181 template <typename ValueType> | 186 template <typename ValueType> |
| 182 void ReceiveLoadedDbValues(WebDataServiceBase::Handle h, | 187 void ReceiveLoadedDbValues(WebDataServiceBase::Handle h, |
| 183 const WDTypedResult* result, | 188 WDTypedResult* result, |
| 184 WebDataServiceBase::Handle* pending_handle, | 189 WebDataServiceBase::Handle* pending_handle, |
| 185 ScopedVector<ValueType>* dest) { | 190 std::vector<std::unique_ptr<ValueType>>* dest) { |
| 186 DCHECK_EQ(*pending_handle, h); | 191 DCHECK_EQ(*pending_handle, h); |
| 187 *pending_handle = 0; | 192 *pending_handle = 0; |
| 188 | 193 |
| 189 const WDResult<std::vector<ValueType*>>* r = | 194 *dest = std::move( |
| 190 static_cast<const WDResult<std::vector<ValueType*>>*>(result); | 195 static_cast<WDResult<std::vector<std::unique_ptr<ValueType>>>*>(result) |
| 191 | 196 ->GetValue()); |
| 192 dest->clear(); | |
| 193 for (ValueType* value : r->GetValue()) | |
| 194 dest->push_back(value); | |
| 195 } | 197 } |
| 196 | 198 |
| 197 // A helper function for finding the maximum value in a string->int map. | 199 // A helper function for finding the maximum value in a string->int map. |
| 198 static bool CompareVotes(const std::pair<std::string, int>& a, | 200 static bool CompareVotes(const std::pair<std::string, int>& a, |
| 199 const std::pair<std::string, int>& b) { | 201 const std::pair<std::string, int>& b) { |
| 200 return a.second < b.second; | 202 return a.second < b.second; |
| 201 } | 203 } |
| 202 | 204 |
| 203 // Returns whether the |suggestion| is valid considering the | 205 // Returns whether the |suggestion| is valid considering the |
| 204 // |field_contents_canon|, the |type| and |is_masked_server_card|. Assigns true | 206 // |field_contents_canon|, the |type| and |is_masked_server_card|. Assigns true |
| 205 // to |is_prefix_matched| if the |field_contents_canon| is a prefix to | 207 // to |is_prefix_matched| if the |field_contents_canon| is a prefix to |
| 206 // |suggestion|, assigns false otherwise. | 208 // |suggestion|, assigns false otherwise. |
| 207 bool IsValidSuggestionForFieldContents(base::string16 suggestion_canon, | 209 bool IsValidSuggestionForFieldContents(base::string16 suggestion_canon, |
| 208 base::string16 field_contents_canon, | 210 base::string16 field_contents_canon, |
| 209 const AutofillType& type, | 211 const AutofillType& type, |
| 210 bool is_masked_server_card, | 212 bool is_masked_server_card, |
| 211 bool* is_prefix_matched) { | 213 bool* is_prefix_matched) { |
| 212 *is_prefix_matched = true; | 214 *is_prefix_matched = true; |
| 213 | 215 |
| 214 // Phones should do a substring match because they can be trimmed to remove | 216 // Phones should do a substring match because they can be trimmed to remove |
| 215 // the first parts (e.g. country code or prefix). It is still considered a | 217 // the first parts (e.g. country code or prefix). It is still considered a |
| 216 // prefix match in order to put it at the top of the suggestions. | 218 // prefix match in order to put it at the top of the suggestions. |
| 217 if ((type.group() == PHONE_HOME || type.group() == PHONE_BILLING) && | 219 if ((type.group() == PHONE_HOME || type.group() == PHONE_BILLING) && |
| 218 suggestion_canon.find(field_contents_canon) != base::string16::npos) { | 220 suggestion_canon.find(field_contents_canon) != base::string16::npos) { |
| 219 return true; | 221 return true; |
| 220 } | 222 } |
| 221 | 223 |
| 222 // For card number fields, suggest the card if: | 224 // For card number fields, suggest the card if: |
| 223 // - the number matches any part of the card, or | 225 // - the number matches any part of the card, or |
| 224 // - it's a masked card and there are 6 or fewers typed so far. | 226 // - it's a masked card and there are 6 or fewer typed so far. |
| 225 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { | 227 if (type.GetStorableType() == CREDIT_CARD_NUMBER) { |
| 226 if (suggestion_canon.find(field_contents_canon) == base::string16::npos && | 228 if (suggestion_canon.find(field_contents_canon) == base::string16::npos && |
| 227 (!is_masked_server_card || field_contents_canon.size() >= 6)) { | 229 (!is_masked_server_card || field_contents_canon.size() >= 6)) { |
| 228 return false; | 230 return false; |
| 229 } | 231 } |
| 230 return true; | 232 return true; |
| 231 } | 233 } |
| 232 | 234 |
| 233 if (base::StartsWith(suggestion_canon, field_contents_canon, | 235 if (base::StartsWith(suggestion_canon, field_contents_canon, |
| 234 base::CompareCase::SENSITIVE)) { | 236 base::CompareCase::SENSITIVE)) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 // run, it is a NOP (other than checking the pref). | 326 // run, it is a NOP (other than checking the pref). |
| 325 ApplyProfileUseDatesFix(); | 327 ApplyProfileUseDatesFix(); |
| 326 | 328 |
| 327 // This runs at most once per major version, tracked in syncable prefs. If it | 329 // This runs at most once per major version, tracked in syncable prefs. If it |
| 328 // has already run for this version, it's a NOP, other than checking the pref. | 330 // has already run for this version, it's a NOP, other than checking the pref. |
| 329 ApplyDedupingRoutine(); | 331 ApplyDedupingRoutine(); |
| 330 } | 332 } |
| 331 | 333 |
| 332 void PersonalDataManager::OnWebDataServiceRequestDone( | 334 void PersonalDataManager::OnWebDataServiceRequestDone( |
| 333 WebDataServiceBase::Handle h, | 335 WebDataServiceBase::Handle h, |
| 334 const WDTypedResult* result) { | 336 std::unique_ptr<WDTypedResult> result) { |
| 335 DCHECK(pending_profiles_query_ || pending_server_profiles_query_ || | 337 DCHECK(pending_profiles_query_ || pending_server_profiles_query_ || |
| 336 pending_creditcards_query_ || pending_server_creditcards_query_); | 338 pending_creditcards_query_ || pending_server_creditcards_query_); |
| 337 | 339 |
| 338 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is | 340 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is |
| 339 // fixed. | 341 // fixed. |
| 340 tracked_objects::ScopedTracker tracking_profile( | 342 tracked_objects::ScopedTracker tracking_profile( |
| 341 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 343 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 342 "422460 PersonalDataManager::OnWebDataServiceRequestDone")); | 344 "422460 PersonalDataManager::OnWebDataServiceRequestDone")); |
| 343 | 345 |
| 344 if (!result) { | 346 if (!result) { |
| 345 // Error from the web database. | 347 // Error from the web database. |
| 346 if (h == pending_creditcards_query_) | 348 if (h == pending_creditcards_query_) |
| 347 pending_creditcards_query_ = 0; | 349 pending_creditcards_query_ = 0; |
| 348 else if (h == pending_profiles_query_) | 350 else if (h == pending_profiles_query_) |
| 349 pending_profiles_query_ = 0; | 351 pending_profiles_query_ = 0; |
| 350 return; | 352 return; |
| 351 } | 353 } |
| 352 | 354 |
| 353 switch (result->GetType()) { | 355 switch (result->GetType()) { |
| 354 case AUTOFILL_PROFILES_RESULT: | 356 case AUTOFILL_PROFILES_RESULT: |
| 355 if (h == pending_profiles_query_) { | 357 if (h == pending_profiles_query_) { |
| 356 ReceiveLoadedDbValues(h, result, &pending_profiles_query_, | 358 ReceiveLoadedDbValues(h, result.get(), &pending_profiles_query_, |
| 357 &web_profiles_); | 359 &web_profiles_); |
| 358 LogProfileCount(); // This only logs local profiles. | 360 LogProfileCount(); // This only logs local profiles. |
| 359 } else { | 361 } else { |
| 360 ReceiveLoadedDbValues(h, result, &pending_server_profiles_query_, | 362 ReceiveLoadedDbValues(h, result.get(), &pending_server_profiles_query_, |
| 361 &server_profiles_); | 363 &server_profiles_); |
| 362 | 364 |
| 363 if (!server_profiles_.empty()) { | 365 if (!server_profiles_.empty()) { |
| 364 std::string account_id = signin_manager_->GetAuthenticatedAccountId(); | 366 std::string account_id = signin_manager_->GetAuthenticatedAccountId(); |
| 365 base::string16 email = | 367 base::string16 email = |
| 366 base::UTF8ToUTF16( | 368 base::UTF8ToUTF16( |
| 367 account_tracker_->GetAccountInfo(account_id).email); | 369 account_tracker_->GetAccountInfo(account_id).email); |
| 368 | 370 |
| 369 // User may have signed out during the fulfillment of the web data | 371 // User may have signed out during the fulfillment of the web data |
| 370 // request, in which case there is no point updating | 372 // request, in which case there is no point updating |
| 371 // |server_profiles_| as it will be cleared. | 373 // |server_profiles_| as it will be cleared. |
| 372 if (!email.empty()) { | 374 if (!email.empty()) { |
| 373 for (AutofillProfile* profile : server_profiles_) | 375 for (auto& profile : server_profiles_) |
| 374 profile->SetRawInfo(EMAIL_ADDRESS, email); | 376 profile->SetRawInfo(EMAIL_ADDRESS, email); |
| 375 } | 377 } |
| 376 } | 378 } |
| 377 } | 379 } |
| 378 break; | 380 break; |
| 379 case AUTOFILL_CREDITCARDS_RESULT: | 381 case AUTOFILL_CREDITCARDS_RESULT: |
| 380 if (h == pending_creditcards_query_) { | 382 if (h == pending_creditcards_query_) { |
| 381 ReceiveLoadedDbValues(h, result, &pending_creditcards_query_, | 383 ReceiveLoadedDbValues(h, result.get(), &pending_creditcards_query_, |
| 382 &local_credit_cards_); | 384 &local_credit_cards_); |
| 383 LogLocalCreditCardCount(); | 385 LogLocalCreditCardCount(); |
| 384 } else { | 386 } else { |
| 385 ReceiveLoadedDbValues(h, result, &pending_server_creditcards_query_, | 387 ReceiveLoadedDbValues(h, result.get(), |
| 388 &pending_server_creditcards_query_, |
| 386 &server_credit_cards_); | 389 &server_credit_cards_); |
| 387 | 390 |
| 388 // If the user has a saved unmasked server card and the experiment is | 391 // If the user has a saved unmasked server card and the experiment is |
| 389 // disabled, force mask all cards back to the unsaved state. | 392 // disabled, force mask all cards back to the unsaved state. |
| 390 if (!OfferStoreUnmaskedCards()) | 393 if (!OfferStoreUnmaskedCards()) |
| 391 ResetFullServerCards(); | 394 ResetFullServerCards(); |
| 392 | 395 |
| 393 LogServerCreditCardCounts(); | 396 LogServerCreditCardCounts(); |
| 394 } | 397 } |
| 395 break; | 398 break; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 | 601 |
| 599 void PersonalDataManager::UpdateServerCreditCard( | 602 void PersonalDataManager::UpdateServerCreditCard( |
| 600 const CreditCard& credit_card) { | 603 const CreditCard& credit_card) { |
| 601 DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type()); | 604 DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type()); |
| 602 | 605 |
| 603 if (is_off_the_record_ || !database_.get()) | 606 if (is_off_the_record_ || !database_.get()) |
| 604 return; | 607 return; |
| 605 | 608 |
| 606 // Look up by server id, not GUID. | 609 // Look up by server id, not GUID. |
| 607 const CreditCard* existing_credit_card = nullptr; | 610 const CreditCard* existing_credit_card = nullptr; |
| 608 for (const auto* server_card : server_credit_cards_) { | 611 for (const auto& server_card : server_credit_cards_) { |
| 609 if (credit_card.server_id() == server_card->server_id()) { | 612 if (credit_card.server_id() == server_card->server_id()) { |
| 610 existing_credit_card = server_card; | 613 existing_credit_card = server_card.get(); |
| 611 break; | 614 break; |
| 612 } | 615 } |
| 613 } | 616 } |
| 614 if (!existing_credit_card) | 617 if (!existing_credit_card) |
| 615 return; | 618 return; |
| 616 | 619 |
| 617 DCHECK_NE(existing_credit_card->record_type(), credit_card.record_type()); | 620 DCHECK_NE(existing_credit_card->record_type(), credit_card.record_type()); |
| 618 DCHECK_EQ(existing_credit_card->Label(), credit_card.Label()); | 621 DCHECK_EQ(existing_credit_card->Label(), credit_card.Label()); |
| 619 if (existing_credit_card->record_type() == CreditCard::MASKED_SERVER_CARD) { | 622 if (existing_credit_card->record_type() == CreditCard::MASKED_SERVER_CARD) { |
| 620 database_->UnmaskServerCreditCard(credit_card, | 623 database_->UnmaskServerCreditCard(credit_card, |
| 621 credit_card.number()); | 624 credit_card.number()); |
| 622 } else { | 625 } else { |
| 623 database_->MaskServerCreditCard(credit_card.server_id()); | 626 database_->MaskServerCreditCard(credit_card.server_id()); |
| 624 } | 627 } |
| 625 | 628 |
| 626 Refresh(); | 629 Refresh(); |
| 627 } | 630 } |
| 628 | 631 |
| 629 void PersonalDataManager::UpdateServerCardBillingAddress( | 632 void PersonalDataManager::UpdateServerCardBillingAddress( |
| 630 const CreditCard& credit_card) { | 633 const CreditCard& credit_card) { |
| 631 DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type()); | 634 DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type()); |
| 632 | 635 |
| 633 if (!database_.get()) | 636 if (!database_.get()) |
| 634 return; | 637 return; |
| 635 | 638 |
| 636 CreditCard* existing_credit_card = nullptr; | 639 CreditCard* existing_credit_card = nullptr; |
| 637 for (auto* server_card : server_credit_cards_) { | 640 for (auto& server_card : server_credit_cards_) { |
| 638 if (credit_card.server_id() == server_card->server_id()) { | 641 if (credit_card.server_id() == server_card->server_id()) { |
| 639 existing_credit_card = server_card; | 642 existing_credit_card = server_card.get(); |
| 640 break; | 643 break; |
| 641 } | 644 } |
| 642 } | 645 } |
| 643 if (!existing_credit_card | 646 if (!existing_credit_card |
| 644 || existing_credit_card->billing_address_id() == | 647 || existing_credit_card->billing_address_id() == |
| 645 credit_card.billing_address_id()) { | 648 credit_card.billing_address_id()) { |
| 646 return; | 649 return; |
| 647 } | 650 } |
| 648 | 651 |
| 649 existing_credit_card->set_billing_address_id( | 652 existing_credit_card->set_billing_address_id( |
| 650 credit_card.billing_address_id()); | 653 credit_card.billing_address_id()); |
| 651 database_->UpdateServerCardBillingAddress(*existing_credit_card); | 654 database_->UpdateServerCardBillingAddress(*existing_credit_card); |
| 652 | 655 |
| 653 Refresh(); | 656 Refresh(); |
| 654 } | 657 } |
| 655 | 658 |
| 656 void PersonalDataManager::ResetFullServerCard(const std::string& guid) { | 659 void PersonalDataManager::ResetFullServerCard(const std::string& guid) { |
| 657 for (const CreditCard* card : server_credit_cards_) { | 660 for (const auto& card : server_credit_cards_) { |
| 658 if (card->guid() == guid) { | 661 if (card->guid() == guid) { |
| 659 DCHECK_EQ(card->record_type(), CreditCard::FULL_SERVER_CARD); | 662 DCHECK_EQ(card->record_type(), CreditCard::FULL_SERVER_CARD); |
| 660 CreditCard card_copy = *card; | 663 CreditCard card_copy = *card; |
| 661 card_copy.set_record_type(CreditCard::MASKED_SERVER_CARD); | 664 card_copy.set_record_type(CreditCard::MASKED_SERVER_CARD); |
| 662 card_copy.SetNumber(card->LastFourDigits()); | 665 card_copy.SetNumber(card->LastFourDigits()); |
| 663 UpdateServerCreditCard(card_copy); | 666 UpdateServerCreditCard(card_copy); |
| 664 break; | 667 break; |
| 665 } | 668 } |
| 666 } | 669 } |
| 667 } | 670 } |
| 668 | 671 |
| 669 void PersonalDataManager::ResetFullServerCards() { | 672 void PersonalDataManager::ResetFullServerCards() { |
| 670 for (const CreditCard* card : server_credit_cards_) { | 673 for (const auto& card : server_credit_cards_) { |
| 671 if (card->record_type() == CreditCard::FULL_SERVER_CARD) { | 674 if (card->record_type() == CreditCard::FULL_SERVER_CARD) { |
| 672 CreditCard card_copy = *card; | 675 CreditCard card_copy = *card; |
| 673 card_copy.set_record_type(CreditCard::MASKED_SERVER_CARD); | 676 card_copy.set_record_type(CreditCard::MASKED_SERVER_CARD); |
| 674 card_copy.SetNumber(card->LastFourDigits()); | 677 card_copy.SetNumber(card->LastFourDigits()); |
| 675 UpdateServerCreditCard(card_copy); | 678 UpdateServerCreditCard(card_copy); |
| 676 } | 679 } |
| 677 } | 680 } |
| 678 } | 681 } |
| 679 | 682 |
| 680 void PersonalDataManager::ClearAllServerData() { | 683 void PersonalDataManager::ClearAllServerData() { |
| 681 // This could theoretically be called before we get the data back from the | 684 // This could theoretically be called before we get the data back from the |
| 682 // database on startup, and it could get called when the wallet pref is | 685 // database on startup, and it could get called when the wallet pref is |
| 683 // off (meaning this class won't even query for the server data) so don't | 686 // off (meaning this class won't even query for the server data) so don't |
| 684 // check the server_credit_cards_/profiles_ before posting to the DB. | 687 // check the server_credit_cards_/profiles_ before posting to the DB. |
| 685 database_->ClearAllServerData(); | 688 database_->ClearAllServerData(); |
| 686 | 689 |
| 687 // The above call will eventually clear our server data by notifying us | 690 // The above call will eventually clear our server data by notifying us |
| 688 // that the data changed and then this class will re-fetch. Preemptively | 691 // that the data changed and then this class will re-fetch. Preemptively |
| 689 // clear so that tests can synchronously verify that this data was cleared. | 692 // clear so that tests can synchronously verify that this data was cleared. |
| 690 server_credit_cards_.clear(); | 693 server_credit_cards_.clear(); |
| 691 server_profiles_.clear(); | 694 server_profiles_.clear(); |
| 692 } | 695 } |
| 693 | 696 |
| 694 void PersonalDataManager::AddServerCreditCardForTest( | 697 void PersonalDataManager::AddServerCreditCardForTest( |
| 695 std::unique_ptr<CreditCard> credit_card) { | 698 std::unique_ptr<CreditCard> credit_card) { |
| 696 server_credit_cards_.push_back(credit_card.release()); | 699 server_credit_cards_.push_back(std::move(credit_card)); |
| 697 } | 700 } |
| 698 | 701 |
| 699 void PersonalDataManager::RemoveByGUID(const std::string& guid) { | 702 void PersonalDataManager::RemoveByGUID(const std::string& guid) { |
| 700 if (is_off_the_record_) | 703 if (is_off_the_record_) |
| 701 return; | 704 return; |
| 702 | 705 |
| 703 bool is_credit_card = FindByGUID<CreditCard>(local_credit_cards_, guid); | 706 bool is_credit_card = FindByGUID<CreditCard>(local_credit_cards_, guid); |
| 704 bool is_profile = !is_credit_card && | 707 bool is_profile = !is_credit_card && |
| 705 FindByGUID<AutofillProfile>(web_profiles_, guid); | 708 FindByGUID<AutofillProfile>(web_profiles_, guid); |
| 706 if (!is_credit_card && !is_profile) | 709 if (!is_credit_card && !is_profile) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 734 } | 737 } |
| 735 | 738 |
| 736 bool PersonalDataManager::IsDataLoaded() const { | 739 bool PersonalDataManager::IsDataLoaded() const { |
| 737 return is_data_loaded_; | 740 return is_data_loaded_; |
| 738 } | 741 } |
| 739 | 742 |
| 740 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const { | 743 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const { |
| 741 return GetProfiles(false); | 744 return GetProfiles(false); |
| 742 } | 745 } |
| 743 | 746 |
| 744 const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const { | 747 std::vector<AutofillProfile*> PersonalDataManager::web_profiles() const { |
| 745 return web_profiles_.get(); | 748 std::vector<AutofillProfile*> result; |
| 749 for (const auto& profile : web_profiles_) |
| 750 result.push_back(profile.get()); |
| 751 return result; |
| 746 } | 752 } |
| 747 | 753 |
| 748 const std::vector<CreditCard*>& PersonalDataManager::GetLocalCreditCards() | 754 std::vector<CreditCard*> PersonalDataManager::GetLocalCreditCards() const { |
| 749 const { | 755 std::vector<CreditCard*> result; |
| 750 return local_credit_cards_.get(); | 756 for (const auto& card : local_credit_cards_) |
| 757 result.push_back(card.get()); |
| 758 return result; |
| 751 } | 759 } |
| 752 | 760 |
| 753 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { | 761 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { |
| 754 credit_cards_.clear(); | 762 credit_cards_.clear(); |
| 755 credit_cards_.insert(credit_cards_.end(), local_credit_cards_.begin(), | 763 for (const auto& card : local_credit_cards_) |
| 756 local_credit_cards_.end()); | 764 credit_cards_.push_back(card.get()); |
| 757 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 765 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
| 758 credit_cards_.insert(credit_cards_.end(), server_credit_cards_.begin(), | 766 for (const auto& card : server_credit_cards_) |
| 759 server_credit_cards_.end()); | 767 credit_cards_.push_back(card.get()); |
| 760 } | 768 } |
| 761 return credit_cards_; | 769 return credit_cards_; |
| 762 } | 770 } |
| 763 | 771 |
| 764 bool PersonalDataManager::HasServerData() const { | 772 bool PersonalDataManager::HasServerData() const { |
| 765 return !server_credit_cards_.empty() || !server_profiles_.empty(); | 773 return !server_credit_cards_.empty() || !server_profiles_.empty(); |
| 766 } | 774 } |
| 767 | 775 |
| 768 void PersonalDataManager::Refresh() { | 776 void PersonalDataManager::Refresh() { |
| 769 LoadProfiles(); | 777 LoadProfiles(); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) | 973 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) |
| 966 return false; | 974 return false; |
| 967 | 975 |
| 968 return true; | 976 return true; |
| 969 } | 977 } |
| 970 | 978 |
| 971 // TODO(crbug.com/618448): Refactor MergeProfile to not depend on class | 979 // TODO(crbug.com/618448): Refactor MergeProfile to not depend on class |
| 972 // variables. | 980 // variables. |
| 973 std::string PersonalDataManager::MergeProfile( | 981 std::string PersonalDataManager::MergeProfile( |
| 974 const AutofillProfile& new_profile, | 982 const AutofillProfile& new_profile, |
| 975 std::vector<AutofillProfile*> existing_profiles, | 983 std::vector<std::unique_ptr<AutofillProfile>>* existing_profiles, |
| 976 const std::string& app_locale, | 984 const std::string& app_locale, |
| 977 std::vector<AutofillProfile>* merged_profiles) { | 985 std::vector<AutofillProfile>* merged_profiles) { |
| 978 merged_profiles->clear(); | 986 merged_profiles->clear(); |
| 979 | 987 |
| 980 // Sort the existing profiles in decreasing order of frecency, so the "best" | 988 // Sort the existing profiles in decreasing order of frecency, so the "best" |
| 981 // profiles are checked first. Put the verified profiles last so the non | 989 // profiles are checked first. Put the verified profiles last so the non |
| 982 // verified profiles get deduped among themselves before reaching the verified | 990 // verified profiles get deduped among themselves before reaching the verified |
| 983 // profiles. | 991 // profiles. |
| 984 // TODO(crbug.com/620521): Remove the check for verified from the sort. | 992 // TODO(crbug.com/620521): Remove the check for verified from the sort. |
| 985 base::Time comparison_time = base::Time::Now(); | 993 base::Time comparison_time = base::Time::Now(); |
| 986 std::sort(existing_profiles.begin(), existing_profiles.end(), | 994 std::sort(existing_profiles->begin(), existing_profiles->end(), |
| 987 [comparison_time](const AutofillDataModel* a, | 995 [comparison_time](const std::unique_ptr<AutofillProfile>& a, |
| 988 const AutofillDataModel* b) { | 996 const std::unique_ptr<AutofillProfile>& b) { |
| 989 if (a->IsVerified() != b->IsVerified()) | 997 if (a->IsVerified() != b->IsVerified()) |
| 990 return !a->IsVerified(); | 998 return !a->IsVerified(); |
| 991 return a->CompareFrecency(b, comparison_time); | 999 return a->CompareFrecency(b.get(), comparison_time); |
| 992 }); | 1000 }); |
| 993 | 1001 |
| 994 // Set to true if |existing_profiles| already contains an equivalent profile. | 1002 // Set to true if |existing_profiles| already contains an equivalent profile. |
| 995 bool matching_profile_found = false; | 1003 bool matching_profile_found = false; |
| 996 std::string guid = new_profile.guid(); | 1004 std::string guid = new_profile.guid(); |
| 997 | 1005 |
| 998 // If we have already saved this address, merge in any missing values. | 1006 // If we have already saved this address, merge in any missing values. |
| 999 // Only merge with the first match. | 1007 // Only merge with the first match. |
| 1000 AutofillProfileComparator comparator(app_locale); | 1008 AutofillProfileComparator comparator(app_locale); |
| 1001 for (AutofillProfile* existing_profile : existing_profiles) { | 1009 for (const auto& existing_profile : *existing_profiles) { |
| 1002 if (!matching_profile_found && | 1010 if (!matching_profile_found && |
| 1003 comparator.AreMergeable(new_profile, *existing_profile) && | 1011 comparator.AreMergeable(new_profile, *existing_profile) && |
| 1004 existing_profile->SaveAdditionalInfo(new_profile, app_locale)) { | 1012 existing_profile->SaveAdditionalInfo(new_profile, app_locale)) { |
| 1005 // Unverified profiles should always be updated with the newer data, | 1013 // Unverified profiles should always be updated with the newer data, |
| 1006 // whereas verified profiles should only ever be overwritten by verified | 1014 // whereas verified profiles should only ever be overwritten by verified |
| 1007 // data. If an automatically aggregated profile would overwrite a | 1015 // data. If an automatically aggregated profile would overwrite a |
| 1008 // verified profile, just drop it. | 1016 // verified profile, just drop it. |
| 1009 matching_profile_found = true; | 1017 matching_profile_found = true; |
| 1010 guid = existing_profile->guid(); | 1018 guid = existing_profile->guid(); |
| 1011 | 1019 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 // Remove empty profiles from input. | 1117 // Remove empty profiles from input. |
| 1110 profiles->erase(std::remove_if(profiles->begin(), profiles->end(), | 1118 profiles->erase(std::remove_if(profiles->begin(), profiles->end(), |
| 1111 IsEmptyFunctor<AutofillProfile>(app_locale_)), | 1119 IsEmptyFunctor<AutofillProfile>(app_locale_)), |
| 1112 profiles->end()); | 1120 profiles->end()); |
| 1113 | 1121 |
| 1114 if (!database_.get()) | 1122 if (!database_.get()) |
| 1115 return; | 1123 return; |
| 1116 | 1124 |
| 1117 // Any profiles that are not in the new profile list should be removed from | 1125 // Any profiles that are not in the new profile list should be removed from |
| 1118 // the web database. | 1126 // the web database. |
| 1119 for (const AutofillProfile* it : web_profiles_) { | 1127 for (const auto& it : web_profiles_) { |
| 1120 if (!FindByGUID<AutofillProfile>(*profiles, it->guid())) | 1128 if (!FindByGUID<AutofillProfile>(*profiles, it->guid())) |
| 1121 database_->RemoveAutofillProfile(it->guid()); | 1129 database_->RemoveAutofillProfile(it->guid()); |
| 1122 } | 1130 } |
| 1123 | 1131 |
| 1124 // Update the web database with the existing profiles. | 1132 // Update the web database with the existing profiles. |
| 1125 for (const AutofillProfile& it : *profiles) { | 1133 for (const AutofillProfile& it : *profiles) { |
| 1126 if (FindByGUID<AutofillProfile>(web_profiles_, it.guid())) | 1134 if (FindByGUID<AutofillProfile>(web_profiles_, it.guid())) |
| 1127 database_->UpdateAutofillProfile(it); | 1135 database_->UpdateAutofillProfile(it); |
| 1128 } | 1136 } |
| 1129 | 1137 |
| 1130 // Add the new profiles to the web database. Don't add a duplicate. | 1138 // Add the new profiles to the web database. Don't add a duplicate. |
| 1131 for (const AutofillProfile& it : *profiles) { | 1139 for (const AutofillProfile& it : *profiles) { |
| 1132 if (!FindByGUID<AutofillProfile>(web_profiles_, it.guid()) && | 1140 if (!FindByGUID<AutofillProfile>(web_profiles_, it.guid()) && |
| 1133 !FindByContents(web_profiles_, it)) | 1141 !FindByContents(web_profiles_, it)) |
| 1134 database_->AddAutofillProfile(it); | 1142 database_->AddAutofillProfile(it); |
| 1135 } | 1143 } |
| 1136 | 1144 |
| 1137 // Copy in the new profiles. | 1145 // Copy in the new profiles. |
| 1138 web_profiles_.clear(); | 1146 web_profiles_.clear(); |
| 1139 for (const AutofillProfile& it : *profiles) { | 1147 for (const AutofillProfile& it : *profiles) { |
| 1140 web_profiles_.push_back(new AutofillProfile(it)); | 1148 web_profiles_.push_back(base::MakeUnique<AutofillProfile>(it)); |
| 1141 } | 1149 } |
| 1142 | 1150 |
| 1143 // Refresh our local cache and send notifications to observers. | 1151 // Refresh our local cache and send notifications to observers. |
| 1144 Refresh(); | 1152 Refresh(); |
| 1145 } | 1153 } |
| 1146 | 1154 |
| 1147 void PersonalDataManager::SetCreditCards( | 1155 void PersonalDataManager::SetCreditCards( |
| 1148 std::vector<CreditCard>* credit_cards) { | 1156 std::vector<CreditCard>* credit_cards) { |
| 1149 if (is_off_the_record_) | 1157 if (is_off_the_record_) |
| 1150 return; | 1158 return; |
| 1151 | 1159 |
| 1152 // Remove empty credit cards from input. | 1160 // Remove empty credit cards from input. |
| 1153 credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(), | 1161 credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(), |
| 1154 IsEmptyFunctor<CreditCard>(app_locale_)), | 1162 IsEmptyFunctor<CreditCard>(app_locale_)), |
| 1155 credit_cards->end()); | 1163 credit_cards->end()); |
| 1156 | 1164 |
| 1157 if (!database_.get()) | 1165 if (!database_.get()) |
| 1158 return; | 1166 return; |
| 1159 | 1167 |
| 1160 // Any credit cards that are not in the new credit card list should be | 1168 // Any credit cards that are not in the new credit card list should be |
| 1161 // removed. | 1169 // removed. |
| 1162 for (const CreditCard* card : local_credit_cards_) { | 1170 for (const auto& card : local_credit_cards_) { |
| 1163 if (!FindByGUID<CreditCard>(*credit_cards, card->guid())) | 1171 if (!FindByGUID<CreditCard>(*credit_cards, card->guid())) |
| 1164 database_->RemoveCreditCard(card->guid()); | 1172 database_->RemoveCreditCard(card->guid()); |
| 1165 } | 1173 } |
| 1166 | 1174 |
| 1167 // Update the web database with the existing credit cards. | 1175 // Update the web database with the existing credit cards. |
| 1168 for (const CreditCard& card : *credit_cards) { | 1176 for (const CreditCard& card : *credit_cards) { |
| 1169 if (FindByGUID<CreditCard>(local_credit_cards_, card.guid())) | 1177 if (FindByGUID<CreditCard>(local_credit_cards_, card.guid())) |
| 1170 database_->UpdateCreditCard(card); | 1178 database_->UpdateCreditCard(card); |
| 1171 } | 1179 } |
| 1172 | 1180 |
| 1173 // Add the new credit cards to the web database. Don't add a duplicate. | 1181 // Add the new credit cards to the web database. Don't add a duplicate. |
| 1174 for (const CreditCard& card : *credit_cards) { | 1182 for (const CreditCard& card : *credit_cards) { |
| 1175 if (!FindByGUID<CreditCard>(local_credit_cards_, card.guid()) && | 1183 if (!FindByGUID<CreditCard>(local_credit_cards_, card.guid()) && |
| 1176 !FindByContents(local_credit_cards_, card)) | 1184 !FindByContents(local_credit_cards_, card)) |
| 1177 database_->AddCreditCard(card); | 1185 database_->AddCreditCard(card); |
| 1178 } | 1186 } |
| 1179 | 1187 |
| 1180 // Copy in the new credit cards. | 1188 // Copy in the new credit cards. |
| 1181 local_credit_cards_.clear(); | 1189 local_credit_cards_.clear(); |
| 1182 for (const CreditCard& card : *credit_cards) | 1190 for (const CreditCard& card : *credit_cards) |
| 1183 local_credit_cards_.push_back(new CreditCard(card)); | 1191 local_credit_cards_.push_back(base::MakeUnique<CreditCard>(card)); |
| 1184 | 1192 |
| 1185 // Refresh our local cache and send notifications to observers. | 1193 // Refresh our local cache and send notifications to observers. |
| 1186 Refresh(); | 1194 Refresh(); |
| 1187 } | 1195 } |
| 1188 | 1196 |
| 1189 void PersonalDataManager::LoadProfiles() { | 1197 void PersonalDataManager::LoadProfiles() { |
| 1190 if (!database_.get()) { | 1198 if (!database_.get()) { |
| 1191 NOTREACHED(); | 1199 NOTREACHED(); |
| 1192 return; | 1200 return; |
| 1193 } | 1201 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1224 *handle = 0; | 1232 *handle = 0; |
| 1225 } | 1233 } |
| 1226 | 1234 |
| 1227 std::string PersonalDataManager::SaveImportedProfile( | 1235 std::string PersonalDataManager::SaveImportedProfile( |
| 1228 const AutofillProfile& imported_profile) { | 1236 const AutofillProfile& imported_profile) { |
| 1229 if (is_off_the_record_) | 1237 if (is_off_the_record_) |
| 1230 return std::string(); | 1238 return std::string(); |
| 1231 | 1239 |
| 1232 // Don't save a web profile if the data in the profile is a subset of a | 1240 // Don't save a web profile if the data in the profile is a subset of a |
| 1233 // server profile, but do record the fact that it was used. | 1241 // server profile, but do record the fact that it was used. |
| 1234 for (const AutofillProfile* profile : server_profiles_) { | 1242 for (const auto& profile : server_profiles_) { |
| 1235 if (imported_profile.IsSubsetOf(*profile, app_locale_)) { | 1243 if (imported_profile.IsSubsetOf(*profile, app_locale_)) { |
| 1236 RecordUseOf(*profile); | 1244 RecordUseOf(*profile); |
| 1237 return profile->guid(); | 1245 return profile->guid(); |
| 1238 } | 1246 } |
| 1239 } | 1247 } |
| 1240 | 1248 |
| 1241 std::vector<AutofillProfile> profiles; | 1249 std::vector<AutofillProfile> profiles; |
| 1242 std::string guid = MergeProfile(imported_profile, web_profiles_.get(), | 1250 std::string guid = |
| 1243 app_locale_, &profiles); | 1251 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles); |
| 1244 SetProfiles(&profiles); | 1252 SetProfiles(&profiles); |
| 1245 return guid; | 1253 return guid; |
| 1246 } | 1254 } |
| 1247 | 1255 |
| 1248 void PersonalDataManager::NotifyPersonalDataChanged() { | 1256 void PersonalDataManager::NotifyPersonalDataChanged() { |
| 1249 for (PersonalDataManagerObserver& observer : observers_) | 1257 for (PersonalDataManagerObserver& observer : observers_) |
| 1250 observer.OnPersonalDataChanged(); | 1258 observer.OnPersonalDataChanged(); |
| 1251 } | 1259 } |
| 1252 | 1260 |
| 1253 std::string PersonalDataManager::SaveImportedCreditCard( | 1261 std::string PersonalDataManager::SaveImportedCreditCard( |
| 1254 const CreditCard& imported_card) { | 1262 const CreditCard& imported_card) { |
| 1255 DCHECK(!imported_card.number().empty()); | 1263 DCHECK(!imported_card.number().empty()); |
| 1256 if (is_off_the_record_) | 1264 if (is_off_the_record_) |
| 1257 return std::string(); | 1265 return std::string(); |
| 1258 | 1266 |
| 1259 // Set to true if |imported_card| is merged into the credit card list. | 1267 // Set to true if |imported_card| is merged into the credit card list. |
| 1260 bool merged = false; | 1268 bool merged = false; |
| 1261 | 1269 |
| 1262 std::string guid = imported_card.guid(); | 1270 std::string guid = imported_card.guid(); |
| 1263 std::vector<CreditCard> credit_cards; | 1271 std::vector<CreditCard> credit_cards; |
| 1264 for (CreditCard* card : local_credit_cards_) { | 1272 for (auto& card : local_credit_cards_) { |
| 1265 // If |imported_card| has not yet been merged, check whether it should be | 1273 // If |imported_card| has not yet been merged, check whether it should be |
| 1266 // with the current |card|. | 1274 // with the current |card|. |
| 1267 if (!merged && card->UpdateFromImportedCard(imported_card, app_locale_)) { | 1275 if (!merged && card->UpdateFromImportedCard(imported_card, app_locale_)) { |
| 1268 guid = card->guid(); | 1276 guid = card->guid(); |
| 1269 merged = true; | 1277 merged = true; |
| 1270 } | 1278 } |
| 1271 | 1279 |
| 1272 credit_cards.push_back(*card); | 1280 credit_cards.push_back(*card); |
| 1273 } | 1281 } |
| 1274 | 1282 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1289 void PersonalDataManager::LogLocalCreditCardCount() const { | 1297 void PersonalDataManager::LogLocalCreditCardCount() const { |
| 1290 if (!has_logged_local_credit_card_count_) { | 1298 if (!has_logged_local_credit_card_count_) { |
| 1291 AutofillMetrics::LogStoredLocalCreditCardCount(local_credit_cards_.size()); | 1299 AutofillMetrics::LogStoredLocalCreditCardCount(local_credit_cards_.size()); |
| 1292 has_logged_local_credit_card_count_ = true; | 1300 has_logged_local_credit_card_count_ = true; |
| 1293 } | 1301 } |
| 1294 } | 1302 } |
| 1295 | 1303 |
| 1296 void PersonalDataManager::LogServerCreditCardCounts() const { | 1304 void PersonalDataManager::LogServerCreditCardCounts() const { |
| 1297 if (!has_logged_server_credit_card_counts_) { | 1305 if (!has_logged_server_credit_card_counts_) { |
| 1298 size_t unmasked_cards = 0, masked_cards = 0; | 1306 size_t unmasked_cards = 0, masked_cards = 0; |
| 1299 for (CreditCard* card : server_credit_cards_) { | 1307 for (const auto& card : server_credit_cards_) { |
| 1300 if (card->record_type() == CreditCard::MASKED_SERVER_CARD) { | 1308 if (card->record_type() == CreditCard::MASKED_SERVER_CARD) { |
| 1301 masked_cards++; | 1309 masked_cards++; |
| 1302 } else if (card->record_type() == CreditCard::FULL_SERVER_CARD) { | 1310 } else if (card->record_type() == CreditCard::FULL_SERVER_CARD) { |
| 1303 unmasked_cards++; | 1311 unmasked_cards++; |
| 1304 } | 1312 } |
| 1305 } | 1313 } |
| 1306 AutofillMetrics::LogStoredServerCreditCardCounts(masked_cards, | 1314 AutofillMetrics::LogStoredServerCreditCardCounts(masked_cards, |
| 1307 unmasked_cards); | 1315 unmasked_cards); |
| 1308 has_logged_server_credit_card_counts_ = true; | 1316 has_logged_server_credit_card_counts_ = true; |
| 1309 } | 1317 } |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 // Reject the credit card if we did not detect enough filled credit card | 1531 // Reject the credit card if we did not detect enough filled credit card |
| 1524 // fields (such as valid number, month, year). | 1532 // fields (such as valid number, month, year). |
| 1525 if (!candidate_credit_card.IsValid()) | 1533 if (!candidate_credit_card.IsValid()) |
| 1526 return false; | 1534 return false; |
| 1527 | 1535 |
| 1528 // Attempt to merge with an existing credit card. Don't present a prompt if we | 1536 // Attempt to merge with an existing credit card. Don't present a prompt if we |
| 1529 // have already saved this card number, unless |should_return_local_card| is | 1537 // have already saved this card number, unless |should_return_local_card| is |
| 1530 // true which indicates that upload is enabled. In this case, it's useful to | 1538 // true which indicates that upload is enabled. In this case, it's useful to |
| 1531 // present the upload prompt to the user to promote the card from a local card | 1539 // present the upload prompt to the user to promote the card from a local card |
| 1532 // to a synced server card. | 1540 // to a synced server card. |
| 1533 for (const CreditCard* card : local_credit_cards_) { | 1541 for (const auto& card : local_credit_cards_) { |
| 1534 // Make a local copy so that the data in |local_credit_cards_| isn't | 1542 // Make a local copy so that the data in |local_credit_cards_| isn't |
| 1535 // modified directly by the UpdateFromImportedCard() call. | 1543 // modified directly by the UpdateFromImportedCard() call. |
| 1536 CreditCard card_copy(*card); | 1544 CreditCard card_copy(*card); |
| 1537 if (card_copy.UpdateFromImportedCard(candidate_credit_card, | 1545 if (card_copy.UpdateFromImportedCard(candidate_credit_card, |
| 1538 app_locale_)) { | 1546 app_locale_)) { |
| 1539 UpdateCreditCard(card_copy); | 1547 UpdateCreditCard(card_copy); |
| 1540 // If we should not return the local card, return that we merged it, | 1548 // If we should not return the local card, return that we merged it, |
| 1541 // without setting |imported_credit_card|. | 1549 // without setting |imported_credit_card|. |
| 1542 if (!should_return_local_card) | 1550 if (!should_return_local_card) |
| 1543 return true; | 1551 return true; |
| 1544 | 1552 |
| 1545 break; | 1553 break; |
| 1546 } | 1554 } |
| 1547 } | 1555 } |
| 1548 | 1556 |
| 1549 // Also don't offer to save if we already have this stored as a server card. | 1557 // Also don't offer to save if we already have this stored as a server card. |
| 1550 // We only check the number because if the new card has the same number as the | 1558 // We only check the number because if the new card has the same number as the |
| 1551 // server card, upload is guaranteed to fail. There's no mechanism for entries | 1559 // server card, upload is guaranteed to fail. There's no mechanism for entries |
| 1552 // with the same number but different names or expiration dates as there is | 1560 // with the same number but different names or expiration dates as there is |
| 1553 // for local cards. | 1561 // for local cards. |
| 1554 for (const CreditCard* card : server_credit_cards_) { | 1562 for (const auto& card : server_credit_cards_) { |
| 1555 if (candidate_credit_card.HasSameNumberAs(*card)) | 1563 if (candidate_credit_card.HasSameNumberAs(*card)) |
| 1556 return false; | 1564 return false; |
| 1557 } | 1565 } |
| 1558 | 1566 |
| 1559 imported_credit_card->reset(new CreditCard(candidate_credit_card)); | 1567 imported_credit_card->reset(new CreditCard(candidate_credit_card)); |
| 1560 return true; | 1568 return true; |
| 1561 } | 1569 } |
| 1562 | 1570 |
| 1563 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles( | 1571 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles( |
| 1564 bool record_metrics) const { | 1572 bool record_metrics) const { |
| 1565 profiles_.clear(); | 1573 profiles_.clear(); |
| 1566 profiles_.insert(profiles_.end(), web_profiles().begin(), | 1574 for (const auto& profile : web_profiles_) |
| 1567 web_profiles().end()); | 1575 profiles_.push_back(profile.get()); |
| 1568 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { | 1576 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { |
| 1569 profiles_.insert( | 1577 for (const auto& profile : server_profiles_) |
| 1570 profiles_.end(), server_profiles_.begin(), server_profiles_.end()); | 1578 profiles_.push_back(profile.get()); |
| 1571 } | 1579 } |
| 1572 return profiles_; | 1580 return profiles_; |
| 1573 } | 1581 } |
| 1574 | 1582 |
| 1575 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( | 1583 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( |
| 1576 const AutofillType& type, | 1584 const AutofillType& type, |
| 1577 const base::string16& field_contents, | 1585 const base::string16& field_contents, |
| 1578 const std::vector<CreditCard*>& cards_to_suggest) const { | 1586 const std::vector<CreditCard*>& cards_to_suggest) const { |
| 1579 std::vector<Suggestion> suggestions; | 1587 std::vector<Suggestion> suggestions; |
| 1580 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); | 1588 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 } | 1671 } |
| 1664 | 1672 |
| 1665 bool PersonalDataManager::ApplyDedupingRoutine() { | 1673 bool PersonalDataManager::ApplyDedupingRoutine() { |
| 1666 if (!is_autofill_profile_dedupe_pending_) | 1674 if (!is_autofill_profile_dedupe_pending_) |
| 1667 return false; | 1675 return false; |
| 1668 | 1676 |
| 1669 DCHECK(IsAutofillProfileCleanupEnabled()); | 1677 DCHECK(IsAutofillProfileCleanupEnabled()); |
| 1670 is_autofill_profile_dedupe_pending_ = false; | 1678 is_autofill_profile_dedupe_pending_ = false; |
| 1671 | 1679 |
| 1672 // No need to de-duplicate if there are less than two profiles. | 1680 // No need to de-duplicate if there are less than two profiles. |
| 1673 if (web_profiles_.get().size() < 2) { | 1681 if (web_profiles_.size() < 2) { |
| 1674 DVLOG(1) << "Autofill profile de-duplication not needed."; | 1682 DVLOG(1) << "Autofill profile de-duplication not needed."; |
| 1675 return false; | 1683 return false; |
| 1676 } | 1684 } |
| 1677 | 1685 |
| 1678 // Check if de-duplication has already been performed this major version. | 1686 // Check if de-duplication has already been performed this major version. |
| 1679 int current_major_version = atoi(version_info::GetVersionNumber().c_str()); | 1687 int current_major_version = atoi(version_info::GetVersionNumber().c_str()); |
| 1680 if (pref_service_->GetInteger(prefs::kAutofillLastVersionDeduped) >= | 1688 if (pref_service_->GetInteger(prefs::kAutofillLastVersionDeduped) >= |
| 1681 current_major_version) { | 1689 current_major_version) { |
| 1682 DVLOG(1) | 1690 DVLOG(1) |
| 1683 << "Autofill profile de-duplication already performed for this version"; | 1691 << "Autofill profile de-duplication already performed for this version"; |
| 1684 return false; | 1692 return false; |
| 1685 } | 1693 } |
| 1686 | 1694 |
| 1687 DVLOG(1) << "Starting autofill profile de-duplication."; | 1695 DVLOG(1) << "Starting autofill profile de-duplication."; |
| 1688 std::vector<AutofillProfile*> existing_profiles = web_profiles_.get(); | |
| 1689 std::unordered_set<AutofillProfile*> profiles_to_delete; | 1696 std::unordered_set<AutofillProfile*> profiles_to_delete; |
| 1690 profiles_to_delete.reserve(existing_profiles.size()); | 1697 profiles_to_delete.reserve(web_profiles_.size()); |
| 1691 | 1698 |
| 1692 DedupeProfiles(&existing_profiles, &profiles_to_delete); | 1699 DedupeProfiles(&web_profiles_, &profiles_to_delete); |
| 1693 | 1700 |
| 1694 // Apply the changes to the database. | 1701 // Apply the changes to the database. |
| 1695 for (AutofillProfile* profile : existing_profiles) { | 1702 for (const auto& profile : web_profiles_) { |
| 1696 // If the profile was set to be deleted, remove it from the database. | 1703 // If the profile was set to be deleted, remove it from the database. |
| 1697 if (profiles_to_delete.count(profile)) { | 1704 if (profiles_to_delete.count(profile.get())) { |
| 1698 database_->RemoveAutofillProfile(profile->guid()); | 1705 database_->RemoveAutofillProfile(profile->guid()); |
| 1699 } else { | 1706 } else { |
| 1700 // Otherwise, update the profile in the database. | 1707 // Otherwise, update the profile in the database. |
| 1701 database_->UpdateAutofillProfile(*profile); | 1708 database_->UpdateAutofillProfile(*profile); |
| 1702 } | 1709 } |
| 1703 } | 1710 } |
| 1704 | 1711 |
| 1705 // Set the pref to the current major version. | 1712 // Set the pref to the current major version. |
| 1706 pref_service_->SetInteger(prefs::kAutofillLastVersionDeduped, | 1713 pref_service_->SetInteger(prefs::kAutofillLastVersionDeduped, |
| 1707 current_major_version); | 1714 current_major_version); |
| 1708 | 1715 |
| 1709 // Refresh the local cache and send notifications to observers. | 1716 // Refresh the local cache and send notifications to observers. |
| 1710 Refresh(); | 1717 Refresh(); |
| 1711 | 1718 |
| 1712 return true; | 1719 return true; |
| 1713 } | 1720 } |
| 1714 | 1721 |
| 1715 void PersonalDataManager::DedupeProfiles( | 1722 void PersonalDataManager::DedupeProfiles( |
| 1716 std::vector<AutofillProfile*>* existing_profiles, | 1723 std::vector<std::unique_ptr<AutofillProfile>>* existing_profiles, |
| 1717 std::unordered_set<AutofillProfile*>* profiles_to_delete) { | 1724 std::unordered_set<AutofillProfile*>* profiles_to_delete) { |
| 1718 AutofillMetrics::LogNumberOfProfilesConsideredForDedupe( | 1725 AutofillMetrics::LogNumberOfProfilesConsideredForDedupe( |
| 1719 existing_profiles->size()); | 1726 existing_profiles->size()); |
| 1720 | 1727 |
| 1721 // Sort the profiles by frecency with all the verified profiles at the end. | 1728 // Sort the profiles by frecency with all the verified profiles at the end. |
| 1722 // That way the most relevant profiles will get merged into the less relevant | 1729 // That way the most relevant profiles will get merged into the less relevant |
| 1723 // profiles, which keeps the syntax of the most relevant profiles data. | 1730 // profiles, which keeps the syntax of the most relevant profiles data. |
| 1724 // Verified profiles are put at the end because they do not merge into other | 1731 // Verified profiles are put at the end because they do not merge into other |
| 1725 // profiles, so the loop can be stopped when we reach those. However they need | 1732 // profiles, so the loop can be stopped when we reach those. However they need |
| 1726 // to be in the vector because an unverified profile trying to merge into a | 1733 // to be in the vector because an unverified profile trying to merge into a |
| 1727 // similar verified profile will be discarded. | 1734 // similar verified profile will be discarded. |
| 1728 base::Time comparison_time = base::Time::Now(); | 1735 base::Time comparison_time = base::Time::Now(); |
| 1729 std::sort(existing_profiles->begin(), existing_profiles->end(), | 1736 std::sort(existing_profiles->begin(), existing_profiles->end(), |
| 1730 [comparison_time](const AutofillDataModel* a, | 1737 [comparison_time](const std::unique_ptr<AutofillProfile>& a, |
| 1731 const AutofillDataModel* b) { | 1738 const std::unique_ptr<AutofillProfile>& b) { |
| 1732 if (a->IsVerified() != b->IsVerified()) | 1739 if (a->IsVerified() != b->IsVerified()) |
| 1733 return !a->IsVerified(); | 1740 return !a->IsVerified(); |
| 1734 return a->CompareFrecency(b, comparison_time); | 1741 return a->CompareFrecency(b.get(), comparison_time); |
| 1735 }); | 1742 }); |
| 1736 | 1743 |
| 1737 AutofillProfileComparator comparator(app_locale_); | 1744 AutofillProfileComparator comparator(app_locale_); |
| 1738 | 1745 |
| 1739 for (size_t i = 0; i < existing_profiles->size(); ++i) { | 1746 for (size_t i = 0; i < existing_profiles->size(); ++i) { |
| 1740 AutofillProfile* profile_to_merge = (*existing_profiles)[i]; | 1747 AutofillProfile* profile_to_merge = (*existing_profiles)[i].get(); |
| 1741 | 1748 |
| 1742 // If the profile was set to be deleted, skip it. It has already been | 1749 // If the profile was set to be deleted, skip it. It has already been |
| 1743 // merged into another profile. | 1750 // merged into another profile. |
| 1744 if (profiles_to_delete->count(profile_to_merge)) | 1751 if (profiles_to_delete->count(profile_to_merge)) |
| 1745 continue; | 1752 continue; |
| 1746 | 1753 |
| 1747 // If we have reached the verified profiles, stop trying to merge. Verified | 1754 // If we have reached the verified profiles, stop trying to merge. Verified |
| 1748 // profiles do not get merged. | 1755 // profiles do not get merged. |
| 1749 if (profile_to_merge->IsVerified()) | 1756 if (profile_to_merge->IsVerified()) |
| 1750 break; | 1757 break; |
| 1751 | 1758 |
| 1752 // If we have not reached the last profile, try to merge |profile_to_merge| | 1759 // If we have not reached the last profile, try to merge |profile_to_merge| |
| 1753 // with all the less relevant |existing_profiles|. | 1760 // with all the less relevant |existing_profiles|. |
| 1754 for (size_t j = i + 1; j < existing_profiles->size(); ++j) { | 1761 for (size_t j = i + 1; j < existing_profiles->size(); ++j) { |
| 1755 AutofillProfile* existing_profile = (*existing_profiles)[j]; | 1762 AutofillProfile* existing_profile = (*existing_profiles)[j].get(); |
| 1756 | 1763 |
| 1757 // Don't try to merge a profile that was already set for deletion. | 1764 // Don't try to merge a profile that was already set for deletion. |
| 1758 if (profiles_to_delete->count(existing_profile)) | 1765 if (profiles_to_delete->count(existing_profile)) |
| 1759 continue; | 1766 continue; |
| 1760 | 1767 |
| 1761 // Move on if the profiles are not mergeable. | 1768 // Move on if the profiles are not mergeable. |
| 1762 if (!comparator.AreMergeable(*existing_profile, *profile_to_merge)) | 1769 if (!comparator.AreMergeable(*existing_profile, *profile_to_merge)) |
| 1763 continue; | 1770 continue; |
| 1764 | 1771 |
| 1765 // The profiles are found to be mergeable. Attempt to update the existing | 1772 // The profiles are found to be mergeable. Attempt to update the existing |
| 1766 // profile. This returns true if the merge was successful, or if the | 1773 // profile. This returns true if the merge was successful, or if the |
| 1767 // merge would have been successful but the existing profile IsVerified() | 1774 // merge would have been successful but the existing profile IsVerified() |
| 1768 // and will not accept updates from profile_to_merge. | 1775 // and will not accept updates from profile_to_merge. |
| 1769 if (existing_profile->SaveAdditionalInfo(*profile_to_merge, | 1776 if (existing_profile->SaveAdditionalInfo(*profile_to_merge, |
| 1770 app_locale_)) { | 1777 app_locale_)) { |
| 1771 // Since |profile_to_merge| was a duplicate of |existing_profile| | 1778 // Since |profile_to_merge| was a duplicate of |existing_profile| |
| 1772 // and was merged sucessfully, it can now be deleted. | 1779 // and was merged successfully, it can now be deleted. |
| 1773 profiles_to_delete->insert(profile_to_merge); | 1780 profiles_to_delete->insert(profile_to_merge); |
| 1774 | 1781 |
| 1775 // Now try to merge the new resulting profile with the rest of the | 1782 // Now try to merge the new resulting profile with the rest of the |
| 1776 // existing profiles. | 1783 // existing profiles. |
| 1777 profile_to_merge = existing_profile; | 1784 profile_to_merge = existing_profile; |
| 1778 | 1785 |
| 1779 // Verified profiles do not get merged. Save some time by not | 1786 // Verified profiles do not get merged. Save some time by not |
| 1780 // trying. | 1787 // trying. |
| 1781 if (profile_to_merge->IsVerified()) | 1788 if (profile_to_merge->IsVerified()) |
| 1782 break; | 1789 break; |
| 1783 } | 1790 } |
| 1784 } | 1791 } |
| 1785 } | 1792 } |
| 1786 AutofillMetrics::LogNumberOfProfilesRemovedDuringDedupe( | 1793 AutofillMetrics::LogNumberOfProfilesRemovedDuringDedupe( |
| 1787 profiles_to_delete->size()); | 1794 profiles_to_delete->size()); |
| 1788 } | 1795 } |
| 1789 | 1796 |
| 1790 } // namespace autofill | 1797 } // namespace autofill |
| OLD | NEW |