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

Unified Diff: components/payments/content/profile_util.cc

Issue 2775553004: [WebPayments] Implementing Profile filter and dedupe (Closed)
Patch Set: Adding omitted files Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: components/payments/content/profile_util.cc
diff --git a/components/payments/content/profile_util.cc b/components/payments/content/profile_util.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8f9a09231259785da418e06db2dd8f924cf44f4e
--- /dev/null
+++ b/components/payments/content/profile_util.cc
@@ -0,0 +1,116 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/payments/content/profile_util.h"
+
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+
+namespace payments {
+namespace profile_util {
+
+std::vector<autofill::AutofillProfile*> FilterProfilesForContact(
+ const std::vector<autofill::AutofillProfile*>& profiles,
+ const std::string& app_locale,
+ PaymentRequestSpec* spec) {
+ // We will be removing profiles, so we operate on a copy.
+ 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
+
+ PaymentsProfileComparator comparator(app_locale, spec);
+
+ // Stable sort, since profiles are expected to be passed in frecency order.
+ std::stable_sort(
+ processed.begin(), processed.end(),
+ std::bind(&PaymentsProfileComparator::CompareContactCompleteness,
+ &comparator, std::placeholders::_1, std::placeholders::_2));
+
+ auto it = processed.begin();
+ while (it != processed.end()) {
+ if (comparator.GetContactCompletenessScore(*it) == 0) {
+ // Since profiles are sorted by completeness, this and any further
+ // profiles can be discarded.
+ processed.erase(it, processed.end());
+ break;
+ }
+
+ // Attempt to find a matching element in the vector before the current.
+ // This is quadratic, but the number of elements is generally small
+ // (< 10), so a more complicated algorithm would be overkill.
+ if (std::find_if(processed.begin(), it,
+ [&](autofill::AutofillProfile* prior) {
+ return comparator.IsContactEqualOrSuperset(prior, *it);
+ }) != it) {
+ // Remove the subset profile. Do not update |it|, as it will point to
+ // the next element after erasure.
+ 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
+ } else {
+ it++;
+ }
+ }
+
+ return processed;
+}
+
+PaymentsProfileComparator::PaymentsProfileComparator(
+ const std::string& app_locale,
+ PaymentRequestSpec* spec)
+ : autofill::AutofillProfileComparator(app_locale), spec_(spec) {}
+
+PaymentsProfileComparator::~PaymentsProfileComparator() {}
+
+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.
+ autofill::AutofillProfile* super,
+ autofill::AutofillProfile* sub) {
+ if (spec_->request_payer_name()) {
+ if (sub->HasInfo(autofill::NAME_FULL) &&
+ !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
+ return false;
+ if (!HaveMergeableNames(*super, *sub))
+ return false;
+ }
+ if (spec_->request_payer_phone()) {
+ if (sub->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER) &&
+ !super->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER))
+ return false;
+ if (!HaveMergeablePhoneNumbers(*super, *sub))
+ return false;
+ }
+ if (spec_->request_payer_email()) {
+ if (sub->HasInfo(autofill::EMAIL_ADDRESS) &&
+ !super->HasInfo(autofill::EMAIL_ADDRESS))
+ return false;
+ if (!HaveMergeableEmailAddresses(*super, *sub))
+ return false;
+ }
+ return true;
+}
+
+int PaymentsProfileComparator::GetContactCompletenessScore(
+ autofill::AutofillProfile* profile) {
+ int score = 0;
+ if (spec_->request_payer_name() && profile->HasInfo(autofill::NAME_FULL))
+ score++;
+ if (spec_->request_payer_phone() &&
+ profile->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER))
+ score++;
+ if (spec_->request_payer_email() && profile->HasInfo(autofill::EMAIL_ADDRESS))
+ score++;
+ 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.
+}
+
+bool PaymentsProfileComparator::IsContactInfoComplete(
+ autofill::AutofillProfile* profile) {
+ 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
+ spec_->request_payer_email();
+ return GetContactCompletenessScore(profile) == score;
+}
+
+bool PaymentsProfileComparator::CompareContactCompleteness(
+ autofill::AutofillProfile* p1,
+ autofill::AutofillProfile* p2) {
+ return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2);
+}
+
+} // namespace profile_util
+} // namespace payments
« components/payments/content/profile_util.h ('K') | « components/payments/content/profile_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698