OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "components/autofill/browser/personal_data_manager.h" | 5 #include "components/autofill/browser/personal_data_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <iterator> | 9 #include <iterator> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "chrome/common/chrome_notification_types.h" | 16 #include "components/autofill/browser/autofill_country.h" |
17 #include "components/autofill/browser/autofill-inl.h" | 17 #include "components/autofill/browser/autofill-inl.h" |
18 #include "components/autofill/browser/autofill_country.h" | |
19 #include "components/autofill/browser/autofill_field.h" | 18 #include "components/autofill/browser/autofill_field.h" |
20 #include "components/autofill/browser/autofill_metrics.h" | 19 #include "components/autofill/browser/autofill_metrics.h" |
21 #include "components/autofill/browser/form_group.h" | 20 #include "components/autofill/browser/form_group.h" |
22 #include "components/autofill/browser/form_structure.h" | 21 #include "components/autofill/browser/form_structure.h" |
23 #include "components/autofill/browser/personal_data_manager_observer.h" | 22 #include "components/autofill/browser/personal_data_manager_observer.h" |
24 #include "components/autofill/browser/phone_number.h" | 23 #include "components/autofill/browser/phone_number.h" |
25 #include "components/autofill/browser/phone_number_i18n.h" | 24 #include "components/autofill/browser/phone_number_i18n.h" |
26 #include "components/autofill/browser/validation.h" | 25 #include "components/autofill/browser/validation.h" |
27 #include "components/autofill/common/autofill_pref_names.h" | 26 #include "components/autofill/common/autofill_pref_names.h" |
28 #include "components/user_prefs/user_prefs.h" | 27 #include "components/user_prefs/user_prefs.h" |
29 #include "components/webdata/autofill/autofill_webdata_service.h" | 28 #include "components/webdata/autofill/autofill_webdata_service.h" |
30 #include "content/public/browser/browser_context.h" | 29 #include "content/public/browser/browser_context.h" |
31 #include "content/public/browser/notification_source.h" | |
32 | 30 |
33 using content::BrowserContext; | 31 using content::BrowserContext; |
34 | 32 |
35 namespace { | 33 namespace { |
36 | 34 |
37 const string16::value_type kCreditCardPrefix[] = {'*', 0}; | 35 const string16::value_type kCreditCardPrefix[] = {'*', 0}; |
38 | 36 |
39 template<typename T> | 37 template<typename T> |
40 class FormGroupMatchesByGUIDFunctor { | 38 class FormGroupMatchesByGUIDFunctor { |
41 public: | 39 public: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 template<typename T> | 73 template<typename T> |
76 T* address_of(T& v) { | 74 T* address_of(T& v) { |
77 return &v; | 75 return &v; |
78 } | 76 } |
79 | 77 |
80 // Returns true if minimum requirements for import of a given |profile| have | 78 // Returns true if minimum requirements for import of a given |profile| have |
81 // been met. An address submitted via a form must have at least the fields | 79 // been met. An address submitted via a form must have at least the fields |
82 // required as determined by its country code. | 80 // required as determined by its country code. |
83 // No verification of validity of the contents is preformed. This is an | 81 // No verification of validity of the contents is preformed. This is an |
84 // existence check only. | 82 // existence check only. |
85 bool IsMinimumAddress(const AutofillProfile& profile) { | 83 bool IsMinimumAddress(const AutofillProfile& profile, |
| 84 const std::string& app_locale) { |
86 // All countries require at least one address line. | 85 // All countries require at least one address line. |
87 if (profile.GetRawInfo(ADDRESS_HOME_LINE1).empty()) | 86 if (profile.GetRawInfo(ADDRESS_HOME_LINE1).empty()) |
88 return false; | 87 return false; |
89 std::string app_locale = AutofillCountry::ApplicationLocale(); | |
90 std::string country_code = | 88 std::string country_code = |
91 UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); | 89 UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); |
92 | 90 |
93 if (country_code.empty()) | 91 if (country_code.empty()) |
94 country_code = AutofillCountry::CountryCodeForLocale(app_locale); | 92 country_code = AutofillCountry::CountryCodeForLocale(app_locale); |
95 | 93 |
96 AutofillCountry country(country_code, app_locale); | 94 AutofillCountry country(country_code, app_locale); |
97 | 95 |
98 if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty()) | 96 if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty()) |
99 return false; | 97 return false; |
(...skipping 23 matching lines...) Expand all Loading... |
123 // Abandon the import if an email address value shows up in a field that is | 121 // Abandon the import if an email address value shows up in a field that is |
124 // not an email address. | 122 // not an email address. |
125 if (field_type != EMAIL_ADDRESS && autofill::IsValidEmailAddress(value)) | 123 if (field_type != EMAIL_ADDRESS && autofill::IsValidEmailAddress(value)) |
126 return false; | 124 return false; |
127 | 125 |
128 return true; | 126 return true; |
129 } | 127 } |
130 | 128 |
131 } // namespace | 129 } // namespace |
132 | 130 |
133 PersonalDataManager::PersonalDataManager() | 131 PersonalDataManager::PersonalDataManager(const std::string& app_locale) |
134 : browser_context_(NULL), | 132 : browser_context_(NULL), |
135 is_data_loaded_(false), | 133 is_data_loaded_(false), |
136 pending_profiles_query_(0), | 134 pending_profiles_query_(0), |
137 pending_creditcards_query_(0), | 135 pending_creditcards_query_(0), |
| 136 app_locale_(app_locale), |
138 metric_logger_(new AutofillMetrics), | 137 metric_logger_(new AutofillMetrics), |
139 has_logged_profile_count_(false) {} | 138 has_logged_profile_count_(false) {} |
140 | 139 |
141 void PersonalDataManager::Init(BrowserContext* browser_context) { | 140 void PersonalDataManager::Init(BrowserContext* browser_context) { |
142 browser_context_ = browser_context; | 141 browser_context_ = browser_context; |
143 metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled()); | 142 metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled()); |
144 | 143 |
145 scoped_refptr<AutofillWebDataService> autofill_data( | 144 scoped_refptr<AutofillWebDataService> autofill_data( |
146 AutofillWebDataService::FromBrowserContext(browser_context_)); | 145 AutofillWebDataService::FromBrowserContext(browser_context_)); |
147 | 146 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 // possible to import. | 230 // possible to import. |
232 int importable_credit_card_fields = 0; | 231 int importable_credit_card_fields = 0; |
233 | 232 |
234 // Detect and discard forms with multiple fields of the same type. | 233 // Detect and discard forms with multiple fields of the same type. |
235 std::set<AutofillFieldType> types_seen; | 234 std::set<AutofillFieldType> types_seen; |
236 | 235 |
237 // We only set complete phone, so aggregate phone parts in these vars and set | 236 // We only set complete phone, so aggregate phone parts in these vars and set |
238 // complete at the end. | 237 // complete at the end. |
239 PhoneNumber::PhoneCombineHelper home; | 238 PhoneNumber::PhoneCombineHelper home; |
240 | 239 |
241 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
242 for (size_t i = 0; i < form.field_count(); ++i) { | 240 for (size_t i = 0; i < form.field_count(); ++i) { |
243 const AutofillField* field = form.field(i); | 241 const AutofillField* field = form.field(i); |
244 string16 value = CollapseWhitespace(field->value, false); | 242 string16 value = CollapseWhitespace(field->value, false); |
245 | 243 |
246 // If we don't know the type of the field, or the user hasn't entered any | 244 // If we don't know the type of the field, or the user hasn't entered any |
247 // information into the field, then skip it. | 245 // information into the field, then skip it. |
248 if (!field->IsFieldFillable() || value.empty()) | 246 if (!field->IsFieldFillable() || value.empty()) |
249 continue; | 247 continue; |
250 | 248 |
251 AutofillFieldType field_type = field->type(); | 249 AutofillFieldType field_type = field->type(); |
252 FieldTypeGroup group(AutofillType(field_type).group()); | 250 FieldTypeGroup group(AutofillType(field_type).group()); |
253 | 251 |
254 // If the |field_type| and |value| don't pass basic validity checks then | 252 // If the |field_type| and |value| don't pass basic validity checks then |
255 // abandon the import. | 253 // abandon the import. |
256 if (!IsValidFieldTypeAndValue(types_seen, field_type, value)) { | 254 if (!IsValidFieldTypeAndValue(types_seen, field_type, value)) { |
257 imported_profile.reset(); | 255 imported_profile.reset(); |
258 local_imported_credit_card.reset(); | 256 local_imported_credit_card.reset(); |
259 break; | 257 break; |
260 } | 258 } |
261 | 259 |
262 types_seen.insert(field_type); | 260 types_seen.insert(field_type); |
263 | 261 |
264 if (group == AutofillType::CREDIT_CARD) { | 262 if (group == AutofillType::CREDIT_CARD) { |
265 if (LowerCaseEqualsASCII(field->form_control_type, "month")) { | 263 if (LowerCaseEqualsASCII(field->form_control_type, "month")) { |
266 DCHECK_EQ(CREDIT_CARD_EXP_MONTH, field_type); | 264 DCHECK_EQ(CREDIT_CARD_EXP_MONTH, field_type); |
267 local_imported_credit_card->SetInfoForMonthInputType(value); | 265 local_imported_credit_card->SetInfoForMonthInputType(value); |
268 } else { | 266 } else { |
269 local_imported_credit_card->SetInfo(field_type, value, app_locale); | 267 local_imported_credit_card->SetInfo(field_type, value, app_locale_); |
270 } | 268 } |
271 ++importable_credit_card_fields; | 269 ++importable_credit_card_fields; |
272 } else { | 270 } else { |
273 // We need to store phone data in the variables, before building the whole | 271 // We need to store phone data in the variables, before building the whole |
274 // number at the end. The rest of the fields are set "as is". | 272 // number at the end. The rest of the fields are set "as is". |
275 // If the fields are not the phone fields in question home.SetInfo() is | 273 // If the fields are not the phone fields in question home.SetInfo() is |
276 // going to return false. | 274 // going to return false. |
277 if (!home.SetInfo(field_type, value)) | 275 if (!home.SetInfo(field_type, value)) |
278 imported_profile->SetInfo(field_type, value, app_locale); | 276 imported_profile->SetInfo(field_type, value, app_locale_); |
279 | 277 |
280 // Reject profiles with invalid country information. | 278 // Reject profiles with invalid country information. |
281 if (field_type == ADDRESS_HOME_COUNTRY && | 279 if (field_type == ADDRESS_HOME_COUNTRY && |
282 !value.empty() && | 280 !value.empty() && |
283 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { | 281 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { |
284 imported_profile.reset(); | 282 imported_profile.reset(); |
285 break; | 283 break; |
286 } | 284 } |
287 } | 285 } |
288 } | 286 } |
289 | 287 |
290 // Construct the phone number. Reject the profile if the number is invalid. | 288 // Construct the phone number. Reject the profile if the number is invalid. |
291 if (imported_profile.get() && !home.IsEmpty()) { | 289 if (imported_profile.get() && !home.IsEmpty()) { |
292 string16 constructed_number; | 290 string16 constructed_number; |
293 if (!home.ParseNumber(*imported_profile, app_locale, &constructed_number) || | 291 if (!home.ParseNumber(*imported_profile, app_locale_, |
| 292 &constructed_number) || |
294 !imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number, | 293 !imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number, |
295 app_locale)) { | 294 app_locale_)) { |
296 imported_profile.reset(); | 295 imported_profile.reset(); |
297 } | 296 } |
298 } | 297 } |
299 | 298 |
300 // Reject the profile if minimum address and validation requirements are not | 299 // Reject the profile if minimum address and validation requirements are not |
301 // met. | 300 // met. |
302 if (imported_profile.get() && !IsValidLearnableProfile(*imported_profile)) | 301 if (imported_profile.get() && |
| 302 !IsValidLearnableProfile(*imported_profile, app_locale_)) |
303 imported_profile.reset(); | 303 imported_profile.reset(); |
304 | 304 |
305 // Reject the credit card if we did not detect enough filled credit card | 305 // Reject the credit card if we did not detect enough filled credit card |
306 // fields or if the credit card number does not seem to be valid. | 306 // fields or if the credit card number does not seem to be valid. |
307 if (local_imported_credit_card.get() && | 307 if (local_imported_credit_card.get() && |
308 !local_imported_credit_card->IsComplete()) { | 308 !local_imported_credit_card->IsComplete()) { |
309 local_imported_credit_card.reset(); | 309 local_imported_credit_card.reset(); |
310 } | 310 } |
311 | 311 |
312 // Don't import if we already have this info. | 312 // Don't import if we already have this info. |
313 // Don't present an infobar if we have already saved this card number. | 313 // Don't present an infobar if we have already saved this card number. |
314 bool merged_credit_card = false; | 314 bool merged_credit_card = false; |
315 if (local_imported_credit_card.get()) { | 315 if (local_imported_credit_card.get()) { |
316 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin(); | 316 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin(); |
317 iter != credit_cards_.end(); | 317 iter != credit_cards_.end(); |
318 ++iter) { | 318 ++iter) { |
319 if ((*iter)->UpdateFromImportedCard(*local_imported_credit_card.get(), | 319 if ((*iter)->UpdateFromImportedCard(*local_imported_credit_card.get(), |
320 app_locale)) { | 320 app_locale_)) { |
321 merged_credit_card = true; | 321 merged_credit_card = true; |
322 UpdateCreditCard(**iter); | 322 UpdateCreditCard(**iter); |
323 local_imported_credit_card.reset(); | 323 local_imported_credit_card.reset(); |
324 break; | 324 break; |
325 } | 325 } |
326 } | 326 } |
327 } | 327 } |
328 | 328 |
329 if (imported_profile.get()) { | 329 if (imported_profile.get()) { |
330 // We always save imported profiles. | 330 // We always save imported profiles. |
331 SaveImportedProfile(*imported_profile); | 331 SaveImportedProfile(*imported_profile); |
332 } | 332 } |
333 *imported_credit_card = local_imported_credit_card.release(); | 333 *imported_credit_card = local_imported_credit_card.release(); |
334 | 334 |
335 if (imported_profile.get() || *imported_credit_card || merged_credit_card) { | 335 if (imported_profile.get() || *imported_credit_card || merged_credit_card) { |
336 return true; | 336 return true; |
337 } else { | 337 } else { |
338 FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_, | 338 FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_, |
339 OnInsufficientFormData()); | 339 OnInsufficientFormData()); |
340 return false; | 340 return false; |
341 } | 341 } |
342 } | 342 } |
343 | 343 |
344 void PersonalDataManager::AddProfile(const AutofillProfile& profile) { | 344 void PersonalDataManager::AddProfile(const AutofillProfile& profile) { |
345 if (browser_context_->IsOffTheRecord()) | 345 if (browser_context_->IsOffTheRecord()) |
346 return; | 346 return; |
347 | 347 |
348 if (profile.IsEmpty()) | 348 if (profile.IsEmpty(app_locale_)) |
349 return; | 349 return; |
350 | 350 |
351 // Don't add an existing profile. | 351 // Don't add an existing profile. |
352 if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid())) | 352 if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid())) |
353 return; | 353 return; |
354 | 354 |
355 scoped_refptr<AutofillWebDataService> autofill_data( | 355 scoped_refptr<AutofillWebDataService> autofill_data( |
356 AutofillWebDataService::FromBrowserContext(browser_context_)); | 356 AutofillWebDataService::FromBrowserContext(browser_context_)); |
357 if (!autofill_data.get()) | 357 if (!autofill_data.get()) |
358 return; | 358 return; |
359 | 359 |
360 // Don't add a duplicate. | 360 // Don't add a duplicate. |
361 if (FindByContents(web_profiles_, profile)) | 361 if (FindByContents(web_profiles_, profile)) |
362 return; | 362 return; |
363 | 363 |
364 // Add the new profile to the web database. | 364 // Add the new profile to the web database. |
365 autofill_data->AddAutofillProfile(profile); | 365 autofill_data->AddAutofillProfile(profile); |
366 | 366 |
367 // Refresh our local cache and send notifications to observers. | 367 // Refresh our local cache and send notifications to observers. |
368 Refresh(); | 368 Refresh(); |
369 } | 369 } |
370 | 370 |
371 void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) { | 371 void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) { |
372 if (browser_context_->IsOffTheRecord()) | 372 if (browser_context_->IsOffTheRecord()) |
373 return; | 373 return; |
374 | 374 |
375 if (!FindByGUID<AutofillProfile>(web_profiles_, profile.guid())) | 375 if (!FindByGUID<AutofillProfile>(web_profiles_, profile.guid())) |
376 return; | 376 return; |
377 | 377 |
378 if (profile.IsEmpty()) { | 378 if (profile.IsEmpty(app_locale_)) { |
379 RemoveByGUID(profile.guid()); | 379 RemoveByGUID(profile.guid()); |
380 return; | 380 return; |
381 } | 381 } |
382 | 382 |
383 scoped_refptr<AutofillWebDataService> autofill_data( | 383 scoped_refptr<AutofillWebDataService> autofill_data( |
384 AutofillWebDataService::FromBrowserContext(browser_context_)); | 384 AutofillWebDataService::FromBrowserContext(browser_context_)); |
385 if (!autofill_data.get()) | 385 if (!autofill_data.get()) |
386 return; | 386 return; |
387 | 387 |
388 // Make the update. | 388 // Make the update. |
(...skipping 11 matching lines...) Expand all Loading... |
400 if ((*iter)->guid() == guid) | 400 if ((*iter)->guid() == guid) |
401 return *iter; | 401 return *iter; |
402 } | 402 } |
403 return NULL; | 403 return NULL; |
404 } | 404 } |
405 | 405 |
406 void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) { | 406 void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) { |
407 if (browser_context_->IsOffTheRecord()) | 407 if (browser_context_->IsOffTheRecord()) |
408 return; | 408 return; |
409 | 409 |
410 if (credit_card.IsEmpty()) | 410 if (credit_card.IsEmpty(app_locale_)) |
411 return; | 411 return; |
412 | 412 |
413 if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid())) | 413 if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid())) |
414 return; | 414 return; |
415 | 415 |
416 scoped_refptr<AutofillWebDataService> autofill_data( | 416 scoped_refptr<AutofillWebDataService> autofill_data( |
417 AutofillWebDataService::FromBrowserContext(browser_context_)); | 417 AutofillWebDataService::FromBrowserContext(browser_context_)); |
418 if (!autofill_data.get()) | 418 if (!autofill_data.get()) |
419 return; | 419 return; |
420 | 420 |
421 // Don't add a duplicate. | 421 // Don't add a duplicate. |
422 if (FindByContents(credit_cards_, credit_card)) | 422 if (FindByContents(credit_cards_, credit_card)) |
423 return; | 423 return; |
424 | 424 |
425 // Add the new credit card to the web database. | 425 // Add the new credit card to the web database. |
426 autofill_data->AddCreditCard(credit_card); | 426 autofill_data->AddCreditCard(credit_card); |
427 | 427 |
428 // Refresh our local cache and send notifications to observers. | 428 // Refresh our local cache and send notifications to observers. |
429 Refresh(); | 429 Refresh(); |
430 } | 430 } |
431 | 431 |
432 void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) { | 432 void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) { |
433 if (browser_context_->IsOffTheRecord()) | 433 if (browser_context_->IsOffTheRecord()) |
434 return; | 434 return; |
435 | 435 |
436 if (!FindByGUID<CreditCard>(credit_cards_, credit_card.guid())) | 436 if (!FindByGUID<CreditCard>(credit_cards_, credit_card.guid())) |
437 return; | 437 return; |
438 | 438 |
439 if (credit_card.IsEmpty()) { | 439 if (credit_card.IsEmpty(app_locale_)) { |
440 RemoveByGUID(credit_card.guid()); | 440 RemoveByGUID(credit_card.guid()); |
441 return; | 441 return; |
442 } | 442 } |
443 | 443 |
444 scoped_refptr<AutofillWebDataService> autofill_data( | 444 scoped_refptr<AutofillWebDataService> autofill_data( |
445 AutofillWebDataService::FromBrowserContext(browser_context_)); | 445 AutofillWebDataService::FromBrowserContext(browser_context_)); |
446 if (!autofill_data.get()) | 446 if (!autofill_data.get()) |
447 return; | 447 return; |
448 | 448 |
449 // Make the update. | 449 // Make the update. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 for (std::vector<CreditCard*>::iterator iter = credit_cards_.begin(); | 481 for (std::vector<CreditCard*>::iterator iter = credit_cards_.begin(); |
482 iter != credit_cards_.end(); ++iter) { | 482 iter != credit_cards_.end(); ++iter) { |
483 if ((*iter)->guid() == guid) | 483 if ((*iter)->guid() == guid) |
484 return *iter; | 484 return *iter; |
485 } | 485 } |
486 return NULL; | 486 return NULL; |
487 } | 487 } |
488 | 488 |
489 void PersonalDataManager::GetNonEmptyTypes( | 489 void PersonalDataManager::GetNonEmptyTypes( |
490 FieldTypeSet* non_empty_types) { | 490 FieldTypeSet* non_empty_types) { |
491 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
492 const std::vector<AutofillProfile*>& profiles = GetProfiles(); | 491 const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
493 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); | 492 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); |
494 iter != profiles.end(); ++iter) { | 493 iter != profiles.end(); ++iter) { |
495 (*iter)->GetNonEmptyTypes(app_locale, non_empty_types); | 494 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); |
496 } | 495 } |
497 | 496 |
498 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin(); | 497 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin(); |
499 iter != credit_cards_.end(); ++iter) { | 498 iter != credit_cards_.end(); ++iter) { |
500 (*iter)->GetNonEmptyTypes(app_locale, non_empty_types); | 499 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); |
501 } | 500 } |
502 } | 501 } |
503 | 502 |
504 bool PersonalDataManager::IsDataLoaded() const { | 503 bool PersonalDataManager::IsDataLoaded() const { |
505 return is_data_loaded_; | 504 return is_data_loaded_; |
506 } | 505 } |
507 | 506 |
508 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() { | 507 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() { |
509 if (!components::UserPrefs::Get(browser_context_)->GetBoolean( | 508 if (!components::UserPrefs::Get(browser_context_)->GetBoolean( |
510 prefs::kAutofillAuxiliaryProfilesEnabled)) { | 509 prefs::kAutofillAuxiliaryProfilesEnabled)) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 std::vector<string16>* values, | 542 std::vector<string16>* values, |
544 std::vector<string16>* labels, | 543 std::vector<string16>* labels, |
545 std::vector<string16>* icons, | 544 std::vector<string16>* icons, |
546 std::vector<GUIDPair>* guid_pairs) { | 545 std::vector<GUIDPair>* guid_pairs) { |
547 values->clear(); | 546 values->clear(); |
548 labels->clear(); | 547 labels->clear(); |
549 icons->clear(); | 548 icons->clear(); |
550 guid_pairs->clear(); | 549 guid_pairs->clear(); |
551 | 550 |
552 const std::vector<AutofillProfile*>& profiles = GetProfiles(); | 551 const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
553 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
554 std::vector<AutofillProfile*> matched_profiles; | 552 std::vector<AutofillProfile*> matched_profiles; |
555 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); | 553 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); |
556 iter != profiles.end(); ++iter) { | 554 iter != profiles.end(); ++iter) { |
557 AutofillProfile* profile = *iter; | 555 AutofillProfile* profile = *iter; |
558 | 556 |
559 // The value of the stored data for this field type in the |profile|. | 557 // The value of the stored data for this field type in the |profile|. |
560 std::vector<string16> multi_values; | 558 std::vector<string16> multi_values; |
561 profile->GetMultiInfo(type, app_locale, &multi_values); | 559 profile->GetMultiInfo(type, app_locale_, &multi_values); |
562 | 560 |
563 for (size_t i = 0; i < multi_values.size(); ++i) { | 561 for (size_t i = 0; i < multi_values.size(); ++i) { |
564 if (!field_is_autofilled) { | 562 if (!field_is_autofilled) { |
565 // Suggest data that starts with what the user has typed. | 563 // Suggest data that starts with what the user has typed. |
566 if (!multi_values[i].empty() && | 564 if (!multi_values[i].empty() && |
567 StartsWith(multi_values[i], field_contents, false)) { | 565 StartsWith(multi_values[i], field_contents, false)) { |
568 matched_profiles.push_back(profile); | 566 matched_profiles.push_back(profile); |
569 values->push_back(multi_values[i]); | 567 values->push_back(multi_values[i]); |
570 guid_pairs->push_back(GUIDPair(profile->guid(), i)); | 568 guid_pairs->push_back(GUIDPair(profile->guid(), i)); |
571 } | 569 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 icons->resize(values->size()); | 614 icons->resize(values->size()); |
617 } | 615 } |
618 | 616 |
619 void PersonalDataManager::GetCreditCardSuggestions( | 617 void PersonalDataManager::GetCreditCardSuggestions( |
620 AutofillFieldType type, | 618 AutofillFieldType type, |
621 const string16& field_contents, | 619 const string16& field_contents, |
622 std::vector<string16>* values, | 620 std::vector<string16>* values, |
623 std::vector<string16>* labels, | 621 std::vector<string16>* labels, |
624 std::vector<string16>* icons, | 622 std::vector<string16>* icons, |
625 std::vector<GUIDPair>* guid_pairs) { | 623 std::vector<GUIDPair>* guid_pairs) { |
626 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
627 for (std::vector<CreditCard*>::const_iterator iter = credit_cards().begin(); | 624 for (std::vector<CreditCard*>::const_iterator iter = credit_cards().begin(); |
628 iter != credit_cards().end(); ++iter) { | 625 iter != credit_cards().end(); ++iter) { |
629 CreditCard* credit_card = *iter; | 626 CreditCard* credit_card = *iter; |
630 | 627 |
631 // The value of the stored data for this field type in the |credit_card|. | 628 // The value of the stored data for this field type in the |credit_card|. |
632 string16 creditcard_field_value = credit_card->GetInfo(type, app_locale); | 629 string16 creditcard_field_value = credit_card->GetInfo(type, app_locale_); |
633 if (!creditcard_field_value.empty() && | 630 if (!creditcard_field_value.empty() && |
634 StartsWith(creditcard_field_value, field_contents, false)) { | 631 StartsWith(creditcard_field_value, field_contents, false)) { |
635 if (type == CREDIT_CARD_NUMBER) | 632 if (type == CREDIT_CARD_NUMBER) |
636 creditcard_field_value = credit_card->ObfuscatedNumber(); | 633 creditcard_field_value = credit_card->ObfuscatedNumber(); |
637 | 634 |
638 string16 label; | 635 string16 label; |
639 if (credit_card->number().empty()) { | 636 if (credit_card->number().empty()) { |
640 // If there is no CC number, return name to show something. | 637 // If there is no CC number, return name to show something. |
641 label = credit_card->GetInfo(CREDIT_CARD_NAME, app_locale); | 638 label = credit_card->GetInfo(CREDIT_CARD_NAME, app_locale_); |
642 } else { | 639 } else { |
643 label = kCreditCardPrefix; | 640 label = kCreditCardPrefix; |
644 label.append(credit_card->LastFourDigits()); | 641 label.append(credit_card->LastFourDigits()); |
645 } | 642 } |
646 | 643 |
647 values->push_back(creditcard_field_value); | 644 values->push_back(creditcard_field_value); |
648 labels->push_back(label); | 645 labels->push_back(label); |
649 icons->push_back(UTF8ToUTF16(credit_card->type())); | 646 icons->push_back(UTF8ToUTF16(credit_card->type())); |
650 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); | 647 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); |
651 } | 648 } |
652 } | 649 } |
653 } | 650 } |
654 | 651 |
655 bool PersonalDataManager::IsAutofillEnabled() const { | 652 bool PersonalDataManager::IsAutofillEnabled() const { |
656 return components::UserPrefs::Get(browser_context_)->GetBoolean( | 653 return components::UserPrefs::Get(browser_context_)->GetBoolean( |
657 prefs::kAutofillEnabled); | 654 prefs::kAutofillEnabled); |
658 } | 655 } |
659 | 656 |
660 // static | 657 // static |
661 bool PersonalDataManager::IsValidLearnableProfile( | 658 bool PersonalDataManager::IsValidLearnableProfile( |
662 const AutofillProfile& profile) { | 659 const AutofillProfile& profile, |
663 if (!IsMinimumAddress(profile)) | 660 const std::string& app_locale) { |
| 661 if (!IsMinimumAddress(profile, app_locale)) |
664 return false; | 662 return false; |
665 | 663 |
666 string16 email = profile.GetRawInfo(EMAIL_ADDRESS); | 664 string16 email = profile.GetRawInfo(EMAIL_ADDRESS); |
667 if (!email.empty() && !autofill::IsValidEmailAddress(email)) | 665 if (!email.empty() && !autofill::IsValidEmailAddress(email)) |
668 return false; | 666 return false; |
669 | 667 |
670 // Reject profiles with invalid US state information. | 668 // Reject profiles with invalid US state information. |
671 string16 state = profile.GetRawInfo(ADDRESS_HOME_STATE); | 669 string16 state = profile.GetRawInfo(ADDRESS_HOME_STATE); |
672 if (profile.GetRawInfo(ADDRESS_HOME_COUNTRY) == ASCIIToUTF16("US") && | 670 if (profile.GetRawInfo(ADDRESS_HOME_COUNTRY) == ASCIIToUTF16("US") && |
673 !state.empty() && !FormGroup::IsValidState(state)) { | 671 !state.empty() && !FormGroup::IsValidState(state)) { |
674 return false; | 672 return false; |
675 } | 673 } |
676 | 674 |
677 // Reject profiles with invalid US zip information. | 675 // Reject profiles with invalid US zip information. |
678 string16 zip = profile.GetRawInfo(ADDRESS_HOME_ZIP); | 676 string16 zip = profile.GetRawInfo(ADDRESS_HOME_ZIP); |
679 if (profile.GetRawInfo(ADDRESS_HOME_COUNTRY) == ASCIIToUTF16("US") && | 677 if (profile.GetRawInfo(ADDRESS_HOME_COUNTRY) == ASCIIToUTF16("US") && |
680 !zip.empty() && !autofill::IsValidZip(zip)) | 678 !zip.empty() && !autofill::IsValidZip(zip)) |
681 return false; | 679 return false; |
682 | 680 |
683 return true; | 681 return true; |
684 } | 682 } |
685 | 683 |
686 // static | 684 // static |
687 bool PersonalDataManager::MergeProfile( | 685 bool PersonalDataManager::MergeProfile( |
688 const AutofillProfile& profile, | 686 const AutofillProfile& profile, |
689 const std::vector<AutofillProfile*>& existing_profiles, | 687 const std::vector<AutofillProfile*>& existing_profiles, |
| 688 const std::string& app_locale, |
690 std::vector<AutofillProfile>* merged_profiles) { | 689 std::vector<AutofillProfile>* merged_profiles) { |
691 merged_profiles->clear(); | 690 merged_profiles->clear(); |
692 | 691 |
693 // Set to true if |profile| is merged into |existing_profiles|. | 692 // Set to true if |profile| is merged into |existing_profiles|. |
694 bool merged = false; | 693 bool merged = false; |
695 | 694 |
696 // If we have already saved this address, merge in any missing values. | 695 // If we have already saved this address, merge in any missing values. |
697 // Only merge with the first match. | 696 // Only merge with the first match. |
698 for (std::vector<AutofillProfile*>::const_iterator iter = | 697 for (std::vector<AutofillProfile*>::const_iterator iter = |
699 existing_profiles.begin(); | 698 existing_profiles.begin(); |
700 iter != existing_profiles.end(); ++iter) { | 699 iter != existing_profiles.end(); ++iter) { |
701 if (!merged) { | 700 if (!merged) { |
702 if (!profile.PrimaryValue().empty() && | 701 if (!profile.PrimaryValue().empty() && |
703 StringToLowerASCII((*iter)->PrimaryValue()) == | 702 StringToLowerASCII((*iter)->PrimaryValue()) == |
704 StringToLowerASCII(profile.PrimaryValue())) { | 703 StringToLowerASCII(profile.PrimaryValue())) { |
705 merged = true; | 704 merged = true; |
706 (*iter)->OverwriteWithOrAddTo(profile); | 705 (*iter)->OverwriteWithOrAddTo(profile, app_locale); |
707 } | 706 } |
708 } | 707 } |
709 merged_profiles->push_back(**iter); | 708 merged_profiles->push_back(**iter); |
710 } | 709 } |
711 | 710 |
712 // If the new profile was not merged with an existing one, add it to the list. | 711 // If the new profile was not merged with an existing one, add it to the list. |
713 if (!merged) | 712 if (!merged) |
714 merged_profiles->push_back(profile); | 713 merged_profiles->push_back(profile); |
715 | 714 |
716 return merged; | 715 return merged; |
717 } | 716 } |
718 | 717 |
719 void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) { | 718 void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) { |
720 if (browser_context_->IsOffTheRecord()) | 719 if (browser_context_->IsOffTheRecord()) |
721 return; | 720 return; |
722 | 721 |
723 // Remove empty profiles from input. | 722 // Remove empty profiles from input. |
724 profiles->erase( | 723 for (std::vector<AutofillProfile>::iterator it = profiles->begin(); |
725 std::remove_if(profiles->begin(), profiles->end(), | 724 it != profiles->end();) { |
726 std::mem_fun_ref(&AutofillProfile::IsEmpty)), | 725 if (it->IsEmpty(app_locale_)) |
727 profiles->end()); | 726 profiles->erase(it); |
| 727 else |
| 728 it++; |
| 729 } |
728 | 730 |
729 // Ensure that profile labels are up to date. Currently, sync relies on | 731 // Ensure that profile labels are up to date. Currently, sync relies on |
730 // labels to identify a profile. | 732 // labels to identify a profile. |
731 // TODO(dhollowa): We need to deprecate labels and update the way sync | 733 // TODO(dhollowa): We need to deprecate labels and update the way sync |
732 // identifies profiles. | 734 // identifies profiles. |
733 std::vector<AutofillProfile*> profile_pointers(profiles->size()); | 735 std::vector<AutofillProfile*> profile_pointers(profiles->size()); |
734 std::transform(profiles->begin(), profiles->end(), profile_pointers.begin(), | 736 std::transform(profiles->begin(), profiles->end(), profile_pointers.begin(), |
735 address_of<AutofillProfile>); | 737 address_of<AutofillProfile>); |
736 AutofillProfile::AdjustInferredLabels(&profile_pointers); | 738 AutofillProfile::AdjustInferredLabels(&profile_pointers); |
737 | 739 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 // Refresh our local cache and send notifications to observers. | 776 // Refresh our local cache and send notifications to observers. |
775 Refresh(); | 777 Refresh(); |
776 } | 778 } |
777 | 779 |
778 void PersonalDataManager::SetCreditCards( | 780 void PersonalDataManager::SetCreditCards( |
779 std::vector<CreditCard>* credit_cards) { | 781 std::vector<CreditCard>* credit_cards) { |
780 if (browser_context_->IsOffTheRecord()) | 782 if (browser_context_->IsOffTheRecord()) |
781 return; | 783 return; |
782 | 784 |
783 // Remove empty credit cards from input. | 785 // Remove empty credit cards from input. |
784 credit_cards->erase( | 786 for (std::vector<CreditCard>::iterator it = credit_cards->begin(); |
785 std::remove_if( | 787 it != credit_cards->end();) { |
786 credit_cards->begin(), credit_cards->end(), | 788 if (it->IsEmpty(app_locale_)) |
787 std::mem_fun_ref(&CreditCard::IsEmpty)), | 789 credit_cards->erase(it); |
788 credit_cards->end()); | 790 else |
| 791 it++; |
| 792 } |
789 | 793 |
790 scoped_refptr<AutofillWebDataService> autofill_data( | 794 scoped_refptr<AutofillWebDataService> autofill_data( |
791 AutofillWebDataService::FromBrowserContext(browser_context_)); | 795 AutofillWebDataService::FromBrowserContext(browser_context_)); |
792 if (!autofill_data.get()) | 796 if (!autofill_data.get()) |
793 return; | 797 return; |
794 | 798 |
795 // Any credit cards that are not in the new credit card list should be | 799 // Any credit cards that are not in the new credit card list should be |
796 // removed. | 800 // removed. |
797 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin(); | 801 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin(); |
798 iter != credit_cards_.end(); ++iter) { | 802 iter != credit_cards_.end(); ++iter) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 // upon form submission. | 920 // upon form submission. |
917 NOTREACHED(); | 921 NOTREACHED(); |
918 return; | 922 return; |
919 } | 923 } |
920 | 924 |
921 // Don't save a web profile if the data in the profile is a subset of an | 925 // Don't save a web profile if the data in the profile is a subset of an |
922 // auxiliary profile. | 926 // auxiliary profile. |
923 for (std::vector<AutofillProfile*>::const_iterator iter = | 927 for (std::vector<AutofillProfile*>::const_iterator iter = |
924 auxiliary_profiles_.begin(); | 928 auxiliary_profiles_.begin(); |
925 iter != auxiliary_profiles_.end(); ++iter) { | 929 iter != auxiliary_profiles_.end(); ++iter) { |
926 if (imported_profile.IsSubsetOf(**iter)) | 930 if (imported_profile.IsSubsetOf(**iter, app_locale_)) |
927 return; | 931 return; |
928 } | 932 } |
929 | 933 |
930 std::vector<AutofillProfile> profiles; | 934 std::vector<AutofillProfile> profiles; |
931 MergeProfile(imported_profile, web_profiles_.get(), &profiles); | 935 MergeProfile(imported_profile, web_profiles_.get(), app_locale_, &profiles); |
932 SetProfiles(&profiles); | 936 SetProfiles(&profiles); |
933 } | 937 } |
934 | 938 |
935 | 939 |
936 void PersonalDataManager::SaveImportedCreditCard( | 940 void PersonalDataManager::SaveImportedCreditCard( |
937 const CreditCard& imported_card) { | 941 const CreditCard& imported_card) { |
938 DCHECK(!imported_card.number().empty()); | 942 DCHECK(!imported_card.number().empty()); |
939 if (browser_context_->IsOffTheRecord()) { | 943 if (browser_context_->IsOffTheRecord()) { |
940 // The |IsOffTheRecord| check should happen earlier in the import process, | 944 // The |IsOffTheRecord| check should happen earlier in the import process, |
941 // upon form submission. | 945 // upon form submission. |
942 NOTREACHED(); | 946 NOTREACHED(); |
943 return; | 947 return; |
944 } | 948 } |
945 | 949 |
946 // Set to true if |imported_card| is merged into the credit card list. | 950 // Set to true if |imported_card| is merged into the credit card list. |
947 bool merged = false; | 951 bool merged = false; |
948 | 952 |
949 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
950 std::vector<CreditCard> credit_cards; | 953 std::vector<CreditCard> credit_cards; |
951 for (std::vector<CreditCard*>::const_iterator card = credit_cards_.begin(); | 954 for (std::vector<CreditCard*>::const_iterator card = credit_cards_.begin(); |
952 card != credit_cards_.end(); | 955 card != credit_cards_.end(); |
953 ++card) { | 956 ++card) { |
954 // If |imported_card| has not yet been merged, check whether it should be | 957 // If |imported_card| has not yet been merged, check whether it should be |
955 // with the current |card|. | 958 // with the current |card|. |
956 if (!merged && (*card)->UpdateFromImportedCard(imported_card, app_locale)) | 959 if (!merged && (*card)->UpdateFromImportedCard(imported_card, app_locale_)) |
957 merged = true; | 960 merged = true; |
958 | 961 |
959 credit_cards.push_back(**card); | 962 credit_cards.push_back(**card); |
960 } | 963 } |
961 | 964 |
962 if (!merged) | 965 if (!merged) |
963 credit_cards.push_back(imported_card); | 966 credit_cards.push_back(imported_card); |
964 | 967 |
965 SetCreditCards(&credit_cards); | 968 SetCreditCards(&credit_cards); |
966 } | 969 } |
(...skipping 11 matching lines...) Expand all Loading... |
978 | 981 |
979 void PersonalDataManager::set_metric_logger( | 982 void PersonalDataManager::set_metric_logger( |
980 const AutofillMetrics* metric_logger) { | 983 const AutofillMetrics* metric_logger) { |
981 metric_logger_.reset(metric_logger); | 984 metric_logger_.reset(metric_logger); |
982 } | 985 } |
983 | 986 |
984 void PersonalDataManager::set_browser_context( | 987 void PersonalDataManager::set_browser_context( |
985 content::BrowserContext* context) { | 988 content::BrowserContext* context) { |
986 browser_context_ = context; | 989 browser_context_ = context; |
987 } | 990 } |
OLD | NEW |