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/ui/webui/options/autofill_options_handler.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/bind_helpers.h" 11 #include "base/guid.h" 12 #include "base/logging.h" 13 #include "base/strings/string16.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "base/values.h" 17 #include "chrome/browser/autofill/personal_data_manager_factory.h" 18 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/ui/autofill/country_combobox_model.h" 21 #include "chrome/common/url_constants.h" 22 #include "components/autofill/core/browser/autofill_country.h" 23 #include "components/autofill/core/browser/autofill_profile.h" 24 #include "components/autofill/core/browser/credit_card.h" 25 #include "components/autofill/core/browser/personal_data_manager.h" 26 #include "components/autofill/core/browser/phone_number_i18n.h" 27 #include "components/autofill/core/common/autofill_constants.h" 28 #include "content/public/browser/web_ui.h" 29 #include "grit/components_strings.h" 30 #include "grit/generated_resources.h" 31 #include "grit/libaddressinput_strings.h" 32 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h" 33 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui_component.h" 34 #include "ui/base/l10n/l10n_util.h" 35 #include "ui/base/webui/web_ui_util.h" 36 37 using autofill::AutofillCountry; 38 using autofill::ServerFieldType; 39 using autofill::AutofillProfile; 40 using autofill::CreditCard; 41 using autofill::PersonalDataManager; 42 using i18n::addressinput::AddressUiComponent; 43 44 namespace { 45 46 const char kSettingsOrigin[] = "Chrome settings"; 47 48 static const char kFullNameField[] = "fullName"; 49 static const char kCompanyNameField[] = "companyName"; 50 static const char kAddressLineField[] = "addrLines"; 51 static const char kDependentLocalityField[] = "dependentLocality"; 52 static const char kCityField[] = "city"; 53 static const char kStateField[] = "state"; 54 static const char kPostalCodeField[] = "postalCode"; 55 static const char kSortingCodeField[] = "sortingCode"; 56 static const char kCountryField[] = "country"; 57 58 static const char kComponents[] = "components"; 59 static const char kLanguageCode[] = "languageCode"; 60 61 // Fills |components| with the address UI components that should be used to 62 // input an address for |country_code| when UI BCP 47 language code is 63 // |ui_language_code|. If |components_language_code| is not NULL, then sets it 64 // to the BCP 47 language code that should be used to format the address for 65 // display. 66 void GetAddressComponents(const std::string& country_code, 67 const std::string& ui_language_code, 68 base::ListValue* address_components, 69 std::string* components_language_code) { 70 DCHECK(address_components); 71 72 std::vector<AddressUiComponent> components = 73 i18n::addressinput::BuildComponents( 74 country_code, ui_language_code, components_language_code); 75 if (components.empty()) { 76 static const char kDefaultCountryCode[] = "US"; 77 components = i18n::addressinput::BuildComponents( 78 kDefaultCountryCode, ui_language_code, components_language_code); 79 } 80 DCHECK(!components.empty()); 81 82 base::ListValue* line = NULL; 83 static const char kField[] = "field"; 84 static const char kLength[] = "length"; 85 for (size_t i = 0; i < components.size(); ++i) { 86 if (i == 0 || 87 components[i - 1].length_hint == AddressUiComponent::HINT_LONG || 88 components[i].length_hint == AddressUiComponent::HINT_LONG) { 89 line = new base::ListValue; 90 address_components->Append(line); 91 } 92 93 scoped_ptr<base::DictionaryValue> component(new base::DictionaryValue); 94 component->SetString( 95 "name", l10n_util::GetStringUTF16(components[i].name_id)); 96 97 switch (components[i].field) { 98 case i18n::addressinput::COUNTRY: 99 component->SetString(kField, kCountryField); 100 break; 101 case i18n::addressinput::ADMIN_AREA: 102 component->SetString(kField, kStateField); 103 break; 104 case i18n::addressinput::LOCALITY: 105 component->SetString(kField, kCityField); 106 break; 107 case i18n::addressinput::DEPENDENT_LOCALITY: 108 component->SetString(kField, kDependentLocalityField); 109 break; 110 case i18n::addressinput::SORTING_CODE: 111 component->SetString(kField, kSortingCodeField); 112 break; 113 case i18n::addressinput::POSTAL_CODE: 114 component->SetString(kField, kPostalCodeField); 115 break; 116 case i18n::addressinput::STREET_ADDRESS: 117 component->SetString(kField, kAddressLineField); 118 break; 119 case i18n::addressinput::ORGANIZATION: 120 component->SetString(kField, kCompanyNameField); 121 break; 122 case i18n::addressinput::RECIPIENT: 123 component->SetString(kField, kFullNameField); 124 component->SetString( 125 "placeholder", 126 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME)); 127 break; 128 } 129 130 switch (components[i].length_hint) { 131 case AddressUiComponent::HINT_LONG: 132 component->SetString(kLength, "long"); 133 break; 134 case AddressUiComponent::HINT_SHORT: 135 component->SetString(kLength, "short"); 136 break; 137 } 138 139 line->Append(component.release()); 140 } 141 } 142 143 // Sets data related to the country <select>. 144 void SetCountryData(const PersonalDataManager& manager, 145 base::DictionaryValue* localized_strings) { 146 autofill::CountryComboboxModel model( 147 manager, base::Callback<bool(const std::string&)>()); 148 const std::vector<AutofillCountry*>& countries = model.countries(); 149 localized_strings->SetString("defaultCountryCode", 150 countries.front()->country_code()); 151 152 // An ordered list of options to show in the <select>. 153 scoped_ptr<base::ListValue> country_list(new base::ListValue()); 154 for (size_t i = 0; i < countries.size(); ++i) { 155 scoped_ptr<base::DictionaryValue> option_details( 156 new base::DictionaryValue()); 157 option_details->SetString("name", model.GetItemAt(i)); 158 option_details->SetString( 159 "value", 160 countries[i] ? countries[i]->country_code() : "separator"); 161 country_list->Append(option_details.release()); 162 } 163 localized_strings->Set("autofillCountrySelectList", country_list.release()); 164 165 scoped_ptr<base::ListValue> default_country_components(new base::ListValue); 166 std::string default_country_language_code; 167 GetAddressComponents(countries.front()->country_code(), 168 g_browser_process->GetApplicationLocale(), 169 default_country_components.get(), 170 &default_country_language_code); 171 localized_strings->Set("autofillDefaultCountryComponents", 172 default_country_components.release()); 173 localized_strings->SetString("autofillDefaultCountryLanguageCode", 174 default_country_language_code); 175 } 176 177 // Get the multi-valued element for |type| and return it in |ListValue| form. 178 void GetValueList(const AutofillProfile& profile, 179 ServerFieldType type, 180 scoped_ptr<base::ListValue>* list) { 181 list->reset(new base::ListValue); 182 183 std::vector<base::string16> values; 184 profile.GetRawMultiInfo(type, &values); 185 186 // |GetRawMultiInfo()| always returns at least one, potentially empty, item. 187 if (values.size() == 1 && values.front().empty()) 188 return; 189 190 for (size_t i = 0; i < values.size(); ++i) { 191 (*list)->Set(i, new base::StringValue(values[i])); 192 } 193 } 194 195 // Set the multi-valued element for |type| from input |list| values. 196 void SetValueList(const base::ListValue* list, 197 ServerFieldType type, 198 AutofillProfile* profile) { 199 std::vector<base::string16> values(list->GetSize()); 200 for (size_t i = 0; i < list->GetSize(); ++i) { 201 base::string16 value; 202 if (list->GetString(i, &value)) 203 values[i] = value; 204 } 205 profile->SetRawMultiInfo(type, values); 206 } 207 208 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from 209 // the |args| input. 210 void ExtractPhoneNumberInformation(const base::ListValue* args, 211 size_t* index, 212 const base::ListValue** phone_number_list, 213 std::string* country_code) { 214 // Retrieve index as a |double|, as that is how it comes across from 215 // JavaScript. 216 double number = 0.0; 217 if (!args->GetDouble(0, &number)) { 218 NOTREACHED(); 219 return; 220 } 221 *index = number; 222 223 if (!args->GetList(1, phone_number_list)) { 224 NOTREACHED(); 225 return; 226 } 227 228 if (!args->GetString(2, country_code)) { 229 NOTREACHED(); 230 return; 231 } 232 } 233 234 // Searches the |list| for the value at |index|. If this value is present 235 // in any of the rest of the list, then the item (at |index|) is removed. 236 // The comparison of phone number values is done on normalized versions of the 237 // phone number values. 238 void RemoveDuplicatePhoneNumberAtIndex(size_t index, 239 const std::string& country_code, 240 base::ListValue* list) { 241 base::string16 new_value; 242 if (!list->GetString(index, &new_value)) { 243 NOTREACHED() << "List should have a value at index " << index; 244 return; 245 } 246 247 bool is_duplicate = false; 248 std::string app_locale = g_browser_process->GetApplicationLocale(); 249 for (size_t i = 0; i < list->GetSize() && !is_duplicate; ++i) { 250 if (i == index) 251 continue; 252 253 base::string16 existing_value; 254 if (!list->GetString(i, &existing_value)) { 255 NOTREACHED() << "List should have a value at index " << i; 256 continue; 257 } 258 is_duplicate = autofill::i18n::PhoneNumbersMatch( 259 new_value, existing_value, country_code, app_locale); 260 } 261 262 if (is_duplicate) 263 list->Remove(index, NULL); 264 } 265 266 scoped_ptr<base::ListValue> ValidatePhoneArguments( 267 const base::ListValue* args) { 268 size_t index = 0; 269 std::string country_code; 270 const base::ListValue* extracted_list = NULL; 271 ExtractPhoneNumberInformation(args, &index, &extracted_list, &country_code); 272 273 scoped_ptr<base::ListValue> list(extracted_list->DeepCopy()); 274 RemoveDuplicatePhoneNumberAtIndex(index, country_code, list.get()); 275 return list.Pass(); 276 } 277 278 } // namespace 279 280 namespace options { 281 282 AutofillOptionsHandler::AutofillOptionsHandler() 283 : personal_data_(NULL) {} 284 285 AutofillOptionsHandler::~AutofillOptionsHandler() { 286 if (personal_data_) 287 personal_data_->RemoveObserver(this); 288 } 289 290 ///////////////////////////////////////////////////////////////////////////// 291 // OptionsPageUIHandler implementation: 292 void AutofillOptionsHandler::GetLocalizedValues( 293 base::DictionaryValue* localized_strings) { 294 DCHECK(localized_strings); 295 296 static OptionsStringResource resources[] = { 297 { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME }, 298 { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME }, 299 { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON }, 300 { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON }, 301 { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON }, 302 { "helpButton", IDS_AUTOFILL_HELP_LABEL }, 303 { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION }, 304 { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION }, 305 { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION }, 306 { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION }, 307 #if defined(OS_MACOSX) 308 { "auxiliaryProfilesEnabled", IDS_AUTOFILL_USE_MAC_ADDRESS_BOOK }, 309 #endif // defined(OS_MACOSX) 310 }; 311 312 RegisterStrings(localized_strings, resources, arraysize(resources)); 313 RegisterTitle(localized_strings, "autofillOptionsPage", 314 IDS_AUTOFILL_OPTIONS_TITLE); 315 316 localized_strings->SetString("helpUrl", autofill::kHelpURL); 317 SetAddressOverlayStrings(localized_strings); 318 SetCreditCardOverlayStrings(localized_strings); 319 } 320 321 void AutofillOptionsHandler::InitializeHandler() { 322 // personal_data_ is NULL in guest mode on Chrome OS. 323 if (personal_data_) 324 personal_data_->AddObserver(this); 325 } 326 327 void AutofillOptionsHandler::InitializePage() { 328 if (personal_data_) 329 LoadAutofillData(); 330 } 331 332 void AutofillOptionsHandler::RegisterMessages() { 333 personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile( 334 Profile::FromWebUI(web_ui())); 335 336 #if defined(OS_MACOSX) && !defined(OS_IOS) 337 web_ui()->RegisterMessageCallback( 338 "accessAddressBook", 339 base::Bind(&AutofillOptionsHandler::AccessAddressBook, 340 base::Unretained(this))); 341 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 342 web_ui()->RegisterMessageCallback( 343 "removeData", 344 base::Bind(&AutofillOptionsHandler::RemoveData, 345 base::Unretained(this))); 346 web_ui()->RegisterMessageCallback( 347 "loadAddressEditor", 348 base::Bind(&AutofillOptionsHandler::LoadAddressEditor, 349 base::Unretained(this))); 350 web_ui()->RegisterMessageCallback( 351 "loadAddressEditorComponents", 352 base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents, 353 base::Unretained(this))); 354 web_ui()->RegisterMessageCallback( 355 "loadCreditCardEditor", 356 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor, 357 base::Unretained(this))); 358 web_ui()->RegisterMessageCallback( 359 "setAddress", 360 base::Bind(&AutofillOptionsHandler::SetAddress, base::Unretained(this))); 361 web_ui()->RegisterMessageCallback( 362 "setCreditCard", 363 base::Bind(&AutofillOptionsHandler::SetCreditCard, 364 base::Unretained(this))); 365 web_ui()->RegisterMessageCallback( 366 "validatePhoneNumbers", 367 base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers, 368 base::Unretained(this))); 369 } 370 371 ///////////////////////////////////////////////////////////////////////////// 372 // PersonalDataManagerObserver implementation: 373 void AutofillOptionsHandler::OnPersonalDataChanged() { 374 LoadAutofillData(); 375 } 376 377 void AutofillOptionsHandler::SetAddressOverlayStrings( 378 base::DictionaryValue* localized_strings) { 379 localized_strings->SetString("autofillEditAddressTitle", 380 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION)); 381 localized_strings->SetString("autofillCountryLabel", 382 l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_I18N_COUNTRY_LABEL)); 383 localized_strings->SetString("autofillPhoneLabel", 384 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE)); 385 localized_strings->SetString("autofillEmailLabel", 386 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL)); 387 localized_strings->SetString("autofillAddPhonePlaceholder", 388 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE)); 389 localized_strings->SetString("autofillAddEmailPlaceholder", 390 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_EMAIL)); 391 SetCountryData(*personal_data_, localized_strings); 392 } 393 394 void AutofillOptionsHandler::SetCreditCardOverlayStrings( 395 base::DictionaryValue* localized_strings) { 396 localized_strings->SetString("autofillEditCreditCardTitle", 397 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION)); 398 localized_strings->SetString("nameOnCardLabel", 399 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD)); 400 localized_strings->SetString("creditCardNumberLabel", 401 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER)); 402 localized_strings->SetString("creditCardExpirationDateLabel", 403 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE)); 404 } 405 406 void AutofillOptionsHandler::LoadAutofillData() { 407 if (!IsPersonalDataLoaded()) 408 return; 409 410 const std::vector<AutofillProfile*>& profiles = 411 personal_data_->web_profiles(); 412 std::vector<base::string16> labels; 413 AutofillProfile::CreateDifferentiatingLabels(profiles, &labels); 414 DCHECK_EQ(labels.size(), profiles.size()); 415 416 base::ListValue addresses; 417 for (size_t i = 0; i < profiles.size(); ++i) { 418 base::ListValue* entry = new base::ListValue(); 419 entry->Append(new base::StringValue(profiles[i]->guid())); 420 entry->Append(new base::StringValue(labels[i])); 421 addresses.Append(entry); 422 } 423 424 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses); 425 426 base::ListValue credit_cards; 427 const std::vector<CreditCard*>& cards = personal_data_->GetCreditCards(); 428 for (std::vector<CreditCard*>::const_iterator iter = cards.begin(); 429 iter != cards.end(); ++iter) { 430 const CreditCard* card = *iter; 431 // TODO(estade): this should be a dictionary. 432 base::ListValue* entry = new base::ListValue(); 433 entry->Append(new base::StringValue(card->guid())); 434 entry->Append(new base::StringValue(card->Label())); 435 entry->Append(new base::StringValue( 436 webui::GetBitmapDataUrlFromResource( 437 CreditCard::IconResourceId(card->type())))); 438 entry->Append(new base::StringValue(card->TypeForDisplay())); 439 credit_cards.Append(entry); 440 } 441 442 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList", 443 credit_cards); 444 } 445 446 #if defined(OS_MACOSX) && !defined(OS_IOS) 447 void AutofillOptionsHandler::AccessAddressBook(const base::ListValue* args) { 448 personal_data_->AccessAddressBook(); 449 } 450 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 451 452 void AutofillOptionsHandler::RemoveData(const base::ListValue* args) { 453 DCHECK(IsPersonalDataLoaded()); 454 455 std::string guid; 456 if (!args->GetString(0, &guid)) { 457 NOTREACHED(); 458 return; 459 } 460 461 personal_data_->RemoveByGUID(guid); 462 } 463 464 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue* args) { 465 DCHECK(IsPersonalDataLoaded()); 466 467 std::string guid; 468 if (!args->GetString(0, &guid)) { 469 NOTREACHED(); 470 return; 471 } 472 473 AutofillProfile* profile = personal_data_->GetProfileByGUID(guid); 474 if (!profile) { 475 // There is a race where a user can click once on the close button and 476 // quickly click again on the list item before the item is removed (since 477 // the list is not updated until the model tells the list an item has been 478 // removed). This will activate the editor for a profile that has been 479 // removed. Do nothing in that case. 480 return; 481 } 482 483 base::DictionaryValue address; 484 address.SetString("guid", profile->guid()); 485 scoped_ptr<base::ListValue> list; 486 GetValueList(*profile, autofill::NAME_FULL, &list); 487 address.Set(kFullNameField, list.release()); 488 address.SetString( 489 kCompanyNameField, profile->GetRawInfo(autofill::COMPANY_NAME)); 490 address.SetString(kAddressLineField, 491 profile->GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS)); 492 address.SetString( 493 kCityField, profile->GetRawInfo(autofill::ADDRESS_HOME_CITY)); 494 address.SetString( 495 kStateField, profile->GetRawInfo(autofill::ADDRESS_HOME_STATE)); 496 address.SetString( 497 kDependentLocalityField, 498 profile->GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY)); 499 address.SetString(kSortingCodeField, 500 profile->GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE)); 501 address.SetString(kPostalCodeField, 502 profile->GetRawInfo(autofill::ADDRESS_HOME_ZIP)); 503 address.SetString(kCountryField, 504 profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); 505 GetValueList(*profile, autofill::PHONE_HOME_WHOLE_NUMBER, &list); 506 address.Set("phone", list.release()); 507 GetValueList(*profile, autofill::EMAIL_ADDRESS, &list); 508 address.Set("email", list.release()); 509 address.SetString(kLanguageCode, profile->language_code()); 510 511 scoped_ptr<base::ListValue> components(new base::ListValue); 512 GetAddressComponents( 513 base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)), 514 profile->language_code(), components.get(), NULL); 515 address.Set(kComponents, components.release()); 516 517 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address); 518 } 519 520 void AutofillOptionsHandler::LoadAddressEditorComponents( 521 const base::ListValue* args) { 522 std::string country_code; 523 if (!args->GetString(0, &country_code)) { 524 NOTREACHED(); 525 return; 526 } 527 528 base::DictionaryValue input; 529 scoped_ptr<base::ListValue> components(new base::ListValue); 530 std::string language_code; 531 GetAddressComponents(country_code, g_browser_process->GetApplicationLocale(), 532 components.get(), &language_code); 533 input.Set(kComponents, components.release()); 534 input.SetString(kLanguageCode, language_code); 535 536 web_ui()->CallJavascriptFunction( 537 "AutofillEditAddressOverlay.loadAddressComponents", input); 538 } 539 540 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue* args) { 541 DCHECK(IsPersonalDataLoaded()); 542 543 std::string guid; 544 if (!args->GetString(0, &guid)) { 545 NOTREACHED(); 546 return; 547 } 548 549 CreditCard* credit_card = personal_data_->GetCreditCardByGUID(guid); 550 if (!credit_card) { 551 // There is a race where a user can click once on the close button and 552 // quickly click again on the list item before the item is removed (since 553 // the list is not updated until the model tells the list an item has been 554 // removed). This will activate the editor for a profile that has been 555 // removed. Do nothing in that case. 556 return; 557 } 558 559 base::DictionaryValue credit_card_data; 560 credit_card_data.SetString("guid", credit_card->guid()); 561 credit_card_data.SetString( 562 "nameOnCard", 563 credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME)); 564 credit_card_data.SetString( 565 "creditCardNumber", 566 credit_card->GetRawInfo(autofill::CREDIT_CARD_NUMBER)); 567 credit_card_data.SetString( 568 "expirationMonth", 569 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH)); 570 credit_card_data.SetString( 571 "expirationYear", 572 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)); 573 574 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard", 575 credit_card_data); 576 } 577 578 void AutofillOptionsHandler::SetAddress(const base::ListValue* args) { 579 if (!IsPersonalDataLoaded()) 580 return; 581 582 int arg_counter = 0; 583 std::string guid; 584 if (!args->GetString(arg_counter++, &guid)) { 585 NOTREACHED(); 586 return; 587 } 588 589 AutofillProfile profile(guid, kSettingsOrigin); 590 591 base::string16 value; 592 const base::ListValue* list_value; 593 if (args->GetList(arg_counter++, &list_value)) 594 SetValueList(list_value, autofill::NAME_FULL, &profile); 595 596 if (args->GetString(arg_counter++, &value)) 597 profile.SetRawInfo(autofill::COMPANY_NAME, value); 598 599 if (args->GetString(arg_counter++, &value)) 600 profile.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, value); 601 602 if (args->GetString(arg_counter++, &value)) 603 profile.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY, value); 604 605 if (args->GetString(arg_counter++, &value)) 606 profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, value); 607 608 if (args->GetString(arg_counter++, &value)) 609 profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, value); 610 611 if (args->GetString(arg_counter++, &value)) 612 profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, value); 613 614 if (args->GetString(arg_counter++, &value)) 615 profile.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE, value); 616 617 if (args->GetString(arg_counter++, &value)) 618 profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY, value); 619 620 if (args->GetList(arg_counter++, &list_value)) 621 SetValueList(list_value, autofill::PHONE_HOME_WHOLE_NUMBER, &profile); 622 623 if (args->GetList(arg_counter++, &list_value)) 624 SetValueList(list_value, autofill::EMAIL_ADDRESS, &profile); 625 626 if (args->GetString(arg_counter++, &value)) 627 profile.set_language_code(base::UTF16ToUTF8(value)); 628 629 if (!base::IsValidGUID(profile.guid())) { 630 profile.set_guid(base::GenerateGUID()); 631 personal_data_->AddProfile(profile); 632 } else { 633 personal_data_->UpdateProfile(profile); 634 } 635 } 636 637 void AutofillOptionsHandler::SetCreditCard(const base::ListValue* args) { 638 if (!IsPersonalDataLoaded()) 639 return; 640 641 std::string guid; 642 if (!args->GetString(0, &guid)) { 643 NOTREACHED(); 644 return; 645 } 646 647 CreditCard credit_card(guid, kSettingsOrigin); 648 649 base::string16 value; 650 if (args->GetString(1, &value)) 651 credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME, value); 652 653 if (args->GetString(2, &value)) 654 credit_card.SetRawInfo(autofill::CREDIT_CARD_NUMBER, value); 655 656 if (args->GetString(3, &value)) 657 credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, value); 658 659 if (args->GetString(4, &value)) 660 credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, value); 661 662 if (!base::IsValidGUID(credit_card.guid())) { 663 credit_card.set_guid(base::GenerateGUID()); 664 personal_data_->AddCreditCard(credit_card); 665 } else { 666 personal_data_->UpdateCreditCard(credit_card); 667 } 668 } 669 670 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue* args) { 671 if (!IsPersonalDataLoaded()) 672 return; 673 674 scoped_ptr<base::ListValue> list_value = ValidatePhoneArguments(args); 675 676 web_ui()->CallJavascriptFunction( 677 "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value); 678 } 679 680 bool AutofillOptionsHandler::IsPersonalDataLoaded() const { 681 return personal_data_ && personal_data_->IsDataLoaded(); 682 } 683 684 } // namespace options 685