Autofill settings: show generated (concatenated) full name in settings
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / autofill_options_handler.cc
blob55bea13677e3c8dc4f6d7de8bc4ac0158a101dda
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.
5 #include "chrome/browser/ui/webui/options/autofill_options_handler.h"
7 #include <vector>
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 "third_party/libaddressinput/messages.h"
32 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h"
33 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h"
34 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "ui/base/webui/web_ui_util.h"
38 using autofill::AutofillCountry;
39 using autofill::AutofillType;
40 using autofill::ServerFieldType;
41 using autofill::AutofillProfile;
42 using autofill::CreditCard;
43 using autofill::PersonalDataManager;
44 using i18n::addressinput::AddressUiComponent;
46 namespace {
48 const char kSettingsOrigin[] = "Chrome settings";
50 static const char kFullNameField[] = "fullName";
51 static const char kCompanyNameField[] = "companyName";
52 static const char kAddressLineField[] = "addrLines";
53 static const char kDependentLocalityField[] = "dependentLocality";
54 static const char kCityField[] = "city";
55 static const char kStateField[] = "state";
56 static const char kPostalCodeField[] = "postalCode";
57 static const char kSortingCodeField[] = "sortingCode";
58 static const char kCountryField[] = "country";
60 static const char kComponents[] = "components";
61 static const char kLanguageCode[] = "languageCode";
63 // Fills |components| with the address UI components that should be used to
64 // input an address for |country_code| when UI BCP 47 language code is
65 // |ui_language_code|. If |components_language_code| is not NULL, then sets it
66 // to the BCP 47 language code that should be used to format the address for
67 // display.
68 void GetAddressComponents(const std::string& country_code,
69 const std::string& ui_language_code,
70 base::ListValue* address_components,
71 std::string* components_language_code) {
72 DCHECK(address_components);
74 i18n::addressinput::Localization localization;
75 localization.SetGetter(l10n_util::GetStringUTF8);
76 std::string not_used;
77 std::vector<AddressUiComponent> components =
78 i18n::addressinput::BuildComponents(
79 country_code,
80 localization,
81 ui_language_code,
82 components_language_code == NULL ?
83 &not_used : components_language_code);
84 if (components.empty()) {
85 static const char kDefaultCountryCode[] = "US";
86 components = i18n::addressinput::BuildComponents(
87 kDefaultCountryCode,
88 localization,
89 ui_language_code,
90 components_language_code == NULL ?
91 &not_used : components_language_code);
93 DCHECK(!components.empty());
95 base::ListValue* line = NULL;
96 static const char kField[] = "field";
97 static const char kLength[] = "length";
98 for (size_t i = 0; i < components.size(); ++i) {
99 if (i == 0 ||
100 components[i - 1].length_hint == AddressUiComponent::HINT_LONG ||
101 components[i].length_hint == AddressUiComponent::HINT_LONG) {
102 line = new base::ListValue;
103 address_components->Append(line);
106 scoped_ptr<base::DictionaryValue> component(new base::DictionaryValue);
107 component->SetString("name", components[i].name);
109 switch (components[i].field) {
110 case i18n::addressinput::COUNTRY:
111 component->SetString(kField, kCountryField);
112 break;
113 case i18n::addressinput::ADMIN_AREA:
114 component->SetString(kField, kStateField);
115 break;
116 case i18n::addressinput::LOCALITY:
117 component->SetString(kField, kCityField);
118 break;
119 case i18n::addressinput::DEPENDENT_LOCALITY:
120 component->SetString(kField, kDependentLocalityField);
121 break;
122 case i18n::addressinput::SORTING_CODE:
123 component->SetString(kField, kSortingCodeField);
124 break;
125 case i18n::addressinput::POSTAL_CODE:
126 component->SetString(kField, kPostalCodeField);
127 break;
128 case i18n::addressinput::STREET_ADDRESS:
129 component->SetString(kField, kAddressLineField);
130 break;
131 case i18n::addressinput::RECIPIENT:
132 component->SetString(kField, kFullNameField);
133 component->SetString(
134 "placeholder",
135 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME));
136 break;
139 switch (components[i].length_hint) {
140 case AddressUiComponent::HINT_LONG:
141 component->SetString(kLength, "long");
142 break;
143 case AddressUiComponent::HINT_SHORT:
144 component->SetString(kLength, "short");
145 break;
148 line->Append(component.release());
152 // Sets data related to the country <select>.
153 void SetCountryData(const PersonalDataManager& manager,
154 base::DictionaryValue* localized_strings) {
155 autofill::CountryComboboxModel model;
156 model.SetCountries(manager, base::Callback<bool(const std::string&)>());
157 const std::vector<AutofillCountry*>& countries = model.countries();
158 localized_strings->SetString("defaultCountryCode",
159 countries.front()->country_code());
161 // An ordered list of options to show in the <select>.
162 scoped_ptr<base::ListValue> country_list(new base::ListValue());
163 for (size_t i = 0; i < countries.size(); ++i) {
164 scoped_ptr<base::DictionaryValue> option_details(
165 new base::DictionaryValue());
166 option_details->SetString("name", model.GetItemAt(i));
167 option_details->SetString(
168 "value",
169 countries[i] ? countries[i]->country_code() : "separator");
170 country_list->Append(option_details.release());
172 localized_strings->Set("autofillCountrySelectList", country_list.release());
174 scoped_ptr<base::ListValue> default_country_components(new base::ListValue);
175 std::string default_country_language_code;
176 GetAddressComponents(countries.front()->country_code(),
177 g_browser_process->GetApplicationLocale(),
178 default_country_components.get(),
179 &default_country_language_code);
180 localized_strings->Set("autofillDefaultCountryComponents",
181 default_country_components.release());
182 localized_strings->SetString("autofillDefaultCountryLanguageCode",
183 default_country_language_code);
186 // Get the multi-valued element for |type| and return it in |ListValue| form.
187 // Buyer beware: the type of data affects whether GetRawInfo or GetInfo is used.
188 void GetValueList(const AutofillProfile& profile,
189 ServerFieldType type,
190 scoped_ptr<base::ListValue>* list) {
191 list->reset(new base::ListValue);
193 std::vector<base::string16> values;
194 if (AutofillType(type).group() == autofill::NAME) {
195 profile.GetMultiInfo(
196 AutofillType(type), g_browser_process->GetApplicationLocale(), &values);
197 } else {
198 profile.GetRawMultiInfo(type, &values);
201 // |Get[Raw]MultiInfo()| always returns at least one, potentially empty, item.
202 if (values.size() == 1 && values.front().empty())
203 return;
205 for (size_t i = 0; i < values.size(); ++i) {
206 (*list)->Set(i, new base::StringValue(values[i]));
210 // Converts a ListValue of StringValues to a vector of string16s.
211 void ListValueToStringVector(const base::ListValue& list,
212 std::vector<base::string16>* output) {
213 output->resize(list.GetSize());
214 for (size_t i = 0; i < list.GetSize(); ++i) {
215 base::string16 value;
216 if (list.GetString(i, &value))
217 (*output)[i].swap(value);
221 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
222 // the |args| input.
223 void ExtractPhoneNumberInformation(const base::ListValue* args,
224 size_t* index,
225 const base::ListValue** phone_number_list,
226 std::string* country_code) {
227 // Retrieve index as a |double|, as that is how it comes across from
228 // JavaScript.
229 double number = 0.0;
230 if (!args->GetDouble(0, &number)) {
231 NOTREACHED();
232 return;
234 *index = number;
236 if (!args->GetList(1, phone_number_list)) {
237 NOTREACHED();
238 return;
241 if (!args->GetString(2, country_code)) {
242 NOTREACHED();
243 return;
247 // Searches the |list| for the value at |index|. If this value is present
248 // in any of the rest of the list, then the item (at |index|) is removed.
249 // The comparison of phone number values is done on normalized versions of the
250 // phone number values.
251 void RemoveDuplicatePhoneNumberAtIndex(size_t index,
252 const std::string& country_code,
253 base::ListValue* list) {
254 base::string16 new_value;
255 if (!list->GetString(index, &new_value)) {
256 NOTREACHED() << "List should have a value at index " << index;
257 return;
260 bool is_duplicate = false;
261 std::string app_locale = g_browser_process->GetApplicationLocale();
262 for (size_t i = 0; i < list->GetSize() && !is_duplicate; ++i) {
263 if (i == index)
264 continue;
266 base::string16 existing_value;
267 if (!list->GetString(i, &existing_value)) {
268 NOTREACHED() << "List should have a value at index " << i;
269 continue;
271 is_duplicate = autofill::i18n::PhoneNumbersMatch(
272 new_value, existing_value, country_code, app_locale);
275 if (is_duplicate)
276 list->Remove(index, NULL);
279 scoped_ptr<base::ListValue> ValidatePhoneArguments(
280 const base::ListValue* args) {
281 size_t index = 0;
282 std::string country_code;
283 const base::ListValue* extracted_list = NULL;
284 ExtractPhoneNumberInformation(args, &index, &extracted_list, &country_code);
286 scoped_ptr<base::ListValue> list(extracted_list->DeepCopy());
287 RemoveDuplicatePhoneNumberAtIndex(index, country_code, list.get());
288 return list.Pass();
291 } // namespace
293 namespace options {
295 AutofillOptionsHandler::AutofillOptionsHandler()
296 : personal_data_(NULL) {}
298 AutofillOptionsHandler::~AutofillOptionsHandler() {
299 if (personal_data_)
300 personal_data_->RemoveObserver(this);
303 /////////////////////////////////////////////////////////////////////////////
304 // OptionsPageUIHandler implementation:
305 void AutofillOptionsHandler::GetLocalizedValues(
306 base::DictionaryValue* localized_strings) {
307 DCHECK(localized_strings);
309 static OptionsStringResource resources[] = {
310 { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME },
311 { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME },
312 { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON },
313 { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON },
314 { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON },
315 { "helpButton", IDS_AUTOFILL_HELP_LABEL },
316 { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION },
317 { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION },
318 { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION },
319 { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION },
320 #if defined(OS_MACOSX)
321 { "auxiliaryProfilesEnabled", IDS_AUTOFILL_USE_MAC_ADDRESS_BOOK },
322 #endif // defined(OS_MACOSX)
325 RegisterStrings(localized_strings, resources, arraysize(resources));
326 RegisterTitle(localized_strings, "autofillOptionsPage",
327 IDS_AUTOFILL_OPTIONS_TITLE);
329 localized_strings->SetString("helpUrl", autofill::kHelpURL);
330 SetAddressOverlayStrings(localized_strings);
331 SetCreditCardOverlayStrings(localized_strings);
334 void AutofillOptionsHandler::InitializeHandler() {
335 // personal_data_ is NULL in guest mode on Chrome OS.
336 if (personal_data_)
337 personal_data_->AddObserver(this);
340 void AutofillOptionsHandler::InitializePage() {
341 if (personal_data_)
342 LoadAutofillData();
345 void AutofillOptionsHandler::RegisterMessages() {
346 personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile(
347 Profile::FromWebUI(web_ui()));
349 #if defined(OS_MACOSX) && !defined(OS_IOS)
350 web_ui()->RegisterMessageCallback(
351 "accessAddressBook",
352 base::Bind(&AutofillOptionsHandler::AccessAddressBook,
353 base::Unretained(this)));
354 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
355 web_ui()->RegisterMessageCallback(
356 "removeData",
357 base::Bind(&AutofillOptionsHandler::RemoveData,
358 base::Unretained(this)));
359 web_ui()->RegisterMessageCallback(
360 "loadAddressEditor",
361 base::Bind(&AutofillOptionsHandler::LoadAddressEditor,
362 base::Unretained(this)));
363 web_ui()->RegisterMessageCallback(
364 "loadAddressEditorComponents",
365 base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents,
366 base::Unretained(this)));
367 web_ui()->RegisterMessageCallback(
368 "loadCreditCardEditor",
369 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor,
370 base::Unretained(this)));
371 web_ui()->RegisterMessageCallback(
372 "setAddress",
373 base::Bind(&AutofillOptionsHandler::SetAddress, base::Unretained(this)));
374 web_ui()->RegisterMessageCallback(
375 "setCreditCard",
376 base::Bind(&AutofillOptionsHandler::SetCreditCard,
377 base::Unretained(this)));
378 web_ui()->RegisterMessageCallback(
379 "validatePhoneNumbers",
380 base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers,
381 base::Unretained(this)));
384 /////////////////////////////////////////////////////////////////////////////
385 // PersonalDataManagerObserver implementation:
386 void AutofillOptionsHandler::OnPersonalDataChanged() {
387 LoadAutofillData();
390 void AutofillOptionsHandler::SetAddressOverlayStrings(
391 base::DictionaryValue* localized_strings) {
392 localized_strings->SetString("autofillEditAddressTitle",
393 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION));
394 localized_strings->SetString("autofillCountryLabel",
395 l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL));
396 localized_strings->SetString("autofillPhoneLabel",
397 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE));
398 localized_strings->SetString("autofillEmailLabel",
399 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL));
400 localized_strings->SetString("autofillAddPhonePlaceholder",
401 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE));
402 localized_strings->SetString("autofillAddEmailPlaceholder",
403 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_EMAIL));
404 SetCountryData(*personal_data_, localized_strings);
407 void AutofillOptionsHandler::SetCreditCardOverlayStrings(
408 base::DictionaryValue* localized_strings) {
409 localized_strings->SetString("autofillEditCreditCardTitle",
410 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION));
411 localized_strings->SetString("nameOnCardLabel",
412 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD));
413 localized_strings->SetString("creditCardNumberLabel",
414 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER));
415 localized_strings->SetString("creditCardExpirationDateLabel",
416 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE));
419 void AutofillOptionsHandler::LoadAutofillData() {
420 if (!IsPersonalDataLoaded())
421 return;
423 const std::vector<AutofillProfile*>& profiles =
424 personal_data_->web_profiles();
425 std::vector<base::string16> labels;
426 AutofillProfile::CreateDifferentiatingLabels(
427 profiles,
428 g_browser_process->GetApplicationLocale(),
429 &labels);
430 DCHECK_EQ(labels.size(), profiles.size());
432 base::ListValue addresses;
433 for (size_t i = 0; i < profiles.size(); ++i) {
434 base::ListValue* entry = new base::ListValue();
435 entry->Append(new base::StringValue(profiles[i]->guid()));
436 entry->Append(new base::StringValue(labels[i]));
437 addresses.Append(entry);
440 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses);
442 base::ListValue credit_cards;
443 const std::vector<CreditCard*>& cards = personal_data_->GetCreditCards();
444 for (std::vector<CreditCard*>::const_iterator iter = cards.begin();
445 iter != cards.end(); ++iter) {
446 const CreditCard* card = *iter;
447 // TODO(estade): this should be a dictionary.
448 base::ListValue* entry = new base::ListValue();
449 entry->Append(new base::StringValue(card->guid()));
450 entry->Append(new base::StringValue(card->Label()));
451 entry->Append(new base::StringValue(
452 webui::GetBitmapDataUrlFromResource(
453 CreditCard::IconResourceId(card->type()))));
454 entry->Append(new base::StringValue(card->TypeForDisplay()));
455 credit_cards.Append(entry);
458 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
459 credit_cards);
462 #if defined(OS_MACOSX) && !defined(OS_IOS)
463 void AutofillOptionsHandler::AccessAddressBook(const base::ListValue* args) {
464 personal_data_->AccessAddressBook();
466 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
468 void AutofillOptionsHandler::RemoveData(const base::ListValue* args) {
469 DCHECK(IsPersonalDataLoaded());
471 std::string guid;
472 if (!args->GetString(0, &guid)) {
473 NOTREACHED();
474 return;
477 personal_data_->RemoveByGUID(guid);
480 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue* args) {
481 DCHECK(IsPersonalDataLoaded());
483 std::string guid;
484 if (!args->GetString(0, &guid)) {
485 NOTREACHED();
486 return;
489 AutofillProfile* profile = personal_data_->GetProfileByGUID(guid);
490 if (!profile) {
491 // There is a race where a user can click once on the close button and
492 // quickly click again on the list item before the item is removed (since
493 // the list is not updated until the model tells the list an item has been
494 // removed). This will activate the editor for a profile that has been
495 // removed. Do nothing in that case.
496 return;
499 base::DictionaryValue address;
500 AutofillProfileToDictionary(*profile, &address);
502 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address);
505 void AutofillOptionsHandler::LoadAddressEditorComponents(
506 const base::ListValue* args) {
507 std::string country_code;
508 if (!args->GetString(0, &country_code)) {
509 NOTREACHED();
510 return;
513 base::DictionaryValue input;
514 scoped_ptr<base::ListValue> components(new base::ListValue);
515 std::string language_code;
516 GetAddressComponents(country_code, g_browser_process->GetApplicationLocale(),
517 components.get(), &language_code);
518 input.Set(kComponents, components.release());
519 input.SetString(kLanguageCode, language_code);
521 web_ui()->CallJavascriptFunction(
522 "AutofillEditAddressOverlay.loadAddressComponents", input);
525 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue* args) {
526 DCHECK(IsPersonalDataLoaded());
528 std::string guid;
529 if (!args->GetString(0, &guid)) {
530 NOTREACHED();
531 return;
534 CreditCard* credit_card = personal_data_->GetCreditCardByGUID(guid);
535 if (!credit_card) {
536 // There is a race where a user can click once on the close button and
537 // quickly click again on the list item before the item is removed (since
538 // the list is not updated until the model tells the list an item has been
539 // removed). This will activate the editor for a profile that has been
540 // removed. Do nothing in that case.
541 return;
544 base::DictionaryValue credit_card_data;
545 credit_card_data.SetString("guid", credit_card->guid());
546 credit_card_data.SetString(
547 "nameOnCard",
548 credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME));
549 credit_card_data.SetString(
550 "creditCardNumber",
551 credit_card->GetRawInfo(autofill::CREDIT_CARD_NUMBER));
552 credit_card_data.SetString(
553 "expirationMonth",
554 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH));
555 credit_card_data.SetString(
556 "expirationYear",
557 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR));
559 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
560 credit_card_data);
563 void AutofillOptionsHandler::SetAddress(const base::ListValue* args) {
564 if (!IsPersonalDataLoaded())
565 return;
567 int arg_counter = 0;
568 std::string guid;
569 if (!args->GetString(arg_counter++, &guid)) {
570 NOTREACHED();
571 return;
574 AutofillProfile profile(guid, kSettingsOrigin);
576 base::string16 value;
577 const base::ListValue* list_value;
578 if (args->GetList(arg_counter++, &list_value)) {
579 std::vector<base::string16> values;
580 ListValueToStringVector(*list_value, &values);
581 profile.SetMultiInfo(AutofillType(autofill::NAME_FULL),
582 values,
583 g_browser_process->GetApplicationLocale());
586 if (args->GetString(arg_counter++, &value))
587 profile.SetRawInfo(autofill::COMPANY_NAME, value);
589 if (args->GetString(arg_counter++, &value))
590 profile.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, value);
592 if (args->GetString(arg_counter++, &value))
593 profile.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY, value);
595 if (args->GetString(arg_counter++, &value))
596 profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, value);
598 if (args->GetString(arg_counter++, &value))
599 profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, value);
601 if (args->GetString(arg_counter++, &value))
602 profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, value);
604 if (args->GetString(arg_counter++, &value))
605 profile.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE, value);
607 if (args->GetString(arg_counter++, &value))
608 profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY, value);
610 if (args->GetList(arg_counter++, &list_value)) {
611 std::vector<base::string16> values;
612 ListValueToStringVector(*list_value, &values);
613 profile.SetRawMultiInfo(autofill::PHONE_HOME_WHOLE_NUMBER, values);
616 if (args->GetList(arg_counter++, &list_value)) {
617 std::vector<base::string16> values;
618 ListValueToStringVector(*list_value, &values);
619 profile.SetRawMultiInfo(autofill::EMAIL_ADDRESS, values);
622 if (args->GetString(arg_counter++, &value))
623 profile.set_language_code(base::UTF16ToUTF8(value));
625 if (!base::IsValidGUID(profile.guid())) {
626 profile.set_guid(base::GenerateGUID());
627 personal_data_->AddProfile(profile);
628 } else {
629 personal_data_->UpdateProfile(profile);
633 void AutofillOptionsHandler::SetCreditCard(const base::ListValue* args) {
634 if (!IsPersonalDataLoaded())
635 return;
637 std::string guid;
638 if (!args->GetString(0, &guid)) {
639 NOTREACHED();
640 return;
643 CreditCard credit_card(guid, kSettingsOrigin);
645 base::string16 value;
646 if (args->GetString(1, &value))
647 credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME, value);
649 if (args->GetString(2, &value))
650 credit_card.SetRawInfo(autofill::CREDIT_CARD_NUMBER, value);
652 if (args->GetString(3, &value))
653 credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, value);
655 if (args->GetString(4, &value))
656 credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, value);
658 if (!base::IsValidGUID(credit_card.guid())) {
659 credit_card.set_guid(base::GenerateGUID());
660 personal_data_->AddCreditCard(credit_card);
661 } else {
662 personal_data_->UpdateCreditCard(credit_card);
666 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue* args) {
667 if (!IsPersonalDataLoaded())
668 return;
670 scoped_ptr<base::ListValue> list_value = ValidatePhoneArguments(args);
672 web_ui()->CallJavascriptFunction(
673 "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value);
676 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
677 return personal_data_ && personal_data_->IsDataLoaded();
680 // static
681 void AutofillOptionsHandler::AutofillProfileToDictionary(
682 const autofill::AutofillProfile& profile,
683 base::DictionaryValue* address) {
684 address->SetString("guid", profile.guid());
685 scoped_ptr<base::ListValue> list;
686 GetValueList(profile, autofill::NAME_FULL, &list);
687 address->Set(kFullNameField, list.release());
688 address->SetString(kCompanyNameField,
689 profile.GetRawInfo(autofill::COMPANY_NAME));
690 address->SetString(kAddressLineField,
691 profile.GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS));
692 address->SetString(kCityField,
693 profile.GetRawInfo(autofill::ADDRESS_HOME_CITY));
694 address->SetString(kStateField,
695 profile.GetRawInfo(autofill::ADDRESS_HOME_STATE));
696 address->SetString(
697 kDependentLocalityField,
698 profile.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY));
699 address->SetString(kSortingCodeField,
700 profile.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE));
701 address->SetString(kPostalCodeField,
702 profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP));
703 address->SetString(kCountryField,
704 profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
705 GetValueList(profile, autofill::PHONE_HOME_WHOLE_NUMBER, &list);
706 address->Set("phone", list.release());
707 GetValueList(profile, autofill::EMAIL_ADDRESS, &list);
708 address->Set("email", list.release());
709 address->SetString(kLanguageCode, profile.language_code());
711 scoped_ptr<base::ListValue> components(new base::ListValue);
712 GetAddressComponents(
713 base::UTF16ToUTF8(profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)),
714 profile.language_code(),
715 components.get(),
716 NULL);
717 address->Set(kComponents, components.release());
720 } // namespace options