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

Side by Side Diff: third_party/libaddressinput/chromium/chrome_address_validator.cc

Issue 392083002: Retry downloading rules for libaddressinput. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "third_party/libaddressinput/chromium/chrome_address_validator.h" 5 #include "third_party/libaddressinput/chromium/chrome_address_validator.h"
6 6
7 #include <cstddef> 7 #include <cmath>
8 #include <string>
9 #include <vector>
10 8
11 #include "base/basictypes.h" 9 #include "base/bind.h"
10 #include "base/location.h"
12 #include "base/logging.h" 11 #include "base/logging.h"
13 #include "base/macros.h" 12 #include "base/message_loop/message_loop.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "third_party/libaddressinput/chromium/addressinput_util.h" 13 #include "third_party/libaddressinput/chromium/addressinput_util.h"
16 #include "third_party/libaddressinput/chromium/input_suggester.h" 14 #include "third_party/libaddressinput/chromium/input_suggester.h"
17 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da ta.h" 15 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da ta.h"
18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fi eld.h"
19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_no rmalizer.h" 16 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_no rmalizer.h"
20 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_va lidator.h"
21 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h "
22 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader .h" 17 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/downloader .h"
23 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_su pplier.h"
24 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" 18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
25 19
26 namespace autofill { 20 namespace autofill {
21 namespace {
27 22
28 using ::i18n::addressinput::AddressData; 23 using ::i18n::addressinput::AddressData;
29 using ::i18n::addressinput::AddressField; 24 using ::i18n::addressinput::AddressField;
30 using ::i18n::addressinput::AddressNormalizer; 25 using ::i18n::addressinput::AddressNormalizer;
31 using ::i18n::addressinput::BuildCallback; 26 using ::i18n::addressinput::BuildCallback;
32 using ::i18n::addressinput::Downloader; 27 using ::i18n::addressinput::Downloader;
33 using ::i18n::addressinput::FieldProblemMap; 28 using ::i18n::addressinput::FieldProblemMap;
34 using ::i18n::addressinput::PreloadSupplier; 29 using ::i18n::addressinput::PreloadSupplier;
35 using ::i18n::addressinput::Storage; 30 using ::i18n::addressinput::Storage;
36 31
37 using ::i18n::addressinput::ADMIN_AREA; 32 using ::i18n::addressinput::ADMIN_AREA;
38 using ::i18n::addressinput::DEPENDENT_LOCALITY; 33 using ::i18n::addressinput::DEPENDENT_LOCALITY;
39 using ::i18n::addressinput::POSTAL_CODE; 34 using ::i18n::addressinput::POSTAL_CODE;
40 35
36 // The number of seconds to wait between the first attempt's failure and the
37 // second attempt's initiation to load rules.
38 static const int kRetryPeriodSeconds = 8;
Evan Stade 2014/07/16 23:35:06 inline
please use gerrit instead 2014/07/16 23:45:17 Done.
39
40 // The maximum number attempts to load rules.
41 static const int kMaxAttemptsNumber = 8;
42
43 // The factor of the exponential backoff when retrying to load rules. For
44 // example, a factor of 2 means the third attempt will be delayed by twice as
45 // long as the second attempt to load rules.
46 static const int kBackoffFactor = 2;
Evan Stade 2014/07/16 23:35:06 inline (and the comment is overkill)
please use gerrit instead 2014/07/16 23:45:17 Done.
47
48 } // namespace
49
41 AddressValidator::AddressValidator(const std::string& validation_data_url, 50 AddressValidator::AddressValidator(const std::string& validation_data_url,
42 scoped_ptr<Downloader> downloader, 51 scoped_ptr<Downloader> downloader,
43 scoped_ptr<Storage> storage, 52 scoped_ptr<Storage> storage,
44 LoadRulesListener* load_rules_listener) 53 LoadRulesListener* load_rules_listener)
45 : supplier_(new PreloadSupplier(validation_data_url, 54 : supplier_(new PreloadSupplier(validation_data_url,
46 downloader.release(), 55 downloader.release(),
47 storage.release())), 56 storage.release())),
48 input_suggester_(new InputSuggester(supplier_.get())), 57 input_suggester_(new InputSuggester(supplier_.get())),
49 normalizer_(new AddressNormalizer(supplier_.get())), 58 normalizer_(new AddressNormalizer(supplier_.get())),
50 validator_(new ::i18n::addressinput::AddressValidator(supplier_.get())), 59 validator_(new ::i18n::addressinput::AddressValidator(supplier_.get())),
51 validated_(BuildCallback(this, &AddressValidator::Validated)), 60 validated_(BuildCallback(this, &AddressValidator::Validated)),
52 rules_loaded_(BuildCallback(this, &AddressValidator::RulesLoaded)), 61 rules_loaded_(BuildCallback(this, &AddressValidator::RulesLoaded)),
53 load_rules_listener_(load_rules_listener) {} 62 load_rules_listener_(load_rules_listener),
63 weak_factory_(this) {}
54 64
55 AddressValidator::~AddressValidator() {} 65 AddressValidator::~AddressValidator() {}
56 66
57 void AddressValidator::LoadRules(const std::string& region_code) { 67 void AddressValidator::LoadRules(const std::string& region_code) {
58 DCHECK(supplier_); 68 attempts_number_[region_code] = 0;
59 supplier_->LoadRules(region_code, *rules_loaded_); 69 supplier_->LoadRules(region_code, *rules_loaded_);
60 } 70 }
61 71
62 AddressValidator::Status AddressValidator::ValidateAddress( 72 AddressValidator::Status AddressValidator::ValidateAddress(
63 const AddressData& address, 73 const AddressData& address,
64 const FieldProblemMap* filter, 74 const FieldProblemMap* filter,
65 FieldProblemMap* problems) const { 75 FieldProblemMap* problems) const {
66 DCHECK(supplier_);
67 DCHECK(validator_);
68
69 if (supplier_->IsPending(address.region_code)) { 76 if (supplier_->IsPending(address.region_code)) {
70 if (problems) 77 if (problems)
71 addressinput::ValidateRequiredFields(address, filter, problems); 78 addressinput::ValidateRequiredFields(address, filter, problems);
72 return RULES_NOT_READY; 79 return RULES_NOT_READY;
73 } 80 }
74 81
75 if (!supplier_->IsLoaded(address.region_code)) { 82 if (!supplier_->IsLoaded(address.region_code)) {
76 if (problems) 83 if (problems)
77 addressinput::ValidateRequiredFields(address, filter, problems); 84 addressinput::ValidateRequiredFields(address, filter, problems);
78 return RULES_UNAVAILABLE; 85 return RULES_UNAVAILABLE;
(...skipping 10 matching lines...) Expand all
89 *validated_); 96 *validated_);
90 97
91 return SUCCESS; 98 return SUCCESS;
92 } 99 }
93 100
94 AddressValidator::Status AddressValidator::GetSuggestions( 101 AddressValidator::Status AddressValidator::GetSuggestions(
95 const AddressData& user_input, 102 const AddressData& user_input,
96 AddressField focused_field, 103 AddressField focused_field,
97 size_t suggestion_limit, 104 size_t suggestion_limit,
98 std::vector<AddressData>* suggestions) const { 105 std::vector<AddressData>* suggestions) const {
99 DCHECK(supplier_);
100 DCHECK(input_suggester_);
101
102 if (supplier_->IsPending(user_input.region_code)) 106 if (supplier_->IsPending(user_input.region_code))
103 return RULES_NOT_READY; 107 return RULES_NOT_READY;
104 108
105 if (!supplier_->IsLoaded(user_input.region_code)) 109 if (!supplier_->IsLoaded(user_input.region_code))
106 return RULES_UNAVAILABLE; 110 return RULES_UNAVAILABLE;
107 111
108 if (!suggestions) 112 if (!suggestions)
109 return SUCCESS; 113 return SUCCESS;
110 114
111 suggestions->clear(); 115 suggestions->clear();
112 116
113 if (focused_field == POSTAL_CODE || 117 if (focused_field == POSTAL_CODE ||
114 (focused_field >= ADMIN_AREA && focused_field <= DEPENDENT_LOCALITY)) { 118 (focused_field >= ADMIN_AREA && focused_field <= DEPENDENT_LOCALITY)) {
115 input_suggester_->GetSuggestions( 119 input_suggester_->GetSuggestions(
116 user_input, focused_field, suggestion_limit, suggestions); 120 user_input, focused_field, suggestion_limit, suggestions);
117 } 121 }
118 122
119 return SUCCESS; 123 return SUCCESS;
120 } 124 }
121 125
122 bool AddressValidator::CanonicalizeAdministrativeArea( 126 bool AddressValidator::CanonicalizeAdministrativeArea(
123 AddressData* address) const { 127 AddressData* address) const {
124 DCHECK(address);
125 DCHECK(supplier_);
126 DCHECK(normalizer_);
127
128 if (!supplier_->IsLoaded(address->region_code)) 128 if (!supplier_->IsLoaded(address->region_code))
129 return false; 129 return false;
130 130
131 // TODO: It would probably be beneficial to use the full canonicalization. 131 // TODO: It would probably be beneficial to use the full canonicalization.
132 AddressData tmp(*address); 132 AddressData tmp(*address);
133 normalizer_->Normalize(&tmp); 133 normalizer_->Normalize(&tmp);
134 address->administrative_area = tmp.administrative_area; 134 address->administrative_area = tmp.administrative_area;
135 135
136 return true; 136 return true;
137 } 137 }
138 138
139 AddressValidator::AddressValidator() : load_rules_listener_(NULL) {} 139 AddressValidator::AddressValidator()
140 : load_rules_listener_(NULL), weak_factory_(this) {}
141
142 base::TimeDelta AddressValidator::GetBaseRetryPeriod() const {
143 return base::TimeDelta::FromSeconds(kRetryPeriodSeconds);
144 }
140 145
141 void AddressValidator::Validated(bool success, 146 void AddressValidator::Validated(bool success,
142 const AddressData&, 147 const AddressData&,
143 const FieldProblemMap&) { 148 const FieldProblemMap&) {
144 DCHECK(success); 149 DCHECK(success);
145 } 150 }
146 151
147 void AddressValidator::RulesLoaded(bool success, 152 void AddressValidator::RulesLoaded(bool success,
148 const std::string& country_code, 153 const std::string& region_code,
149 int) { 154 int) {
150 if (load_rules_listener_) 155 if (load_rules_listener_)
151 load_rules_listener_->OnAddressValidationRulesLoaded(country_code, success); 156 load_rules_listener_->OnAddressValidationRulesLoaded(region_code, success);
157
158 // Count the first failed attempt to load rules as well.
159 if (success || attempts_number_[region_code] + 1 >= kMaxAttemptsNumber)
160 return;
161
162 base::MessageLoop::current()->PostDelayedTask(
163 FROM_HERE,
164 base::Bind(&AddressValidator::RetryLoadRules,
165 weak_factory_.GetWeakPtr(),
166 region_code),
167 GetBaseRetryPeriod() *
168 pow(kBackoffFactor, attempts_number_[region_code]++));
169 }
170
171 void AddressValidator::RetryLoadRules(const std::string& region_code) {
172 // Do not reset retry count.
173 supplier_->LoadRules(region_code, *rules_loaded_);
152 } 174 }
153 175
154 } // namespace autofill 176 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698