| 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 |