| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 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 "ios/chrome/browser/payments/payment_request.h" | 5 #include "ios/chrome/browser/payments/payment_request.h" |
| 6 | 6 |
| 7 #include "base/containers/adapters.h" |
| 7 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 8 #include "components/autofill/core/browser/autofill_data_util.h" | 9 #include "components/autofill/core/browser/autofill_data_util.h" |
| 9 #include "components/autofill/core/browser/autofill_profile.h" | 10 #include "components/autofill/core/browser/autofill_profile.h" |
| 10 #include "components/autofill/core/browser/credit_card.h" | 11 #include "components/autofill/core/browser/credit_card.h" |
| 11 #include "components/autofill/core/browser/personal_data_manager.h" | 12 #include "components/autofill/core/browser/personal_data_manager.h" |
| 12 #include "components/payments/core/currency_formatter.h" | 13 #include "components/payments/core/currency_formatter.h" |
| 13 #include "components/payments/core/payment_request_data_util.h" | 14 #include "components/payments/core/payment_request_data_util.h" |
| 14 #include "components/payments/core/payments_profile_comparator.h" | 15 #include "components/payments/core/payments_profile_comparator.h" |
| 15 #include "ios/chrome/browser/application_context.h" | 16 #include "ios/chrome/browser/application_context.h" |
| 16 #include "ios/web/public/payments/payment_request.h" | 17 #include "ios/web/public/payments/payment_request.h" |
| 17 | 18 |
| 18 #if !defined(__has_feature) || !__has_feature(objc_arc) | 19 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 19 #error "This file requires ARC support." | 20 #error "This file requires ARC support." |
| 20 #endif | 21 #endif |
| 21 | 22 |
| 22 PaymentRequest::PaymentRequest( | 23 PaymentRequest::PaymentRequest( |
| 23 const web::PaymentRequest& web_payment_request, | 24 const web::PaymentRequest& web_payment_request, |
| 24 autofill::PersonalDataManager* personal_data_manager) | 25 autofill::PersonalDataManager* personal_data_manager) |
| 25 : web_payment_request_(web_payment_request), | 26 : web_payment_request_(web_payment_request), |
| 26 personal_data_manager_(personal_data_manager), | 27 personal_data_manager_(personal_data_manager), |
| 27 selected_shipping_profile_(nullptr), | 28 selected_shipping_profile_(nullptr), |
| 28 selected_contact_profile_(nullptr), | 29 selected_contact_profile_(nullptr), |
| 29 selected_credit_card_(nullptr), | 30 selected_credit_card_(nullptr), |
| 30 selected_shipping_option_(nullptr) { | 31 selected_shipping_option_(nullptr), |
| 32 profile_comparator_(GetApplicationContext()->GetApplicationLocale(), |
| 33 *this) { |
| 34 PopulateShippingOptionCache(); |
| 31 PopulateProfileCache(); | 35 PopulateProfileCache(); |
| 32 PopulateCreditCardCache(); | 36 PopulateCreditCardCache(); |
| 33 PopulateShippingOptionCache(); | |
| 34 } | 37 } |
| 35 | 38 |
| 36 PaymentRequest::~PaymentRequest() {} | 39 PaymentRequest::~PaymentRequest() {} |
| 37 | 40 |
| 38 void PaymentRequest::set_payment_details(const web::PaymentDetails& details) { | 41 void PaymentRequest::UpdatePaymentDetails(const web::PaymentDetails& details) { |
| 39 web_payment_request_.details = details; | 42 web_payment_request_.details = details; |
| 40 PopulateShippingOptionCache(); | 43 PopulateShippingOptionCache(); |
| 41 } | 44 } |
| 42 | 45 |
| 43 bool PaymentRequest::request_shipping() const { | 46 bool PaymentRequest::request_shipping() const { |
| 44 return web_payment_request_.options.request_shipping; | 47 return web_payment_request_.options.request_shipping; |
| 45 } | 48 } |
| 46 | 49 |
| 47 bool PaymentRequest::request_payer_name() const { | 50 bool PaymentRequest::request_payer_name() const { |
| 48 return web_payment_request_.options.request_payer_name; | 51 return web_payment_request_.options.request_payer_name; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 return credit_cards_.front(); | 87 return credit_cards_.front(); |
| 85 } | 88 } |
| 86 | 89 |
| 87 bool PaymentRequest::CanMakePayment() const { | 90 bool PaymentRequest::CanMakePayment() const { |
| 88 return !credit_cards_.empty(); | 91 return !credit_cards_.empty(); |
| 89 } | 92 } |
| 90 | 93 |
| 91 void PaymentRequest::PopulateProfileCache() { | 94 void PaymentRequest::PopulateProfileCache() { |
| 92 const std::vector<autofill::AutofillProfile*>& profiles_to_suggest = | 95 const std::vector<autofill::AutofillProfile*>& profiles_to_suggest = |
| 93 personal_data_manager_->GetProfilesToSuggest(); | 96 personal_data_manager_->GetProfilesToSuggest(); |
| 97 // Return early if the user has no stored Autofill profiles. |
| 98 if (profiles_to_suggest.empty()) |
| 99 return; |
| 100 |
| 94 profile_cache_.reserve(profiles_to_suggest.size()); | 101 profile_cache_.reserve(profiles_to_suggest.size()); |
| 95 for (const auto* profile : profiles_to_suggest) { | 102 for (const auto* profile : profiles_to_suggest) { |
| 96 profile_cache_.push_back(*profile); | 103 profile_cache_.push_back(*profile); |
| 97 shipping_profiles_.push_back(&profile_cache_.back()); | 104 shipping_profiles_.push_back(&profile_cache_.back()); |
| 98 contact_profiles_.push_back(&profile_cache_.back()); | |
| 99 } | 105 } |
| 100 | 106 |
| 101 payments::PaymentsProfileComparator comparator( | 107 // If the merchant provided a shipping option, select a suitable default |
| 102 GetApplicationContext()->GetApplicationLocale(), *this); | 108 // shipping profile. We pick the profile that is most complete, going down |
| 109 // the list in Frecency order. |
| 110 // TODO(crbug.com/719652): Have a proper ordering of shipping addresses by |
| 111 // completeness. |
| 112 if (selected_shipping_option_) { |
| 113 selected_shipping_profile_ = shipping_profiles_[0]; |
| 114 for (autofill::AutofillProfile* profile : shipping_profiles_) { |
| 115 if (profile_comparator_.IsShippingComplete(profile)) { |
| 116 selected_shipping_profile_ = profile; |
| 117 break; |
| 118 } |
| 119 } |
| 120 } |
| 103 | 121 |
| 104 // TODO(crbug.com/602666): Implement deduplication and prioritization rules | 122 // Contact profiles are deduped and ordered in completeness. |
| 105 // for shipping profiles. | 123 contact_profiles_ = |
| 124 profile_comparator_.FilterProfilesForContact(shipping_profiles_); |
| 106 | 125 |
| 107 contact_profiles_ = comparator.FilterProfilesForContact(contact_profiles_); | 126 // If the highest-ranking contact profile is usable, select it. Otherwise, |
| 108 | 127 // select none. |
| 109 if (!shipping_profiles_.empty()) | |
| 110 selected_shipping_profile_ = shipping_profiles_[0]; | |
| 111 if (!contact_profiles_.empty() && | 128 if (!contact_profiles_.empty() && |
| 112 comparator.IsContactInfoComplete(contact_profiles_[0])) { | 129 profile_comparator_.IsContactInfoComplete(contact_profiles_[0])) { |
| 113 selected_contact_profile_ = contact_profiles_[0]; | 130 selected_contact_profile_ = contact_profiles_[0]; |
| 114 } | 131 } |
| 115 } | 132 } |
| 116 | 133 |
| 117 void PaymentRequest::PopulateCreditCardCache() { | 134 void PaymentRequest::PopulateCreditCardCache() { |
| 118 // TODO(crbug.com/709036): Validate method data. | 135 // TODO(crbug.com/709036): Validate method data. |
| 119 payments::data_util::ParseBasicCardSupportedNetworks( | 136 payments::data_util::ParseBasicCardSupportedNetworks( |
| 120 web_payment_request_.method_data, &supported_card_networks_, | 137 web_payment_request_.method_data, &supported_card_networks_, |
| 121 &basic_card_specified_networks_); | 138 &basic_card_specified_networks_); |
| 122 | 139 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 137 } | 154 } |
| 138 | 155 |
| 139 // TODO(crbug.com/602666): Implement prioritization rules for credit cards. | 156 // TODO(crbug.com/602666): Implement prioritization rules for credit cards. |
| 140 | 157 |
| 141 if (!credit_cards_.empty()) | 158 if (!credit_cards_.empty()) |
| 142 selected_credit_card_ = credit_cards_[0]; | 159 selected_credit_card_ = credit_cards_[0]; |
| 143 } | 160 } |
| 144 | 161 |
| 145 void PaymentRequest::PopulateShippingOptionCache() { | 162 void PaymentRequest::PopulateShippingOptionCache() { |
| 146 shipping_options_.clear(); | 163 shipping_options_.clear(); |
| 164 selected_shipping_option_ = nullptr; |
| 165 if (web_payment_request_.details.shipping_options.empty()) |
| 166 return; |
| 167 |
| 147 shipping_options_.reserve( | 168 shipping_options_.reserve( |
| 148 web_payment_request_.details.shipping_options.size()); | 169 web_payment_request_.details.shipping_options.size()); |
| 149 std::transform(std::begin(web_payment_request_.details.shipping_options), | 170 std::transform(std::begin(web_payment_request_.details.shipping_options), |
| 150 std::end(web_payment_request_.details.shipping_options), | 171 std::end(web_payment_request_.details.shipping_options), |
| 151 std::back_inserter(shipping_options_), | 172 std::back_inserter(shipping_options_), |
| 152 [](web::PaymentShippingOption& option) { return &option; }); | 173 [](web::PaymentShippingOption& option) { return &option; }); |
| 153 | 174 |
| 154 selected_shipping_option_ = nullptr; | 175 for (auto* shipping_option : base::Reversed(shipping_options_)) { |
| 155 for (auto* shipping_option : shipping_options_) { | |
| 156 if (shipping_option->selected) { | 176 if (shipping_option->selected) { |
| 157 // If more than one option has |selected| set, the last one in the | 177 // If more than one option has |selected| set, the last one in the |
| 158 // sequence should be treated as the selected item. | 178 // sequence should be treated as the selected item. |
| 159 selected_shipping_option_ = shipping_option; | 179 selected_shipping_option_ = shipping_option; |
| 180 break; |
| 160 } | 181 } |
| 161 } | 182 } |
| 162 } | 183 } |
| OLD | NEW |