Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/payments/content/profile_util.h" | |
| 6 | |
| 7 #include "components/autofill/core/browser/autofill_profile.h" | |
| 8 #include "components/autofill/core/browser/field_types.h" | |
| 9 | |
| 10 namespace payments { | |
| 11 namespace profile_util { | |
| 12 | |
| 13 std::vector<autofill::AutofillProfile*> FilterProfilesForContact( | |
| 14 const std::vector<autofill::AutofillProfile*>& profiles, | |
| 15 const std::string& app_locale, | |
| 16 PaymentRequestSpec* spec) { | |
| 17 // We will be removing profiles, so we operate on a copy. | |
| 18 std::vector<autofill::AutofillProfile*> processed = profiles; | |
|
Roger McFarlane (Chromium)
2017/03/24 18:23:16
Note, but don't actually apply, that this could ha
| |
| 19 | |
| 20 PaymentsProfileComparator comparator(app_locale, spec); | |
| 21 | |
| 22 // Stable sort, since profiles are expected to be passed in frecency order. | |
| 23 std::stable_sort( | |
| 24 processed.begin(), processed.end(), | |
| 25 std::bind(&PaymentsProfileComparator::CompareContactCompleteness, | |
| 26 &comparator, std::placeholders::_1, std::placeholders::_2)); | |
| 27 | |
| 28 auto it = processed.begin(); | |
| 29 while (it != processed.end()) { | |
| 30 if (comparator.GetContactCompletenessScore(*it) == 0) { | |
| 31 // Since profiles are sorted by completeness, this and any further | |
| 32 // profiles can be discarded. | |
| 33 processed.erase(it, processed.end()); | |
| 34 break; | |
| 35 } | |
| 36 | |
| 37 // Attempt to find a matching element in the vector before the current. | |
| 38 // This is quadratic, but the number of elements is generally small | |
| 39 // (< 10), so a more complicated algorithm would be overkill. | |
| 40 if (std::find_if(processed.begin(), it, | |
| 41 [&](autofill::AutofillProfile* prior) { | |
| 42 return comparator.IsContactEqualOrSuperset(prior, *it); | |
| 43 }) != it) { | |
| 44 // Remove the subset profile. Do not update |it|, as it will point to | |
| 45 // the next element after erasure. | |
| 46 processed.erase(it); | |
|
Roger McFarlane (Chromium)
2017/03/24 18:23:16
this isn't safe (i.e., you're venturing off into u
sebsg
2017/03/27 17:13:28
+1. What I did in Java is have add them to a new v
tmartino
2017/04/03 16:42:54
As discussed offline, erase returns an iterator to
| |
| 47 } else { | |
| 48 it++; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 return processed; | |
| 53 } | |
| 54 | |
| 55 PaymentsProfileComparator::PaymentsProfileComparator( | |
| 56 const std::string& app_locale, | |
| 57 PaymentRequestSpec* spec) | |
| 58 : autofill::AutofillProfileComparator(app_locale), spec_(spec) {} | |
| 59 | |
| 60 PaymentsProfileComparator::~PaymentsProfileComparator() {} | |
| 61 | |
| 62 bool PaymentsProfileComparator::IsContactEqualOrSuperset( | |
|
Roger McFarlane (Chromium)
2017/03/24 18:23:16
Alas, the merge-ability tests don't really yield a
sebsg
2017/03/27 17:13:28
Yeah that's a good point Roger. In the Java implem
tmartino
2017/04/03 16:42:54
As resolved offline we've decided to accept this.
| |
| 63 autofill::AutofillProfile* super, | |
| 64 autofill::AutofillProfile* sub) { | |
| 65 if (spec_->request_payer_name()) { | |
| 66 if (sub->HasInfo(autofill::NAME_FULL) && | |
| 67 !super->HasInfo(autofill::NAME_FULL)) | |
|
Roger McFarlane (Chromium)
2017/03/24 18:23:16
nit: multi-line if requires curly braces
tmartino
2017/04/03 16:42:54
Believe it or not, I've been told elsewhere that t
| |
| 68 return false; | |
| 69 if (!HaveMergeableNames(*super, *sub)) | |
| 70 return false; | |
| 71 } | |
| 72 if (spec_->request_payer_phone()) { | |
| 73 if (sub->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER) && | |
| 74 !super->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) | |
| 75 return false; | |
| 76 if (!HaveMergeablePhoneNumbers(*super, *sub)) | |
| 77 return false; | |
| 78 } | |
| 79 if (spec_->request_payer_email()) { | |
| 80 if (sub->HasInfo(autofill::EMAIL_ADDRESS) && | |
| 81 !super->HasInfo(autofill::EMAIL_ADDRESS)) | |
| 82 return false; | |
| 83 if (!HaveMergeableEmailAddresses(*super, *sub)) | |
| 84 return false; | |
| 85 } | |
| 86 return true; | |
| 87 } | |
| 88 | |
| 89 int PaymentsProfileComparator::GetContactCompletenessScore( | |
| 90 autofill::AutofillProfile* profile) { | |
| 91 int score = 0; | |
| 92 if (spec_->request_payer_name() && profile->HasInfo(autofill::NAME_FULL)) | |
| 93 score++; | |
| 94 if (spec_->request_payer_phone() && | |
| 95 profile->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) | |
| 96 score++; | |
| 97 if (spec_->request_payer_email() && profile->HasInfo(autofill::EMAIL_ADDRESS)) | |
| 98 score++; | |
| 99 return score; | |
|
Roger McFarlane (Chromium)
2017/03/24 18:23:16
could be made a bit more succinct?
return
(sp
sebsg
2017/03/27 17:13:28
For the spec question: Not really, they all need t
tmartino
2017/04/03 16:42:54
Done re: succinctness.
| |
| 100 } | |
| 101 | |
| 102 bool PaymentsProfileComparator::IsContactInfoComplete( | |
| 103 autofill::AutofillProfile* profile) { | |
| 104 int score = spec_->request_payer_name() + spec_->request_payer_phone() + | |
|
Roger McFarlane (Chromium)
2017/03/24 18:23:16
s/score/desired_score|full_score/
?
tmartino
2017/04/03 16:42:54
Done
| |
| 105 spec_->request_payer_email(); | |
| 106 return GetContactCompletenessScore(profile) == score; | |
| 107 } | |
| 108 | |
| 109 bool PaymentsProfileComparator::CompareContactCompleteness( | |
| 110 autofill::AutofillProfile* p1, | |
| 111 autofill::AutofillProfile* p2) { | |
| 112 return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2); | |
| 113 } | |
| 114 | |
| 115 } // namespace profile_util | |
| 116 } // namespace payments | |
| OLD | NEW |