Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / autofill_options_handler.cc
blob84540adf70ce46cfb007f5208844f769d95cacfa
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/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;
53 namespace {
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);
80 return value.Pass();
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
87 // display.
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);
96 std::string not_used;
97 std::vector<AddressUiComponent> components =
98 i18n::addressinput::BuildComponents(
99 country_code,
100 localization,
101 ui_language_code,
102 components_language_code == NULL ?
103 &not_used : components_language_code);
104 if (components.empty()) {
105 static const char kDefaultCountryCode[] = "US";
106 components = i18n::addressinput::BuildComponents(
107 kDefaultCountryCode,
108 localization,
109 ui_language_code,
110 components_language_code == NULL ?
111 &not_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) {
119 if (i == 0 ||
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);
132 break;
133 case i18n::addressinput::ADMIN_AREA:
134 component->SetString(kField, kStateField);
135 break;
136 case i18n::addressinput::LOCALITY:
137 component->SetString(kField, kCityField);
138 break;
139 case i18n::addressinput::DEPENDENT_LOCALITY:
140 component->SetString(kField, kDependentLocalityField);
141 break;
142 case i18n::addressinput::SORTING_CODE:
143 component->SetString(kField, kSortingCodeField);
144 break;
145 case i18n::addressinput::POSTAL_CODE:
146 component->SetString(kField, kPostalCodeField);
147 break;
148 case i18n::addressinput::STREET_ADDRESS:
149 component->SetString(kField, kAddressLineField);
150 break;
151 case i18n::addressinput::ORGANIZATION:
152 component->SetString(kField, kCompanyNameField);
153 break;
154 case i18n::addressinput::RECIPIENT:
155 component->SetString(kField, kFullNameField);
156 break;
159 switch (components[i].length_hint) {
160 case AddressUiComponent::HINT_LONG:
161 component->SetString(kLength, "long");
162 break;
163 case AddressUiComponent::HINT_SHORT:
164 component->SetString(kLength, "short");
165 break;
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(
188 "value",
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);
206 } // namespace
208 namespace options {
210 AutofillOptionsHandler::AutofillOptionsHandler()
211 : personal_data_(NULL), observer_(this) {
214 AutofillOptionsHandler::~AutofillOptionsHandler() {
215 if (personal_data_)
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
262 // content.
263 ProfileSyncService* service =
264 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
265 Profile::FromWebUI(web_ui()));
266 if (service)
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.
276 if (personal_data_)
277 personal_data_->AddObserver(this);
280 void AutofillOptionsHandler::InitializePage() {
281 if (personal_data_)
282 LoadAutofillData();
284 // Also update the visibility of the Wallet checkbox (which may have
285 // changed since the localized string dictionary was built).
286 OnStateChanged();
289 void AutofillOptionsHandler::RegisterMessages() {
290 web_ui()->RegisterMessageCallback(
291 "removeData",
292 base::Bind(&AutofillOptionsHandler::RemoveData,
293 base::Unretained(this)));
294 web_ui()->RegisterMessageCallback(
295 "loadAddressEditor",
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(
307 "setAddress",
308 base::Bind(&AutofillOptionsHandler::SetAddress, base::Unretained(this)));
309 web_ui()->RegisterMessageCallback(
310 "setCreditCard",
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() {
322 LoadAutofillData();
323 OnStateChanged();
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())
360 return;
362 const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
363 std::vector<base::string16> labels;
364 AutofillProfile::CreateDifferentiatingLabels(
365 profiles,
366 g_browser_process->GetApplicationLocale(),
367 &labels);
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)
374 continue;
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",
399 credit_cards);
402 void AutofillOptionsHandler::RemoveData(const base::ListValue* args) {
403 DCHECK(IsPersonalDataLoaded());
405 std::string guid;
406 if (!args->GetString(0, &guid)) {
407 NOTREACHED();
408 return;
411 personal_data_->RemoveByGUID(guid);
414 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue* args) {
415 DCHECK(IsPersonalDataLoaded());
417 std::string guid;
418 if (!args->GetString(0, &guid)) {
419 NOTREACHED();
420 return;
423 AutofillProfile* profile = personal_data_->GetProfileByGUID(guid);
424 if (!profile) {
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.
430 return;
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)) {
443 NOTREACHED();
444 return;
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());
462 std::string guid;
463 if (!args->GetString(0, &guid)) {
464 NOTREACHED();
465 return;
468 CreditCard* credit_card = personal_data_->GetCreditCardByGUID(guid);
469 if (!credit_card) {
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.
475 return;
478 base::DictionaryValue credit_card_data;
479 credit_card_data.SetString("guid", credit_card->guid());
480 credit_card_data.SetString(
481 "nameOnCard",
482 credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME));
483 credit_card_data.SetString(
484 "creditCardNumber",
485 credit_card->GetRawInfo(autofill::CREDIT_CARD_NUMBER));
486 credit_card_data.SetString(
487 "expirationMonth",
488 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH));
489 credit_card_data.SetString(
490 "expirationYear",
491 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR));
493 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
494 credit_card_data);
497 void AutofillOptionsHandler::SetAddress(const base::ListValue* args) {
498 if (!IsPersonalDataLoaded())
499 return;
501 int arg_counter = 0;
502 std::string guid;
503 if (!args->GetString(arg_counter++, &guid)) {
504 NOTREACHED();
505 return;
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);
552 } else {
553 personal_data_->UpdateProfile(profile);
557 void AutofillOptionsHandler::SetCreditCard(const base::ListValue* args) {
558 if (!IsPersonalDataLoaded())
559 return;
561 std::string guid;
562 if (!args->GetString(0, &guid)) {
563 NOTREACHED();
564 return;
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);
585 } else {
586 personal_data_->UpdateCreditCard(credit_card);
590 void AutofillOptionsHandler::RemaskServerCard(const base::ListValue* args) {
591 std::string guid;
592 if (!args->GetString(0, &guid)) {
593 NOTREACHED();
594 return;
597 personal_data_->ResetFullServerCard(guid);
600 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
601 return personal_data_ && personal_data_->IsDataLoaded();
604 // static
605 void AutofillOptionsHandler::AutofillProfileToDictionary(
606 const autofill::AutofillProfile& profile,
607 base::DictionaryValue* address) {
608 address->SetString("guid", profile.guid());
609 address->SetString(
610 kFullNameField,
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));
621 address->SetString(
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(),
639 components.get(),
640 NULL);
641 address->Set(kComponents, components.release());
644 } // namespace options