Chromium Code Reviews| Index: components/payments/core/address_normalization_manager.cc |
| diff --git a/components/payments/core/address_normalization_manager.cc b/components/payments/core/address_normalization_manager.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..066f873da726042ec3863b19fad4c5e7ac7790c3 |
| --- /dev/null |
| +++ b/components/payments/core/address_normalization_manager.cc |
| @@ -0,0 +1,143 @@ |
| +// 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/core/address_normalization_manager.h" |
| + |
| +#include "base/memory/ptr_util.h" |
| +#include "base/strings/utf_string_conversions.h" |
| +#include "components/autofill/core/browser/autofill_data_util.h" |
| +#include "components/autofill/core/browser/field_types.h" |
| +#include "components/payments/core/address_normalizer.h" |
| + |
| +namespace payments { |
| + |
| +namespace { |
| +constexpr int kAddressNormalizationTimeoutSeconds = 5; |
| +} // namespace |
| + |
| +// Implements the payments::AddressNormalizer::Delegate interface, and |
| +// notifies its parent AddressNormalizationManager when normalization has |
| +// completed. |
| +class AddressNormalizationManager::NormalizerDelegate |
| + : public payments::AddressNormalizer::Delegate { |
|
Mathieu
2017/05/17 16:45:14
no need for payments::
macourteau
2017/05/17 18:38:40
Done.
|
| + public: |
| + // |owner| is the parent AddressNormalizationManager, |address_normalizer| is |
| + // a pointer to an instance of AddressNormalizer which will handle |
| + // normalization of |profile|. |profile| will be updated when normalization is |
| + // complete. |
| + NormalizerDelegate(AddressNormalizationManager* owner, |
| + AddressNormalizer* address_normalizer, |
| + autofill::AutofillProfile* profile); |
| + |
| + // Returns whether this delegate has completed or not. |
| + bool HasCompleted() const; |
| + |
| + // payments::AddressNormalizer::Delegate: |
| + void OnAddressNormalized( |
| + const autofill::AutofillProfile& normalized_profile) override; |
| + void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override; |
| + |
| + private: |
| + // Helper method that handles when normalization has completed. |
| + void OnCompletion(const autofill::AutofillProfile& profile); |
| + |
| + bool has_completed_ = false; |
| + AddressNormalizationManager* owner_ = nullptr; |
| + autofill::AutofillProfile* profile_ = nullptr; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(NormalizerDelegate); |
| +}; |
| + |
| +AddressNormalizationManager::AddressNormalizationManager( |
| + std::unique_ptr<AddressNormalizer> address_normalizer, |
| + const std::string& default_country_code) |
| + : default_country_code_(default_country_code), |
| + address_normalizer_(std::move(address_normalizer)) { |
| + DCHECK(autofill::data_util::IsValidCountryCode(default_country_code)); |
| + DCHECK(address_normalizer_); |
| + |
| + // Start loading rules for the default country code. This happens |
| + // asynchronously, and will speed up normalization later if the rules for the |
| + // address' region have already been loaded. |
| + address_normalizer_->LoadRulesForRegion(default_country_code); |
| +} |
| + |
| +AddressNormalizationManager::~AddressNormalizationManager() {} |
| + |
| +void AddressNormalizationManager::FinalizeWithCompletionCallback( |
| + CompletionCallback completion_callback) { |
| + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| + completion_callback_ = std::move(completion_callback); |
| + accepting_requests_ = false; |
| + MaybeRunCompletionCallback(); |
| +} |
| + |
| +void AddressNormalizationManager::StartNormalizingAddress( |
| + autofill::AutofillProfile* profile) { |
| + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| + DCHECK(accepting_requests_) << "FinalizeWithCompletionCallback has been " |
| + "called, cannot normalize more addresses"; |
| + |
| + delegates_.push_back(base::MakeUnique<NormalizerDelegate>( |
|
Mathieu
2017/05/17 16:45:14
can we use emplace_back and remove the std::unique
macourteau
2017/05/17 18:38:40
NormalizerDelegate is noncopyable (DISALLOW_COPY_A
|
| + this, address_normalizer_.get(), profile)); |
| +} |
| + |
| +void AddressNormalizationManager::MaybeRunCompletionCallback() { |
| + if (accepting_requests_ || !completion_callback_) |
| + return; |
| + |
| + for (const auto& delegate : delegates_) { |
| + if (!delegate->HasCompleted()) { |
| + return; |
| + } |
| + } |
| + |
| + // We're no longer accepting requests, and all the delegates have completed. |
| + // Now's the time to run the completion callback. |
| + std::move(completion_callback_).Run(*this); |
| +} |
| + |
| +AddressNormalizationManager::NormalizerDelegate::NormalizerDelegate( |
| + AddressNormalizationManager* owner, |
| + AddressNormalizer* address_normalizer, |
| + autofill::AutofillProfile* profile) |
| + : owner_(owner), profile_(profile) { |
| + DCHECK(owner_); |
| + DCHECK(profile_); |
| + |
| + std::string country_code = |
| + base::UTF16ToUTF8(profile_->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); |
| + if (!autofill::data_util::IsValidCountryCode(country_code)) { |
|
Mathieu
2017/05/17 16:45:14
nit: no curlies
macourteau
2017/05/17 18:38:40
Done.
|
| + country_code = owner_->default_country_code_; |
| + } |
| + |
| + address_normalizer->StartAddressNormalization( |
| + *profile_, country_code, kAddressNormalizationTimeoutSeconds, this); |
| +} |
| + |
| +bool AddressNormalizationManager::NormalizerDelegate::HasCompleted() const { |
|
Mathieu
2017/05/17 16:45:14
has_completed() can be used
macourteau
2017/05/17 18:38:40
Done.
|
| + return has_completed_; |
| +} |
| + |
| +void AddressNormalizationManager::NormalizerDelegate::OnAddressNormalized( |
| + const autofill::AutofillProfile& normalized_profile) { |
| + OnCompletion(normalized_profile); |
| +} |
| + |
| +void AddressNormalizationManager::NormalizerDelegate::OnCouldNotNormalize( |
| + const autofill::AutofillProfile& profile) { |
| + // Since the phone number is formatted in either case, this profile should |
| + // be used. |
| + OnCompletion(profile); |
| +} |
| + |
| +void AddressNormalizationManager::NormalizerDelegate::OnCompletion( |
| + const autofill::AutofillProfile& profile) { |
| + DCHECK(!has_completed_); |
| + has_completed_ = true; |
| + *profile_ = profile; |
| + owner_->MaybeRunCompletionCallback(); |
| +} |
| + |
| +} // namespace payments |