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 |