Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: components/payments/core/profile_util.cc

Issue 2775553004: [WebPayments] Implementing Profile filter and dedupe (Closed)
Patch Set: include algo Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/core/profile_util.h"
6
7 #include <algorithm>
8
9 #include "components/autofill/core/browser/autofill_profile.h"
10 #include "components/autofill/core/browser/field_types.h"
11 #include "components/payments/core/payment_options_provider.h"
12
13 namespace payments {
14 namespace profile_util {
15
16 std::vector<autofill::AutofillProfile*> FilterProfilesForContact(
17 const std::vector<autofill::AutofillProfile*>& profiles,
18 const std::string& app_locale,
19 PaymentOptionsProvider* options) {
20 // We will be removing profiles, so we operate on a copy.
21 std::vector<autofill::AutofillProfile*> processed = profiles;
22
23 PaymentsProfileComparator comparator(app_locale, options);
24
25 // Stable sort, since profiles are expected to be passed in frecency order.
26 std::stable_sort(
27 processed.begin(), processed.end(),
28 std::bind(&PaymentsProfileComparator::IsContactMoreComplete, &comparator,
29 std::placeholders::_1, std::placeholders::_2));
30
31 auto it = processed.begin();
32 while (it != processed.end()) {
33 if (comparator.GetContactCompletenessScore(*it) == 0) {
34 // Since profiles are sorted by completeness, this and any further
35 // profiles can be discarded.
36 processed.erase(it, processed.end());
37 break;
38 }
39
40 // Attempt to find a matching element in the vector before the current.
41 // This is quadratic, but the number of elements is generally small
42 // (< 10), so a more complicated algorithm would be overkill.
43 if (std::find_if(processed.begin(), it,
44 [&](autofill::AutofillProfile* prior) {
45 return comparator.IsContactEqualOrSuperset(prior, *it);
46 }) != it) {
47 // Remove the subset profile. |it| will point to the next element after
48 // erasure.
49 it = processed.erase(it);
50 } else {
51 it++;
52 }
53 }
54
55 return processed;
56 }
57
58 PaymentsProfileComparator::PaymentsProfileComparator(
59 const std::string& app_locale,
60 PaymentOptionsProvider* options)
61 : autofill::AutofillProfileComparator(app_locale), options_(options) {}
62
63 PaymentsProfileComparator::~PaymentsProfileComparator() {}
64
65 bool PaymentsProfileComparator::IsContactEqualOrSuperset(
66 autofill::AutofillProfile* super,
67 autofill::AutofillProfile* sub) {
68 if (options_->request_payer_name()) {
69 if (sub->HasInfo(autofill::NAME_FULL) &&
70 !super->HasInfo(autofill::NAME_FULL)) {
71 return false;
72 }
73 if (!HaveMergeableNames(*super, *sub))
74 return false;
75 }
76 if (options_->request_payer_phone()) {
77 if (sub->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER) &&
78 !super->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) {
79 return false;
80 }
81 if (!HaveMergeablePhoneNumbers(*super, *sub))
82 return false;
83 }
84 if (options_->request_payer_email()) {
85 if (sub->HasInfo(autofill::EMAIL_ADDRESS) &&
86 !super->HasInfo(autofill::EMAIL_ADDRESS)) {
87 return false;
88 }
89 if (!HaveMergeableEmailAddresses(*super, *sub))
90 return false;
91 }
92 return true;
93 }
94
95 int PaymentsProfileComparator::GetContactCompletenessScore(
96 autofill::AutofillProfile* profile) {
Mathieu 2017/04/03 19:11:53 const ref?
tmartino 2017/04/04 21:00:22 I thought about it, but considering the need to us
Mathieu 2017/04/05 13:43:10 I think as much as possible we should use const re
97 if (!profile)
98 return 0;
99
100 return (options_->request_payer_name() &&
101 profile->HasInfo(autofill::NAME_FULL)) +
102 (options_->request_payer_phone() &&
103 profile->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) +
104 (options_->request_payer_email() &&
105 profile->HasInfo(autofill::EMAIL_ADDRESS));
106 }
107
108 bool PaymentsProfileComparator::IsContactInfoComplete(
109 autofill::AutofillProfile* profile) {
110 int desired_score = options_->request_payer_name() +
111 options_->request_payer_phone() +
112 options_->request_payer_email();
113 return GetContactCompletenessScore(profile) == desired_score;
114 }
115
116 bool PaymentsProfileComparator::IsContactMoreComplete(
117 autofill::AutofillProfile* p1,
118 autofill::AutofillProfile* p2) {
119 return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2);
120 }
121
122 } // namespace profile_util
123 } // namespace payments
OLDNEW
« components/payments/core/profile_util.h ('K') | « components/payments/core/profile_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698