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
);
159 switch (components
[i
].length_hint
) {
160 case AddressUiComponent::HINT_LONG
:
161 component
->SetString(kLength
, "long");
163 case AddressUiComponent::HINT_SHORT
:
164 component
->SetString(kLength
, "short");
168 line
->Append(component
.release());
172 // Sets data related to the country <select>.
173 void SetCountryData(const PersonalDataManager
& manager
,
174 base::DictionaryValue
* localized_strings
) {
175 autofill::CountryComboboxModel model
;
176 model
.SetCountries(manager
, base::Callback
<bool(const std::string
&)>());
177 const std::vector
<AutofillCountry
*>& countries
= model
.countries();
178 localized_strings
->SetString("defaultCountryCode",
179 countries
.front()->country_code());
181 // An ordered list of options to show in the <select>.
182 scoped_ptr
<base::ListValue
> country_list(new base::ListValue());
183 for (size_t i
= 0; i
< countries
.size(); ++i
) {
184 scoped_ptr
<base::DictionaryValue
> option_details(
185 new base::DictionaryValue());
186 option_details
->SetString("name", model
.GetItemAt(i
));
187 option_details
->SetString(
189 countries
[i
] ? countries
[i
]->country_code() : "separator");
190 country_list
->Append(option_details
.release());
192 localized_strings
->Set("autofillCountrySelectList", country_list
.release());
194 scoped_ptr
<base::ListValue
> default_country_components(new base::ListValue
);
195 std::string default_country_language_code
;
196 GetAddressComponents(countries
.front()->country_code(),
197 g_browser_process
->GetApplicationLocale(),
198 default_country_components
.get(),
199 &default_country_language_code
);
200 localized_strings
->Set("autofillDefaultCountryComponents",
201 default_country_components
.release());
202 localized_strings
->SetString("autofillDefaultCountryLanguageCode",
203 default_country_language_code
);
210 AutofillOptionsHandler::AutofillOptionsHandler()
211 : personal_data_(NULL
), observer_(this) {
214 AutofillOptionsHandler::~AutofillOptionsHandler() {
216 personal_data_
->RemoveObserver(this);
219 /////////////////////////////////////////////////////////////////////////////
220 // OptionsPageUIHandler implementation:
221 void AutofillOptionsHandler::GetLocalizedValues(
222 base::DictionaryValue
* localized_strings
) {
223 DCHECK(localized_strings
);
225 static OptionsStringResource resources
[] = {
226 { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME
},
227 { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME
},
228 { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON
},
229 { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON
},
230 { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON
},
231 { "autofillFromGoogleAccount", IDS_AUTOFILL_FROM_GOOGLE_ACCOUNT
},
232 { "autofillDescribeLocalCopy", IDS_AUTOFILL_DESCRIBE_LOCAL_COPY
},
233 { "autofillClearLocalCopyButton", IDS_AUTOFILL_CLEAR_LOCAL_COPY_BUTTON
},
234 { "helpButton", IDS_AUTOFILL_HELP_LABEL
},
235 { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION
},
236 { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
},
237 { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION
},
238 { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
},
239 { "autofillWalletOption", IDS_AUTOFILL_USE_WALLET_DATA
},
242 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
243 RegisterTitle(localized_strings
, "autofillOptionsPage",
244 IDS_AUTOFILL_OPTIONS_TITLE
);
246 localized_strings
->SetString("helpUrl", autofill::kHelpURL
);
248 personal_data_
= autofill::PersonalDataManagerFactory::GetForProfile(
249 Profile::FromWebUI(web_ui()));
251 SetAddressOverlayStrings(localized_strings
);
252 SetCreditCardOverlayStrings(localized_strings
);
254 localized_strings
->SetString(
255 "manageWalletAddressesUrl",
256 autofill::wallet::GetManageAddressesUrl(0).spec());
257 localized_strings
->SetString(
258 "manageWalletPaymentMethodsUrl",
259 autofill::wallet::GetManageInstrumentsUrl(0).spec());
261 // This is set in loadTimeData to minimize the chance of a load-time flash of
263 ProfileSyncService
* service
=
264 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
265 Profile::FromWebUI(web_ui()));
267 observer_
.Add(service
);
269 localized_strings
->SetBoolean("autofillWalletIntegrationAvailable",
270 autofill::WalletIntegrationAvailableForProfile(
271 Profile::FromWebUI(web_ui())));
274 void AutofillOptionsHandler::InitializeHandler() {
275 // personal_data_ is NULL in guest mode on Chrome OS.
277 personal_data_
->AddObserver(this);
280 void AutofillOptionsHandler::InitializePage() {
284 // Also update the visibility of the Wallet checkbox (which may have
285 // changed since the localized string dictionary was built).
289 void AutofillOptionsHandler::RegisterMessages() {
290 web_ui()->RegisterMessageCallback(
292 base::Bind(&AutofillOptionsHandler::RemoveData
,
293 base::Unretained(this)));
294 web_ui()->RegisterMessageCallback(
296 base::Bind(&AutofillOptionsHandler::LoadAddressEditor
,
297 base::Unretained(this)));
298 web_ui()->RegisterMessageCallback(
299 "loadAddressEditorComponents",
300 base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents
,
301 base::Unretained(this)));
302 web_ui()->RegisterMessageCallback(
303 "loadCreditCardEditor",
304 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor
,
305 base::Unretained(this)));
306 web_ui()->RegisterMessageCallback(
308 base::Bind(&AutofillOptionsHandler::SetAddress
, base::Unretained(this)));
309 web_ui()->RegisterMessageCallback(
311 base::Bind(&AutofillOptionsHandler::SetCreditCard
,
312 base::Unretained(this)));
313 web_ui()->RegisterMessageCallback(
314 "clearLocalCardCopy",
315 base::Bind(&AutofillOptionsHandler::RemaskServerCard
,
316 base::Unretained(this)));
319 /////////////////////////////////////////////////////////////////////////////
320 // PersonalDataManagerObserver implementation:
321 void AutofillOptionsHandler::OnPersonalDataChanged() {
326 void AutofillOptionsHandler::OnStateChanged() {
327 web_ui()->CallJavascriptFunction(
328 "AutofillOptions.walletIntegrationAvailableStateChanged",
329 base::FundamentalValue(autofill::WalletIntegrationAvailableForProfile(
330 Profile::FromWebUI(web_ui()))));
333 void AutofillOptionsHandler::SetAddressOverlayStrings(
334 base::DictionaryValue
* localized_strings
) {
335 localized_strings
->SetString("autofillEditAddressTitle",
336 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
));
337 localized_strings
->SetString("autofillCountryLabel",
338 l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL
));
339 localized_strings
->SetString("autofillPhoneLabel",
340 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE
));
341 localized_strings
->SetString("autofillEmailLabel",
342 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL
));
343 SetCountryData(*personal_data_
, localized_strings
);
346 void AutofillOptionsHandler::SetCreditCardOverlayStrings(
347 base::DictionaryValue
* localized_strings
) {
348 localized_strings
->SetString("autofillEditCreditCardTitle",
349 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
));
350 localized_strings
->SetString("nameOnCardLabel",
351 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD
));
352 localized_strings
->SetString("creditCardNumberLabel",
353 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER
));
354 localized_strings
->SetString("creditCardExpirationDateLabel",
355 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE
));
358 void AutofillOptionsHandler::LoadAutofillData() {
359 if (!IsPersonalDataLoaded())
362 const std::vector
<AutofillProfile
*>& profiles
= personal_data_
->GetProfiles();
363 std::vector
<base::string16
> labels
;
364 AutofillProfile::CreateDifferentiatingLabels(
366 g_browser_process
->GetApplicationLocale(),
368 DCHECK_EQ(labels
.size(), profiles
.size());
370 base::ListValue addresses
;
371 for (size_t i
= 0; i
< profiles
.size(); ++i
) {
372 // Skip showing auxiliary profiles (e.g. Mac Contacts) for now.
373 if (profiles
[i
]->record_type() == AutofillProfile::AUXILIARY_PROFILE
)
376 base::string16 separator
=
377 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR
);
378 std::vector
<base::string16
> label_parts
;
379 base::SplitStringUsingSubstr(labels
[i
], separator
, &label_parts
);
381 scoped_ptr
<base::DictionaryValue
> value(new base::DictionaryValue
);
382 value
->SetString("guid", profiles
[i
]->guid());
383 value
->SetString("label", label_parts
[0]);
384 value
->SetString("sublabel", labels
[i
].substr(label_parts
[0].size()));
385 value
->SetBoolean("isLocal", profiles
[i
]->record_type() ==
386 AutofillProfile::LOCAL_PROFILE
);
387 addresses
.Append(value
.release());
390 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses
);
392 base::ListValue credit_cards
;
393 const std::vector
<CreditCard
*>& cards
= personal_data_
->GetCreditCards();
394 for (const CreditCard
* card
: cards
) {
395 credit_cards
.Append(CreditCardToDictionary(*card
).release());
398 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
402 void AutofillOptionsHandler::RemoveData(const base::ListValue
* args
) {
403 DCHECK(IsPersonalDataLoaded());
406 if (!args
->GetString(0, &guid
)) {
411 personal_data_
->RemoveByGUID(guid
);
414 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue
* args
) {
415 DCHECK(IsPersonalDataLoaded());
418 if (!args
->GetString(0, &guid
)) {
423 AutofillProfile
* profile
= personal_data_
->GetProfileByGUID(guid
);
425 // There is a race where a user can click once on the close button and
426 // quickly click again on the list item before the item is removed (since
427 // the list is not updated until the model tells the list an item has been
428 // removed). This will activate the editor for a profile that has been
429 // removed. Do nothing in that case.
433 base::DictionaryValue address
;
434 AutofillProfileToDictionary(*profile
, &address
);
436 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address
);
439 void AutofillOptionsHandler::LoadAddressEditorComponents(
440 const base::ListValue
* args
) {
441 std::string country_code
;
442 if (!args
->GetString(0, &country_code
)) {
447 base::DictionaryValue input
;
448 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
449 std::string language_code
;
450 GetAddressComponents(country_code
, g_browser_process
->GetApplicationLocale(),
451 components
.get(), &language_code
);
452 input
.Set(kComponents
, components
.release());
453 input
.SetString(kLanguageCode
, language_code
);
455 web_ui()->CallJavascriptFunction(
456 "AutofillEditAddressOverlay.loadAddressComponents", input
);
459 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue
* args
) {
460 DCHECK(IsPersonalDataLoaded());
463 if (!args
->GetString(0, &guid
)) {
468 CreditCard
* credit_card
= personal_data_
->GetCreditCardByGUID(guid
);
470 // There is a race where a user can click once on the close button and
471 // quickly click again on the list item before the item is removed (since
472 // the list is not updated until the model tells the list an item has been
473 // removed). This will activate the editor for a profile that has been
474 // removed. Do nothing in that case.
478 base::DictionaryValue credit_card_data
;
479 credit_card_data
.SetString("guid", credit_card
->guid());
480 credit_card_data
.SetString(
482 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NAME
));
483 credit_card_data
.SetString(
485 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NUMBER
));
486 credit_card_data
.SetString(
488 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
));
489 credit_card_data
.SetString(
491 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
));
493 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
497 void AutofillOptionsHandler::SetAddress(const base::ListValue
* args
) {
498 if (!IsPersonalDataLoaded())
503 if (!args
->GetString(arg_counter
++, &guid
)) {
508 AutofillProfile
profile(guid
, kSettingsOrigin
);
510 base::string16 value
;
511 if (args
->GetString(arg_counter
++, &value
)) {
512 profile
.SetInfo(AutofillType(autofill::NAME_FULL
), value
,
513 g_browser_process
->GetApplicationLocale());
516 if (args
->GetString(arg_counter
++, &value
))
517 profile
.SetRawInfo(autofill::COMPANY_NAME
, value
);
519 if (args
->GetString(arg_counter
++, &value
))
520 profile
.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
, value
);
522 if (args
->GetString(arg_counter
++, &value
))
523 profile
.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
, value
);
525 if (args
->GetString(arg_counter
++, &value
))
526 profile
.SetRawInfo(autofill::ADDRESS_HOME_CITY
, value
);
528 if (args
->GetString(arg_counter
++, &value
))
529 profile
.SetRawInfo(autofill::ADDRESS_HOME_STATE
, value
);
531 if (args
->GetString(arg_counter
++, &value
))
532 profile
.SetRawInfo(autofill::ADDRESS_HOME_ZIP
, value
);
534 if (args
->GetString(arg_counter
++, &value
))
535 profile
.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
, value
);
537 if (args
->GetString(arg_counter
++, &value
))
538 profile
.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY
, value
);
540 if (args
->GetString(arg_counter
++, &value
))
541 profile
.SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER
, value
);
543 if (args
->GetString(arg_counter
++, &value
))
544 profile
.SetRawInfo(autofill::EMAIL_ADDRESS
, value
);
546 if (args
->GetString(arg_counter
++, &value
))
547 profile
.set_language_code(base::UTF16ToUTF8(value
));
549 if (!base::IsValidGUID(profile
.guid())) {
550 profile
.set_guid(base::GenerateGUID());
551 personal_data_
->AddProfile(profile
);
553 personal_data_
->UpdateProfile(profile
);
557 void AutofillOptionsHandler::SetCreditCard(const base::ListValue
* args
) {
558 if (!IsPersonalDataLoaded())
562 if (!args
->GetString(0, &guid
)) {
567 CreditCard
credit_card(guid
, kSettingsOrigin
);
569 base::string16 value
;
570 if (args
->GetString(1, &value
))
571 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NAME
, value
);
573 if (args
->GetString(2, &value
))
574 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NUMBER
, value
);
576 if (args
->GetString(3, &value
))
577 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
, value
);
579 if (args
->GetString(4, &value
))
580 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
, value
);
582 if (!base::IsValidGUID(credit_card
.guid())) {
583 credit_card
.set_guid(base::GenerateGUID());
584 personal_data_
->AddCreditCard(credit_card
);
586 personal_data_
->UpdateCreditCard(credit_card
);
590 void AutofillOptionsHandler::RemaskServerCard(const base::ListValue
* args
) {
592 if (!args
->GetString(0, &guid
)) {
597 personal_data_
->ResetFullServerCard(guid
);
600 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
601 return personal_data_
&& personal_data_
->IsDataLoaded();
605 void AutofillOptionsHandler::AutofillProfileToDictionary(
606 const autofill::AutofillProfile
& profile
,
607 base::DictionaryValue
* address
) {
608 address
->SetString("guid", profile
.guid());
611 profile
.GetInfo(AutofillType(autofill::NAME_FULL
),
612 g_browser_process
->GetApplicationLocale()));
613 address
->SetString(kCompanyNameField
,
614 profile
.GetRawInfo(autofill::COMPANY_NAME
));
615 address
->SetString(kAddressLineField
,
616 profile
.GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
));
617 address
->SetString(kCityField
,
618 profile
.GetRawInfo(autofill::ADDRESS_HOME_CITY
));
619 address
->SetString(kStateField
,
620 profile
.GetRawInfo(autofill::ADDRESS_HOME_STATE
));
622 kDependentLocalityField
,
623 profile
.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
));
624 address
->SetString(kSortingCodeField
,
625 profile
.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
));
626 address
->SetString(kPostalCodeField
,
627 profile
.GetRawInfo(autofill::ADDRESS_HOME_ZIP
));
628 address
->SetString(kCountryField
,
629 profile
.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
));
630 address
->SetString("phone",
631 profile
.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER
));
632 address
->SetString("email", profile
.GetRawInfo(autofill::EMAIL_ADDRESS
));
633 address
->SetString(kLanguageCode
, profile
.language_code());
635 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
636 GetAddressComponents(
637 base::UTF16ToUTF8(profile
.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
)),
638 profile
.language_code(),
641 address
->Set(kComponents
, components
.release());
644 } // namespace options