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"
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/component_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"
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
;
46 const char kSettingsOrigin
[] = "Chrome settings";
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";
58 static const char kComponents
[] = "components";
59 static const char kLanguageCode
[] = "languageCode";
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
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
);
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
);
80 DCHECK(!components
.empty());
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
) {
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
);
93 scoped_ptr
<base::DictionaryValue
> component(new base::DictionaryValue
);
95 "name", l10n_util::GetStringUTF16(components
[i
].name_id
));
97 switch (components
[i
].field
) {
98 case i18n::addressinput::COUNTRY
:
99 component
->SetString(kField
, kCountryField
);
101 case i18n::addressinput::ADMIN_AREA
:
102 component
->SetString(kField
, kStateField
);
104 case i18n::addressinput::LOCALITY
:
105 component
->SetString(kField
, kCityField
);
107 case i18n::addressinput::DEPENDENT_LOCALITY
:
108 component
->SetString(kField
, kDependentLocalityField
);
110 case i18n::addressinput::SORTING_CODE
:
111 component
->SetString(kField
, kSortingCodeField
);
113 case i18n::addressinput::POSTAL_CODE
:
114 component
->SetString(kField
, kPostalCodeField
);
116 case i18n::addressinput::STREET_ADDRESS
:
117 component
->SetString(kField
, kAddressLineField
);
119 case i18n::addressinput::ORGANIZATION
:
120 component
->SetString(kField
, kCompanyNameField
);
122 case i18n::addressinput::RECIPIENT
:
123 component
->SetString(kField
, kFullNameField
);
124 component
->SetString(
126 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME
));
130 switch (components
[i
].length_hint
) {
131 case AddressUiComponent::HINT_LONG
:
132 component
->SetString(kLength
, "long");
134 case AddressUiComponent::HINT_SHORT
:
135 component
->SetString(kLength
, "short");
139 line
->Append(component
.release());
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());
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(
160 countries
[i
] ? countries
[i
]->country_code() : "separator");
161 country_list
->Append(option_details
.release());
163 localized_strings
->Set("autofillCountrySelectList", country_list
.release());
165 scoped_ptr
<base::ListValue
> defaultCountryComponents(new base::ListValue
);
166 std::string defaultCountryLanguageCode
;
167 GetAddressComponents(countries
.front()->country_code(),
168 g_browser_process
->GetApplicationLocale(),
169 defaultCountryComponents
.get(),
170 &defaultCountryLanguageCode
);
171 localized_strings
->Set("autofillDefaultCountryComponents",
172 defaultCountryComponents
.release());
173 localized_strings
->SetString("autofillDefaultCountryLanguageCode",
174 defaultCountryLanguageCode
);
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
);
183 std::vector
<base::string16
> values
;
184 profile
.GetRawMultiInfo(type
, &values
);
186 // |GetRawMultiInfo()| always returns at least one, potentially empty, item.
187 if (values
.size() == 1 && values
.front().empty())
190 for (size_t i
= 0; i
< values
.size(); ++i
) {
191 (*list
)->Set(i
, new base::StringValue(values
[i
]));
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
))
205 profile
->SetRawMultiInfo(type
, values
);
208 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
210 void ExtractPhoneNumberInformation(const base::ListValue
* args
,
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
217 if (!args
->GetDouble(0, &number
)) {
223 if (!args
->GetList(1, phone_number_list
)) {
228 if (!args
->GetString(2, country_code
)) {
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
;
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
) {
253 base::string16 existing_value
;
254 if (!list
->GetString(i
, &existing_value
)) {
255 NOTREACHED() << "List should have a value at index " << i
;
258 is_duplicate
= autofill::i18n::PhoneNumbersMatch(
259 new_value
, existing_value
, country_code
, app_locale
);
263 list
->Remove(index
, NULL
);
266 scoped_ptr
<base::ListValue
> ValidatePhoneArguments(
267 const base::ListValue
* args
) {
269 std::string country_code
;
270 const base::ListValue
* extracted_list
= NULL
;
271 ExtractPhoneNumberInformation(args
, &index
, &extracted_list
, &country_code
);
273 scoped_ptr
<base::ListValue
> list(extracted_list
->DeepCopy());
274 RemoveDuplicatePhoneNumberAtIndex(index
, country_code
, list
.get());
282 AutofillOptionsHandler::AutofillOptionsHandler()
283 : personal_data_(NULL
) {}
285 AutofillOptionsHandler::~AutofillOptionsHandler() {
287 personal_data_
->RemoveObserver(this);
290 /////////////////////////////////////////////////////////////////////////////
291 // OptionsPageUIHandler implementation:
292 void AutofillOptionsHandler::GetLocalizedValues(
293 base::DictionaryValue
* localized_strings
) {
294 DCHECK(localized_strings
);
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)
312 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
313 RegisterTitle(localized_strings
, "autofillOptionsPage",
314 IDS_AUTOFILL_OPTIONS_TITLE
);
316 localized_strings
->SetString("helpUrl", autofill::kHelpURL
);
317 SetAddressOverlayStrings(localized_strings
);
318 SetCreditCardOverlayStrings(localized_strings
);
321 void AutofillOptionsHandler::InitializeHandler() {
322 // personal_data_ is NULL in guest mode on Chrome OS.
324 personal_data_
->AddObserver(this);
327 void AutofillOptionsHandler::InitializePage() {
332 void AutofillOptionsHandler::RegisterMessages() {
333 personal_data_
= autofill::PersonalDataManagerFactory::GetForProfile(
334 Profile::FromWebUI(web_ui()));
336 web_ui()->RegisterMessageCallback(
338 base::Bind(&AutofillOptionsHandler::RemoveData
,
339 base::Unretained(this)));
340 web_ui()->RegisterMessageCallback(
342 base::Bind(&AutofillOptionsHandler::LoadAddressEditor
,
343 base::Unretained(this)));
344 web_ui()->RegisterMessageCallback(
345 "loadAddressEditorComponents",
346 base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents
,
347 base::Unretained(this)));
348 web_ui()->RegisterMessageCallback(
349 "loadCreditCardEditor",
350 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor
,
351 base::Unretained(this)));
352 web_ui()->RegisterMessageCallback(
354 base::Bind(&AutofillOptionsHandler::SetAddress
, base::Unretained(this)));
355 web_ui()->RegisterMessageCallback(
357 base::Bind(&AutofillOptionsHandler::SetCreditCard
,
358 base::Unretained(this)));
359 web_ui()->RegisterMessageCallback(
360 "validatePhoneNumbers",
361 base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers
,
362 base::Unretained(this)));
365 /////////////////////////////////////////////////////////////////////////////
366 // PersonalDataManagerObserver implementation:
367 void AutofillOptionsHandler::OnPersonalDataChanged() {
371 void AutofillOptionsHandler::SetAddressOverlayStrings(
372 base::DictionaryValue
* localized_strings
) {
373 localized_strings
->SetString("autofillEditAddressTitle",
374 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
));
375 localized_strings
->SetString("autofillCountryLabel",
376 l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_I18N_COUNTRY_LABEL
));
377 localized_strings
->SetString("autofillPhoneLabel",
378 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE
));
379 localized_strings
->SetString("autofillEmailLabel",
380 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL
));
381 localized_strings
->SetString("autofillAddPhonePlaceholder",
382 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE
));
383 localized_strings
->SetString("autofillAddEmailPlaceholder",
384 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_EMAIL
));
385 SetCountryData(*personal_data_
, localized_strings
);
388 void AutofillOptionsHandler::SetCreditCardOverlayStrings(
389 base::DictionaryValue
* localized_strings
) {
390 localized_strings
->SetString("autofillEditCreditCardTitle",
391 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
));
392 localized_strings
->SetString("nameOnCardLabel",
393 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD
));
394 localized_strings
->SetString("creditCardNumberLabel",
395 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER
));
396 localized_strings
->SetString("creditCardExpirationDateLabel",
397 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE
));
400 void AutofillOptionsHandler::LoadAutofillData() {
401 if (!IsPersonalDataLoaded())
404 const std::vector
<AutofillProfile
*>& profiles
=
405 personal_data_
->web_profiles();
406 std::vector
<base::string16
> labels
;
407 AutofillProfile::CreateDifferentiatingLabels(profiles
, &labels
);
408 DCHECK_EQ(labels
.size(), profiles
.size());
410 base::ListValue addresses
;
411 for (size_t i
= 0; i
< profiles
.size(); ++i
) {
412 base::ListValue
* entry
= new base::ListValue();
413 entry
->Append(new base::StringValue(profiles
[i
]->guid()));
414 entry
->Append(new base::StringValue(labels
[i
]));
415 addresses
.Append(entry
);
418 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses
);
420 base::ListValue credit_cards
;
421 const std::vector
<CreditCard
*>& cards
= personal_data_
->GetCreditCards();
422 for (std::vector
<CreditCard
*>::const_iterator iter
= cards
.begin();
423 iter
!= cards
.end(); ++iter
) {
424 const CreditCard
* card
= *iter
;
425 // TODO(estade): this should be a dictionary.
426 base::ListValue
* entry
= new base::ListValue();
427 entry
->Append(new base::StringValue(card
->guid()));
428 entry
->Append(new base::StringValue(card
->Label()));
429 entry
->Append(new base::StringValue(
430 webui::GetBitmapDataUrlFromResource(
431 CreditCard::IconResourceId(card
->type()))));
432 entry
->Append(new base::StringValue(card
->TypeForDisplay()));
433 credit_cards
.Append(entry
);
436 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
440 void AutofillOptionsHandler::RemoveData(const base::ListValue
* args
) {
441 DCHECK(IsPersonalDataLoaded());
444 if (!args
->GetString(0, &guid
)) {
449 personal_data_
->RemoveByGUID(guid
);
452 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue
* args
) {
453 DCHECK(IsPersonalDataLoaded());
456 if (!args
->GetString(0, &guid
)) {
461 AutofillProfile
* profile
= personal_data_
->GetProfileByGUID(guid
);
463 // There is a race where a user can click once on the close button and
464 // quickly click again on the list item before the item is removed (since
465 // the list is not updated until the model tells the list an item has been
466 // removed). This will activate the editor for a profile that has been
467 // removed. Do nothing in that case.
471 base::DictionaryValue address
;
472 address
.SetString("guid", profile
->guid());
473 scoped_ptr
<base::ListValue
> list
;
474 GetValueList(*profile
, autofill::NAME_FULL
, &list
);
475 address
.Set(kFullNameField
, list
.release());
477 kCompanyNameField
, profile
->GetRawInfo(autofill::COMPANY_NAME
));
478 address
.SetString(kAddressLineField
,
479 profile
->GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
));
481 kCityField
, profile
->GetRawInfo(autofill::ADDRESS_HOME_CITY
));
483 kStateField
, profile
->GetRawInfo(autofill::ADDRESS_HOME_STATE
));
485 kDependentLocalityField
,
486 profile
->GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
));
487 address
.SetString(kSortingCodeField
,
488 profile
->GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
));
489 address
.SetString(kPostalCodeField
,
490 profile
->GetRawInfo(autofill::ADDRESS_HOME_ZIP
));
491 address
.SetString(kCountryField
,
492 profile
->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
));
493 GetValueList(*profile
, autofill::PHONE_HOME_WHOLE_NUMBER
, &list
);
494 address
.Set("phone", list
.release());
495 GetValueList(*profile
, autofill::EMAIL_ADDRESS
, &list
);
496 address
.Set("email", list
.release());
497 address
.SetString(kLanguageCode
, profile
->language_code());
499 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
500 GetAddressComponents(
501 base::UTF16ToUTF8(profile
->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
)),
502 profile
->language_code(), components
.get(), NULL
);
503 address
.Set(kComponents
, components
.release());
505 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address
);
508 void AutofillOptionsHandler::LoadAddressEditorComponents(
509 const base::ListValue
* args
) {
510 std::string country_code
;
511 if (!args
->GetString(0, &country_code
)) {
516 base::DictionaryValue input
;
517 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
518 std::string language_code
;
519 GetAddressComponents(country_code
, g_browser_process
->GetApplicationLocale(),
520 components
.get(), &language_code
);
521 input
.Set(kComponents
, components
.release());
522 input
.SetString(kLanguageCode
, language_code
);
524 web_ui()->CallJavascriptFunction(
525 "AutofillEditAddressOverlay.loadAddressComponents", input
);
528 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue
* args
) {
529 DCHECK(IsPersonalDataLoaded());
532 if (!args
->GetString(0, &guid
)) {
537 CreditCard
* credit_card
= personal_data_
->GetCreditCardByGUID(guid
);
539 // There is a race where a user can click once on the close button and
540 // quickly click again on the list item before the item is removed (since
541 // the list is not updated until the model tells the list an item has been
542 // removed). This will activate the editor for a profile that has been
543 // removed. Do nothing in that case.
547 base::DictionaryValue credit_card_data
;
548 credit_card_data
.SetString("guid", credit_card
->guid());
549 credit_card_data
.SetString(
551 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NAME
));
552 credit_card_data
.SetString(
554 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NUMBER
));
555 credit_card_data
.SetString(
557 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
));
558 credit_card_data
.SetString(
560 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
));
562 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
566 void AutofillOptionsHandler::SetAddress(const base::ListValue
* args
) {
567 if (!IsPersonalDataLoaded())
572 if (!args
->GetString(arg_counter
++, &guid
)) {
577 AutofillProfile
profile(guid
, kSettingsOrigin
);
579 base::string16 value
;
580 const base::ListValue
* list_value
;
581 if (args
->GetList(arg_counter
++, &list_value
))
582 SetValueList(list_value
, autofill::NAME_FULL
, &profile
);
584 if (args
->GetString(arg_counter
++, &value
))
585 profile
.SetRawInfo(autofill::COMPANY_NAME
, value
);
587 if (args
->GetString(arg_counter
++, &value
))
588 profile
.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
, value
);
590 if (args
->GetString(arg_counter
++, &value
))
591 profile
.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
, value
);
593 if (args
->GetString(arg_counter
++, &value
))
594 profile
.SetRawInfo(autofill::ADDRESS_HOME_CITY
, value
);
596 if (args
->GetString(arg_counter
++, &value
))
597 profile
.SetRawInfo(autofill::ADDRESS_HOME_STATE
, value
);
599 if (args
->GetString(arg_counter
++, &value
))
600 profile
.SetRawInfo(autofill::ADDRESS_HOME_ZIP
, value
);
602 if (args
->GetString(arg_counter
++, &value
))
603 profile
.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
, value
);
605 if (args
->GetString(arg_counter
++, &value
))
606 profile
.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY
, value
);
608 if (args
->GetList(arg_counter
++, &list_value
))
609 SetValueList(list_value
, autofill::PHONE_HOME_WHOLE_NUMBER
, &profile
);
611 if (args
->GetList(arg_counter
++, &list_value
))
612 SetValueList(list_value
, autofill::EMAIL_ADDRESS
, &profile
);
614 if (args
->GetString(arg_counter
++, &value
))
615 profile
.set_language_code(base::UTF16ToUTF8(value
));
617 if (!base::IsValidGUID(profile
.guid())) {
618 profile
.set_guid(base::GenerateGUID());
619 personal_data_
->AddProfile(profile
);
621 personal_data_
->UpdateProfile(profile
);
625 void AutofillOptionsHandler::SetCreditCard(const base::ListValue
* args
) {
626 if (!IsPersonalDataLoaded())
630 if (!args
->GetString(0, &guid
)) {
635 CreditCard
credit_card(guid
, kSettingsOrigin
);
637 base::string16 value
;
638 if (args
->GetString(1, &value
))
639 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NAME
, value
);
641 if (args
->GetString(2, &value
))
642 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NUMBER
, value
);
644 if (args
->GetString(3, &value
))
645 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
, value
);
647 if (args
->GetString(4, &value
))
648 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
, value
);
650 if (!base::IsValidGUID(credit_card
.guid())) {
651 credit_card
.set_guid(base::GenerateGUID());
652 personal_data_
->AddCreditCard(credit_card
);
654 personal_data_
->UpdateCreditCard(credit_card
);
658 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue
* args
) {
659 if (!IsPersonalDataLoaded())
662 scoped_ptr
<base::ListValue
> list_value
= ValidatePhoneArguments(args
);
664 web_ui()->CallJavascriptFunction(
665 "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value
);
668 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
669 return personal_data_
&& personal_data_
->IsDataLoaded();
672 } // namespace options