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/command_line.h"
12 #include "base/guid.h"
13 #include "base/logging.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_split.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/values.h"
19 #include "chrome/browser/autofill/options_util.h"
20 #include "chrome/browser/autofill/personal_data_manager_factory.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/sync/profile_sync_service_factory.h"
24 #include "chrome/browser/ui/autofill/country_combobox_model.h"
25 #include "chrome/common/url_constants.h"
26 #include "chrome/grit/chromium_strings.h"
27 #include "chrome/grit/generated_resources.h"
28 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
29 #include "components/autofill/core/browser/autofill_country.h"
30 #include "components/autofill/core/browser/autofill_profile.h"
31 #include "components/autofill/core/browser/credit_card.h"
32 #include "components/autofill/core/browser/personal_data_manager.h"
33 #include "components/autofill/core/browser/phone_number_i18n.h"
34 #include "components/autofill/core/common/autofill_constants.h"
35 #include "components/autofill/core/common/autofill_switches.h"
36 #include "content/public/browser/web_ui.h"
37 #include "grit/components_strings.h"
38 #include "third_party/libaddressinput/messages.h"
39 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h"
40 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h"
41 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/base/webui/web_ui_util.h"
45 using autofill::AutofillCountry
;
46 using autofill::AutofillType
;
47 using autofill::ServerFieldType
;
48 using autofill::AutofillProfile
;
49 using autofill::CreditCard
;
50 using autofill::PersonalDataManager
;
51 using i18n::addressinput::AddressUiComponent
;
55 const char kSettingsOrigin
[] = "Chrome settings";
57 static const char kFullNameField
[] = "fullName";
58 static const char kCompanyNameField
[] = "companyName";
59 static const char kAddressLineField
[] = "addrLines";
60 static const char kDependentLocalityField
[] = "dependentLocality";
61 static const char kCityField
[] = "city";
62 static const char kStateField
[] = "state";
63 static const char kPostalCodeField
[] = "postalCode";
64 static const char kSortingCodeField
[] = "sortingCode";
65 static const char kCountryField
[] = "country";
67 static const char kComponents
[] = "components";
68 static const char kLanguageCode
[] = "languageCode";
70 scoped_ptr
<base::DictionaryValue
> CreditCardToDictionary(
71 const CreditCard
& card
) {
72 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue
);
73 value
->SetString("guid", card
.guid());
74 std::pair
<base::string16
, base::string16
> label_pieces
= card
.LabelPieces();
75 value
->SetString("label", label_pieces
.first
);
76 value
->SetString("sublabel", label_pieces
.second
);
77 value
->SetBoolean("isLocal", card
.record_type() == CreditCard::LOCAL_CARD
);
78 value
->SetBoolean("isCached",
79 card
.record_type() == CreditCard::FULL_SERVER_CARD
);
83 // Fills |components| with the address UI components that should be used to
84 // input an address for |country_code| when UI BCP 47 language code is
85 // |ui_language_code|. If |components_language_code| is not NULL, then sets it
86 // to the BCP 47 language code that should be used to format the address for
88 void GetAddressComponents(const std::string
& country_code
,
89 const std::string
& ui_language_code
,
90 base::ListValue
* address_components
,
91 std::string
* components_language_code
) {
92 DCHECK(address_components
);
94 i18n::addressinput::Localization localization
;
95 localization
.SetGetter(l10n_util::GetStringUTF8
);
97 std::vector
<AddressUiComponent
> components
=
98 i18n::addressinput::BuildComponents(
102 components_language_code
== NULL
?
103 ¬_used
: components_language_code
);
104 if (components
.empty()) {
105 static const char kDefaultCountryCode
[] = "US";
106 components
= i18n::addressinput::BuildComponents(
110 components_language_code
== NULL
?
111 ¬_used
: components_language_code
);
113 DCHECK(!components
.empty());
115 base::ListValue
* line
= NULL
;
116 static const char kField
[] = "field";
117 static const char kLength
[] = "length";
118 for (size_t i
= 0; i
< components
.size(); ++i
) {
120 components
[i
- 1].length_hint
== AddressUiComponent::HINT_LONG
||
121 components
[i
].length_hint
== AddressUiComponent::HINT_LONG
) {
122 line
= new base::ListValue
;
123 address_components
->Append(line
);
126 scoped_ptr
<base::DictionaryValue
> component(new base::DictionaryValue
);
127 component
->SetString("name", components
[i
].name
);
129 switch (components
[i
].field
) {
130 case i18n::addressinput::COUNTRY
:
131 component
->SetString(kField
, kCountryField
);
133 case i18n::addressinput::ADMIN_AREA
:
134 component
->SetString(kField
, kStateField
);
136 case i18n::addressinput::LOCALITY
:
137 component
->SetString(kField
, kCityField
);
139 case i18n::addressinput::DEPENDENT_LOCALITY
:
140 component
->SetString(kField
, kDependentLocalityField
);
142 case i18n::addressinput::SORTING_CODE
:
143 component
->SetString(kField
, kSortingCodeField
);
145 case i18n::addressinput::POSTAL_CODE
:
146 component
->SetString(kField
, kPostalCodeField
);
148 case i18n::addressinput::STREET_ADDRESS
:
149 component
->SetString(kField
, kAddressLineField
);
151 case i18n::addressinput::ORGANIZATION
:
152 component
->SetString(kField
, kCompanyNameField
);
154 case i18n::addressinput::RECIPIENT
:
155 component
->SetString(kField
, kFullNameField
);
156 component
->SetString(
158 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME
));
162 switch (components
[i
].length_hint
) {
163 case AddressUiComponent::HINT_LONG
:
164 component
->SetString(kLength
, "long");
166 case AddressUiComponent::HINT_SHORT
:
167 component
->SetString(kLength
, "short");
171 line
->Append(component
.release());
175 // Sets data related to the country <select>.
176 void SetCountryData(const PersonalDataManager
& manager
,
177 base::DictionaryValue
* localized_strings
) {
178 autofill::CountryComboboxModel model
;
179 model
.SetCountries(manager
, base::Callback
<bool(const std::string
&)>());
180 const std::vector
<AutofillCountry
*>& countries
= model
.countries();
181 localized_strings
->SetString("defaultCountryCode",
182 countries
.front()->country_code());
184 // An ordered list of options to show in the <select>.
185 scoped_ptr
<base::ListValue
> country_list(new base::ListValue());
186 for (size_t i
= 0; i
< countries
.size(); ++i
) {
187 scoped_ptr
<base::DictionaryValue
> option_details(
188 new base::DictionaryValue());
189 option_details
->SetString("name", model
.GetItemAt(i
));
190 option_details
->SetString(
192 countries
[i
] ? countries
[i
]->country_code() : "separator");
193 country_list
->Append(option_details
.release());
195 localized_strings
->Set("autofillCountrySelectList", country_list
.release());
197 scoped_ptr
<base::ListValue
> default_country_components(new base::ListValue
);
198 std::string default_country_language_code
;
199 GetAddressComponents(countries
.front()->country_code(),
200 g_browser_process
->GetApplicationLocale(),
201 default_country_components
.get(),
202 &default_country_language_code
);
203 localized_strings
->Set("autofillDefaultCountryComponents",
204 default_country_components
.release());
205 localized_strings
->SetString("autofillDefaultCountryLanguageCode",
206 default_country_language_code
);
209 // Get the multi-valued element for |type| and return it in |ListValue| form.
210 // Buyer beware: the type of data affects whether GetRawInfo or GetInfo is used.
211 void GetValueList(const AutofillProfile
& profile
,
212 ServerFieldType type
,
213 scoped_ptr
<base::ListValue
>* list
) {
214 list
->reset(new base::ListValue
);
216 std::vector
<base::string16
> values
;
217 if (AutofillType(type
).group() == autofill::NAME
) {
218 profile
.GetMultiInfo(
219 AutofillType(type
), g_browser_process
->GetApplicationLocale(), &values
);
221 profile
.GetRawMultiInfo(type
, &values
);
224 // |Get[Raw]MultiInfo()| always returns at least one, potentially empty, item.
225 if (values
.size() == 1 && values
.front().empty())
228 for (size_t i
= 0; i
< values
.size(); ++i
) {
229 (*list
)->Set(i
, new base::StringValue(values
[i
]));
233 // Converts a ListValue of StringValues to a vector of string16s.
234 void ListValueToStringVector(const base::ListValue
& list
,
235 std::vector
<base::string16
>* output
) {
236 output
->resize(list
.GetSize());
237 for (size_t i
= 0; i
< list
.GetSize(); ++i
) {
238 base::string16 value
;
239 if (list
.GetString(i
, &value
))
240 (*output
)[i
].swap(value
);
244 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
246 void ExtractPhoneNumberInformation(const base::ListValue
* args
,
248 const base::ListValue
** phone_number_list
,
249 std::string
* country_code
) {
250 // Retrieve index as a |double|, as that is how it comes across from
253 if (!args
->GetDouble(0, &number
)) {
259 if (!args
->GetList(1, phone_number_list
)) {
264 if (!args
->GetString(2, country_code
)) {
270 // Searches the |list| for the value at |index|. If this value is present
271 // in any of the rest of the list, then the item (at |index|) is removed.
272 // The comparison of phone number values is done on normalized versions of the
273 // phone number values.
274 void RemoveDuplicatePhoneNumberAtIndex(size_t index
,
275 const std::string
& country_code
,
276 base::ListValue
* list
) {
277 base::string16 new_value
;
278 if (!list
->GetString(index
, &new_value
)) {
279 NOTREACHED() << "List should have a value at index " << index
;
283 bool is_duplicate
= false;
284 std::string app_locale
= g_browser_process
->GetApplicationLocale();
285 for (size_t i
= 0; i
< list
->GetSize() && !is_duplicate
; ++i
) {
289 base::string16 existing_value
;
290 if (!list
->GetString(i
, &existing_value
)) {
291 NOTREACHED() << "List should have a value at index " << i
;
294 is_duplicate
= autofill::i18n::PhoneNumbersMatch(
295 new_value
, existing_value
, country_code
, app_locale
);
299 list
->Remove(index
, NULL
);
302 scoped_ptr
<base::ListValue
> ValidatePhoneArguments(
303 const base::ListValue
* args
) {
305 std::string country_code
;
306 const base::ListValue
* extracted_list
= NULL
;
307 ExtractPhoneNumberInformation(args
, &index
, &extracted_list
, &country_code
);
309 scoped_ptr
<base::ListValue
> list(extracted_list
->DeepCopy());
310 RemoveDuplicatePhoneNumberAtIndex(index
, country_code
, list
.get());
318 AutofillOptionsHandler::AutofillOptionsHandler()
319 : personal_data_(NULL
), observer_(this) {
322 AutofillOptionsHandler::~AutofillOptionsHandler() {
324 personal_data_
->RemoveObserver(this);
327 /////////////////////////////////////////////////////////////////////////////
328 // OptionsPageUIHandler implementation:
329 void AutofillOptionsHandler::GetLocalizedValues(
330 base::DictionaryValue
* localized_strings
) {
331 DCHECK(localized_strings
);
333 static OptionsStringResource resources
[] = {
334 { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME
},
335 { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME
},
336 { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON
},
337 { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON
},
338 { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON
},
339 { "autofillFromGoogleAccount", IDS_AUTOFILL_FROM_GOOGLE_ACCOUNT
},
340 { "autofillDescribeLocalCopy", IDS_AUTOFILL_DESCRIBE_LOCAL_COPY
},
341 { "autofillClearLocalCopyButton", IDS_AUTOFILL_CLEAR_LOCAL_COPY_BUTTON
},
342 { "helpButton", IDS_AUTOFILL_HELP_LABEL
},
343 { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION
},
344 { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
},
345 { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION
},
346 { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
},
347 { "autofillWalletOption", IDS_AUTOFILL_USE_WALLET_DATA
},
348 #if defined(OS_MACOSX)
349 { "auxiliaryProfilesEnabled", IDS_AUTOFILL_USE_MAC_ADDRESS_BOOK
},
350 #endif // defined(OS_MACOSX)
353 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
354 RegisterTitle(localized_strings
, "autofillOptionsPage",
355 IDS_AUTOFILL_OPTIONS_TITLE
);
357 localized_strings
->SetString("helpUrl", autofill::kHelpURL
);
359 personal_data_
= autofill::PersonalDataManagerFactory::GetForProfile(
360 Profile::FromWebUI(web_ui()));
362 SetAddressOverlayStrings(localized_strings
);
363 SetCreditCardOverlayStrings(localized_strings
);
365 localized_strings
->SetString(
366 "manageWalletAddressesUrl",
367 autofill::wallet::GetManageAddressesUrl(0).spec());
368 localized_strings
->SetString(
369 "manageWalletPaymentMethodsUrl",
370 autofill::wallet::GetManageInstrumentsUrl(0).spec());
372 // This is set in loadTimeData to minimize the chance of a load-time flash of
374 ProfileSyncService
* service
=
375 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
376 Profile::FromWebUI(web_ui()));
378 observer_
.Add(service
);
380 localized_strings
->SetBoolean("autofillWalletIntegrationAvailable",
381 autofill::WalletIntegrationAvailableForProfile(
382 Profile::FromWebUI(web_ui())));
385 void AutofillOptionsHandler::InitializeHandler() {
386 // personal_data_ is NULL in guest mode on Chrome OS.
388 personal_data_
->AddObserver(this);
391 void AutofillOptionsHandler::InitializePage() {
395 // Also update the visibility of the Wallet checkbox (which may have
396 // changed since the localized string dictionary was built).
400 void AutofillOptionsHandler::RegisterMessages() {
401 #if defined(OS_MACOSX) && !defined(OS_IOS)
402 web_ui()->RegisterMessageCallback(
404 base::Bind(&AutofillOptionsHandler::AccessAddressBook
,
405 base::Unretained(this)));
406 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
407 web_ui()->RegisterMessageCallback(
409 base::Bind(&AutofillOptionsHandler::RemoveData
,
410 base::Unretained(this)));
411 web_ui()->RegisterMessageCallback(
413 base::Bind(&AutofillOptionsHandler::LoadAddressEditor
,
414 base::Unretained(this)));
415 web_ui()->RegisterMessageCallback(
416 "loadAddressEditorComponents",
417 base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents
,
418 base::Unretained(this)));
419 web_ui()->RegisterMessageCallback(
420 "loadCreditCardEditor",
421 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor
,
422 base::Unretained(this)));
423 web_ui()->RegisterMessageCallback(
425 base::Bind(&AutofillOptionsHandler::SetAddress
, base::Unretained(this)));
426 web_ui()->RegisterMessageCallback(
428 base::Bind(&AutofillOptionsHandler::SetCreditCard
,
429 base::Unretained(this)));
430 web_ui()->RegisterMessageCallback(
431 "validatePhoneNumbers",
432 base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers
,
433 base::Unretained(this)));
434 web_ui()->RegisterMessageCallback(
435 "clearLocalCardCopy",
436 base::Bind(&AutofillOptionsHandler::RemaskServerCard
,
437 base::Unretained(this)));
440 /////////////////////////////////////////////////////////////////////////////
441 // PersonalDataManagerObserver implementation:
442 void AutofillOptionsHandler::OnPersonalDataChanged() {
447 void AutofillOptionsHandler::OnStateChanged() {
448 web_ui()->CallJavascriptFunction(
449 "AutofillOptions.walletIntegrationAvailableStateChanged",
450 base::FundamentalValue(autofill::WalletIntegrationAvailableForProfile(
451 Profile::FromWebUI(web_ui()))));
454 void AutofillOptionsHandler::SetAddressOverlayStrings(
455 base::DictionaryValue
* localized_strings
) {
456 localized_strings
->SetString("autofillEditAddressTitle",
457 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
));
458 localized_strings
->SetString("autofillCountryLabel",
459 l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL
));
460 localized_strings
->SetString("autofillPhoneLabel",
461 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE
));
462 localized_strings
->SetString("autofillEmailLabel",
463 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL
));
464 localized_strings
->SetString("autofillAddPhonePlaceholder",
465 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE
));
466 localized_strings
->SetString("autofillAddEmailPlaceholder",
467 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_EMAIL
));
468 SetCountryData(*personal_data_
, localized_strings
);
471 void AutofillOptionsHandler::SetCreditCardOverlayStrings(
472 base::DictionaryValue
* localized_strings
) {
473 localized_strings
->SetString("autofillEditCreditCardTitle",
474 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
));
475 localized_strings
->SetString("nameOnCardLabel",
476 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD
));
477 localized_strings
->SetString("creditCardNumberLabel",
478 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER
));
479 localized_strings
->SetString("creditCardExpirationDateLabel",
480 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE
));
483 void AutofillOptionsHandler::LoadAutofillData() {
484 if (!IsPersonalDataLoaded())
487 const std::vector
<AutofillProfile
*>& profiles
= personal_data_
->GetProfiles();
488 std::vector
<base::string16
> labels
;
489 AutofillProfile::CreateDifferentiatingLabels(
491 g_browser_process
->GetApplicationLocale(),
493 DCHECK_EQ(labels
.size(), profiles
.size());
495 base::ListValue addresses
;
496 for (size_t i
= 0; i
< profiles
.size(); ++i
) {
497 // Skip showing auxiliary profiles (e.g. Mac Contacts) for now.
498 if (profiles
[i
]->record_type() == AutofillProfile::AUXILIARY_PROFILE
)
501 base::string16 separator
=
502 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR
);
503 std::vector
<base::string16
> label_parts
;
504 base::SplitStringUsingSubstr(labels
[i
], separator
, &label_parts
);
506 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue
);
507 value
->SetString("guid", profiles
[i
]->guid());
508 value
->SetString("label", label_parts
[0]);
509 value
->SetString("sublabel", labels
[i
].substr(label_parts
[0].size()));
510 value
->SetBoolean("isLocal", profiles
[i
]->record_type() ==
511 AutofillProfile::LOCAL_PROFILE
);
512 addresses
.Append(value
.release());
515 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses
);
517 base::ListValue credit_cards
;
518 const std::vector
<CreditCard
*>& cards
= personal_data_
->GetCreditCards();
519 for (const CreditCard
* card
: cards
) {
520 credit_cards
.Append(CreditCardToDictionary(*card
).release());
523 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
527 #if defined(OS_MACOSX) && !defined(OS_IOS)
528 void AutofillOptionsHandler::AccessAddressBook(const base::ListValue
* args
) {
529 personal_data_
->AccessAddressBook();
531 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
533 void AutofillOptionsHandler::RemoveData(const base::ListValue
* args
) {
534 DCHECK(IsPersonalDataLoaded());
537 if (!args
->GetString(0, &guid
)) {
542 personal_data_
->RemoveByGUID(guid
);
545 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue
* args
) {
546 DCHECK(IsPersonalDataLoaded());
549 if (!args
->GetString(0, &guid
)) {
554 AutofillProfile
* profile
= personal_data_
->GetProfileByGUID(guid
);
556 // There is a race where a user can click once on the close button and
557 // quickly click again on the list item before the item is removed (since
558 // the list is not updated until the model tells the list an item has been
559 // removed). This will activate the editor for a profile that has been
560 // removed. Do nothing in that case.
564 base::DictionaryValue address
;
565 AutofillProfileToDictionary(*profile
, &address
);
567 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address
);
570 void AutofillOptionsHandler::LoadAddressEditorComponents(
571 const base::ListValue
* args
) {
572 std::string country_code
;
573 if (!args
->GetString(0, &country_code
)) {
578 base::DictionaryValue input
;
579 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
580 std::string language_code
;
581 GetAddressComponents(country_code
, g_browser_process
->GetApplicationLocale(),
582 components
.get(), &language_code
);
583 input
.Set(kComponents
, components
.release());
584 input
.SetString(kLanguageCode
, language_code
);
586 web_ui()->CallJavascriptFunction(
587 "AutofillEditAddressOverlay.loadAddressComponents", input
);
590 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue
* args
) {
591 DCHECK(IsPersonalDataLoaded());
594 if (!args
->GetString(0, &guid
)) {
599 CreditCard
* credit_card
= personal_data_
->GetCreditCardByGUID(guid
);
601 // There is a race where a user can click once on the close button and
602 // quickly click again on the list item before the item is removed (since
603 // the list is not updated until the model tells the list an item has been
604 // removed). This will activate the editor for a profile that has been
605 // removed. Do nothing in that case.
609 base::DictionaryValue credit_card_data
;
610 credit_card_data
.SetString("guid", credit_card
->guid());
611 credit_card_data
.SetString(
613 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NAME
));
614 credit_card_data
.SetString(
616 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NUMBER
));
617 credit_card_data
.SetString(
619 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
));
620 credit_card_data
.SetString(
622 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
));
624 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
628 void AutofillOptionsHandler::SetAddress(const base::ListValue
* args
) {
629 if (!IsPersonalDataLoaded())
634 if (!args
->GetString(arg_counter
++, &guid
)) {
639 AutofillProfile
profile(guid
, kSettingsOrigin
);
641 base::string16 value
;
642 const base::ListValue
* list_value
;
643 if (args
->GetList(arg_counter
++, &list_value
)) {
644 std::vector
<base::string16
> values
;
645 ListValueToStringVector(*list_value
, &values
);
646 AutofillProfile
* old_profile
= personal_data_
->GetProfileByGUID(guid
);
647 profile
.CopyAndUpdateNameList(values
, old_profile
,
648 g_browser_process
->GetApplicationLocale());
651 if (args
->GetString(arg_counter
++, &value
))
652 profile
.SetRawInfo(autofill::COMPANY_NAME
, value
);
654 if (args
->GetString(arg_counter
++, &value
))
655 profile
.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
, value
);
657 if (args
->GetString(arg_counter
++, &value
))
658 profile
.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
, value
);
660 if (args
->GetString(arg_counter
++, &value
))
661 profile
.SetRawInfo(autofill::ADDRESS_HOME_CITY
, value
);
663 if (args
->GetString(arg_counter
++, &value
))
664 profile
.SetRawInfo(autofill::ADDRESS_HOME_STATE
, value
);
666 if (args
->GetString(arg_counter
++, &value
))
667 profile
.SetRawInfo(autofill::ADDRESS_HOME_ZIP
, value
);
669 if (args
->GetString(arg_counter
++, &value
))
670 profile
.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
, value
);
672 if (args
->GetString(arg_counter
++, &value
))
673 profile
.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY
, value
);
675 if (args
->GetList(arg_counter
++, &list_value
)) {
676 std::vector
<base::string16
> values
;
677 ListValueToStringVector(*list_value
, &values
);
678 profile
.SetRawMultiInfo(autofill::PHONE_HOME_WHOLE_NUMBER
, values
);
681 if (args
->GetList(arg_counter
++, &list_value
)) {
682 std::vector
<base::string16
> values
;
683 ListValueToStringVector(*list_value
, &values
);
684 profile
.SetRawMultiInfo(autofill::EMAIL_ADDRESS
, values
);
687 if (args
->GetString(arg_counter
++, &value
))
688 profile
.set_language_code(base::UTF16ToUTF8(value
));
690 if (!base::IsValidGUID(profile
.guid())) {
691 profile
.set_guid(base::GenerateGUID());
692 personal_data_
->AddProfile(profile
);
694 personal_data_
->UpdateProfile(profile
);
698 void AutofillOptionsHandler::SetCreditCard(const base::ListValue
* args
) {
699 if (!IsPersonalDataLoaded())
703 if (!args
->GetString(0, &guid
)) {
708 CreditCard
credit_card(guid
, kSettingsOrigin
);
710 base::string16 value
;
711 if (args
->GetString(1, &value
))
712 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NAME
, value
);
714 if (args
->GetString(2, &value
))
715 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NUMBER
, value
);
717 if (args
->GetString(3, &value
))
718 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
, value
);
720 if (args
->GetString(4, &value
))
721 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
, value
);
723 if (!base::IsValidGUID(credit_card
.guid())) {
724 credit_card
.set_guid(base::GenerateGUID());
725 personal_data_
->AddCreditCard(credit_card
);
727 personal_data_
->UpdateCreditCard(credit_card
);
731 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue
* args
) {
732 if (!IsPersonalDataLoaded())
735 scoped_ptr
<base::ListValue
> list_value
= ValidatePhoneArguments(args
);
737 web_ui()->CallJavascriptFunction(
738 "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value
);
741 void AutofillOptionsHandler::RemaskServerCard(const base::ListValue
* args
) {
743 if (!args
->GetString(0, &guid
)) {
748 personal_data_
->ResetFullServerCard(guid
);
751 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
752 return personal_data_
&& personal_data_
->IsDataLoaded();
756 void AutofillOptionsHandler::AutofillProfileToDictionary(
757 const autofill::AutofillProfile
& profile
,
758 base::DictionaryValue
* address
) {
759 address
->SetString("guid", profile
.guid());
760 scoped_ptr
<base::ListValue
> list
;
761 GetValueList(profile
, autofill::NAME_FULL
, &list
);
762 address
->Set(kFullNameField
, list
.release());
763 address
->SetString(kCompanyNameField
,
764 profile
.GetRawInfo(autofill::COMPANY_NAME
));
765 address
->SetString(kAddressLineField
,
766 profile
.GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
));
767 address
->SetString(kCityField
,
768 profile
.GetRawInfo(autofill::ADDRESS_HOME_CITY
));
769 address
->SetString(kStateField
,
770 profile
.GetRawInfo(autofill::ADDRESS_HOME_STATE
));
772 kDependentLocalityField
,
773 profile
.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
));
774 address
->SetString(kSortingCodeField
,
775 profile
.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
));
776 address
->SetString(kPostalCodeField
,
777 profile
.GetRawInfo(autofill::ADDRESS_HOME_ZIP
));
778 address
->SetString(kCountryField
,
779 profile
.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
));
780 GetValueList(profile
, autofill::PHONE_HOME_WHOLE_NUMBER
, &list
);
781 address
->Set("phone", list
.release());
782 GetValueList(profile
, autofill::EMAIL_ADDRESS
, &list
);
783 address
->Set("email", list
.release());
784 address
->SetString(kLanguageCode
, profile
.language_code());
786 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
787 GetAddressComponents(
788 base::UTF16ToUTF8(profile
.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
)),
789 profile
.language_code(),
792 address
->Set(kComponents
, components
.release());
795 } // namespace options