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

Side by Side Diff: chrome/browser/autocomplete_history_manager.cc

Issue 10843067: Move AutocompleteHistoryManager into chrome/browser/autofill/ as it is (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge to LKGR Created 8 years, 4 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
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/autocomplete_history_manager.h"
6
7 #include <vector>
8
9 #include "base/string16.h"
10 #include "base/string_number_conversions.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/autofill/autofill_external_delegate.h"
13 #include "chrome/browser/autofill/credit_card.h"
14 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/webdata/web_data_service_factory.h"
17 #include "chrome/common/autofill_messages.h"
18 #include "chrome/common/pref_names.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "webkit/forms/form_data.h"
22
23 using base::StringPiece16;
24 using content::WebContents;
25 using webkit::forms::FormData;
26 using webkit::forms::FormField;
27
28 namespace {
29
30 // Limit on the number of suggestions to appear in the pop-up menu under an
31 // text input element in a form.
32 const int kMaxAutocompleteMenuItems = 6;
33
34 // The separator characters for SSNs.
35 const char16 kSSNSeparators[] = {' ', '-', 0};
36
37 bool IsSSN(const string16& text) {
38 string16 number_string;
39 RemoveChars(text, kSSNSeparators, &number_string);
40
41 // A SSN is of the form AAA-GG-SSSS (A = area number, G = group number, S =
42 // serial number). The validation we do here is simply checking if the area,
43 // group, and serial numbers are valid.
44 //
45 // Historically, the area number was assigned per state, with the group number
46 // ascending in an alternating even/odd sequence. With that scheme it was
47 // possible to check for validity by referencing a table that had the highest
48 // group number assigned for a given area number. (This was something that
49 // Chromium never did though, because the "high group" values were constantly
50 // changing.)
51 //
52 // However, starting on 25 June 2011 the SSA began issuing SSNs randomly from
53 // all areas and groups. Group numbers and serial numbers of zero remain
54 // invalid, and areas 000, 666, and 900-999 remain invalid.
55 //
56 // References for current practices:
57 // http://www.socialsecurity.gov/employer/randomization.html
58 // http://www.socialsecurity.gov/employer/randomizationfaqs.html
59 //
60 // References for historic practices:
61 // http://www.socialsecurity.gov/history/ssn/geocard.html
62 // http://www.socialsecurity.gov/employer/stateweb.htm
63 // http://www.socialsecurity.gov/employer/ssnvhighgroup.htm
64
65 if (number_string.length() != 9 || !IsStringASCII(number_string))
66 return false;
67
68 int area;
69 if (!base::StringToInt(StringPiece16(number_string.begin(),
70 number_string.begin() + 3),
71 &area)) {
72 return false;
73 }
74 if (area < 1 ||
75 area == 666 ||
76 area >= 900) {
77 return false;
78 }
79
80 int group;
81 if (!base::StringToInt(StringPiece16(number_string.begin() + 3,
82 number_string.begin() + 5),
83 &group)
84 || group == 0) {
85 return false;
86 }
87
88 int serial;
89 if (!base::StringToInt(StringPiece16(number_string.begin() + 5,
90 number_string.begin() + 9),
91 &serial)
92 || serial == 0) {
93 return false;
94 }
95
96 return true;
97 }
98
99 bool IsTextField(const FormField& field) {
100 return
101 field.form_control_type == ASCIIToUTF16("text") ||
102 field.form_control_type == ASCIIToUTF16("search") ||
103 field.form_control_type == ASCIIToUTF16("tel") ||
104 field.form_control_type == ASCIIToUTF16("url") ||
105 field.form_control_type == ASCIIToUTF16("email") ||
106 field.form_control_type == ASCIIToUTF16("text");
107 }
108
109 } // namespace
110
111 AutocompleteHistoryManager::AutocompleteHistoryManager(
112 WebContents* web_contents)
113 : content::WebContentsObserver(web_contents),
114 pending_query_handle_(0),
115 query_id_(0),
116 external_delegate_(NULL) {
117 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
118 // May be NULL in unit tests.
119 web_data_service_ = WebDataServiceFactory::GetForProfile(
120 profile_, Profile::EXPLICIT_ACCESS);
121 autofill_enabled_.Init(prefs::kAutofillEnabled, profile_->GetPrefs(), NULL);
122 }
123
124 AutocompleteHistoryManager::~AutocompleteHistoryManager() {
125 CancelPendingQuery();
126 }
127
128 bool AutocompleteHistoryManager::OnMessageReceived(
129 const IPC::Message& message) {
130 bool handled = true;
131 IPC_BEGIN_MESSAGE_MAP(AutocompleteHistoryManager, message)
132 IPC_MESSAGE_HANDLER(AutofillHostMsg_RemoveAutocompleteEntry,
133 OnRemoveAutocompleteEntry)
134 IPC_MESSAGE_UNHANDLED(handled = false)
135 IPC_END_MESSAGE_MAP()
136 return handled;
137 }
138
139 void AutocompleteHistoryManager::OnWebDataServiceRequestDone(
140 WebDataService::Handle h,
141 const WDTypedResult* result) {
142 DCHECK(pending_query_handle_);
143 pending_query_handle_ = 0;
144
145 if (!*autofill_enabled_) {
146 SendSuggestions(NULL);
147 return;
148 }
149
150 DCHECK(result);
151 // Returning early here if |result| is NULL. We've seen this happen on
152 // Linux due to NFS dismounting and causing sql failures.
153 // See http://crbug.com/68783.
154 if (!result) {
155 SendSuggestions(NULL);
156 return;
157 }
158
159 DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType());
160 const WDResult<std::vector<string16> >* autofill_result =
161 static_cast<const WDResult<std::vector<string16> >*>(result);
162 std::vector<string16> suggestions = autofill_result->GetValue();
163 SendSuggestions(&suggestions);
164 }
165
166 void AutocompleteHistoryManager::OnGetAutocompleteSuggestions(
167 int query_id,
168 const string16& name,
169 const string16& prefix,
170 const std::vector<string16>& autofill_values,
171 const std::vector<string16>& autofill_labels,
172 const std::vector<string16>& autofill_icons,
173 const std::vector<int>& autofill_unique_ids) {
174 CancelPendingQuery();
175
176 query_id_ = query_id;
177 autofill_values_ = autofill_values;
178 autofill_labels_ = autofill_labels;
179 autofill_icons_ = autofill_icons;
180 autofill_unique_ids_ = autofill_unique_ids;
181 if (!*autofill_enabled_) {
182 SendSuggestions(NULL);
183 return;
184 }
185
186 if (web_data_service_.get()) {
187 pending_query_handle_ = web_data_service_->GetFormValuesForElementName(
188 name, prefix, kMaxAutocompleteMenuItems, this);
189 }
190 }
191
192 void AutocompleteHistoryManager::OnFormSubmitted(const FormData& form) {
193 if (!*autofill_enabled_)
194 return;
195
196 if (profile_->IsOffTheRecord())
197 return;
198
199 // Don't save data that was submitted through JavaScript.
200 if (!form.user_submitted)
201 return;
202
203 // We put the following restriction on stored FormFields:
204 // - non-empty name
205 // - non-empty value
206 // - text field
207 // - value is not a credit card number
208 // - value is not a SSN
209 std::vector<FormField> values;
210 for (std::vector<FormField>::const_iterator iter =
211 form.fields.begin();
212 iter != form.fields.end(); ++iter) {
213 if (!iter->value.empty() &&
214 !iter->name.empty() &&
215 IsTextField(*iter) &&
216 !CreditCard::IsValidCreditCardNumber(iter->value) &&
217 !IsSSN(iter->value)) {
218 values.push_back(*iter);
219 }
220 }
221
222 if (!values.empty() && web_data_service_.get())
223 web_data_service_->AddFormFields(values);
224 }
225
226 void AutocompleteHistoryManager::OnRemoveAutocompleteEntry(
227 const string16& name, const string16& value) {
228 if (web_data_service_.get())
229 web_data_service_->RemoveFormValueForElementName(name, value);
230 }
231
232 void AutocompleteHistoryManager::SetExternalDelegate(
233 AutofillExternalDelegate* delegate) {
234 external_delegate_ = delegate;
235 }
236
237 AutocompleteHistoryManager::AutocompleteHistoryManager(
238 WebContents* web_contents,
239 Profile* profile,
240 WebDataService* wds)
241 : content::WebContentsObserver(web_contents),
242 profile_(profile),
243 web_data_service_(wds),
244 pending_query_handle_(0),
245 query_id_(0),
246 external_delegate_(NULL) {
247 autofill_enabled_.Init(
248 prefs::kAutofillEnabled, profile_->GetPrefs(), NULL);
249 }
250
251 void AutocompleteHistoryManager::CancelPendingQuery() {
252 if (pending_query_handle_) {
253 SendSuggestions(NULL);
254 if (web_data_service_.get())
255 web_data_service_->CancelRequest(pending_query_handle_);
256 pending_query_handle_ = 0;
257 }
258 }
259
260 void AutocompleteHistoryManager::SendSuggestions(
261 const std::vector<string16>* suggestions) {
262 if (suggestions) {
263 // Combine Autofill and Autocomplete values into values and labels.
264 for (size_t i = 0; i < suggestions->size(); ++i) {
265 bool unique = true;
266 for (size_t j = 0; j < autofill_values_.size(); ++j) {
267 // Don't add duplicate values.
268 if (autofill_values_[j] == (*suggestions)[i]) {
269 unique = false;
270 break;
271 }
272 }
273
274 if (unique) {
275 autofill_values_.push_back((*suggestions)[i]);
276 autofill_labels_.push_back(string16());
277 autofill_icons_.push_back(string16());
278 autofill_unique_ids_.push_back(0); // 0 means no profile.
279 }
280 }
281 }
282
283 if (external_delegate_) {
284 external_delegate_->OnSuggestionsReturned(
285 query_id_,
286 autofill_values_,
287 autofill_labels_,
288 autofill_icons_,
289 autofill_unique_ids_);
290 } else {
291 Send(new AutofillMsg_SuggestionsReturned(routing_id(),
292 query_id_,
293 autofill_values_,
294 autofill_labels_,
295 autofill_icons_,
296 autofill_unique_ids_));
297 }
298
299 query_id_ = 0;
300 autofill_values_.clear();
301 autofill_labels_.clear();
302 autofill_icons_.clear();
303 autofill_unique_ids_.clear();
304 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete_history_manager.h ('k') | chrome/browser/autocomplete_history_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698