Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / autofill_options_handler.cc
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.
4
5 #include "chrome/browser/ui/webui/options/autofill_options_handler.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/guid.h"
12 #include "base/logging.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "chrome/browser/autofill/personal_data_manager_factory.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/autofill/country_combobox_model.h"
21 #include "chrome/common/url_constants.h"
22 #include "components/autofill/core/browser/autofill_country.h"
23 #include "components/autofill/core/browser/autofill_profile.h"
24 #include "components/autofill/core/browser/credit_card.h"
25 #include "components/autofill/core/browser/personal_data_manager.h"
26 #include "components/autofill/core/browser/phone_number_i18n.h"
27 #include "components/autofill/core/common/autofill_constants.h"
28 #include "content/public/browser/web_ui.h"
29 #include "grit/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"
36
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;
43
44 namespace {
45
46 const char kSettingsOrigin[] = "Chrome settings";
47
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";
57
58 static const char kComponents[] = "components";
59 static const char kLanguageCode[] = "languageCode";
60
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
65 // display.
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);
71
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);
79   }
80   DCHECK(!components.empty());
81
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) {
86     if (i == 0 ||
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);
91     }
92
93     scoped_ptr<base::DictionaryValue> component(new base::DictionaryValue);
94     component->SetString(
95         "name", l10n_util::GetStringUTF16(components[i].name_id));
96
97     switch (components[i].field) {
98       case i18n::addressinput::COUNTRY:
99         component->SetString(kField, kCountryField);
100         break;
101       case i18n::addressinput::ADMIN_AREA:
102         component->SetString(kField, kStateField);
103         break;
104       case i18n::addressinput::LOCALITY:
105         component->SetString(kField, kCityField);
106         break;
107       case i18n::addressinput::DEPENDENT_LOCALITY:
108         component->SetString(kField, kDependentLocalityField);
109         break;
110       case i18n::addressinput::SORTING_CODE:
111         component->SetString(kField, kSortingCodeField);
112         break;
113       case i18n::addressinput::POSTAL_CODE:
114         component->SetString(kField, kPostalCodeField);
115         break;
116       case i18n::addressinput::STREET_ADDRESS:
117         component->SetString(kField, kAddressLineField);
118         break;
119       case i18n::addressinput::ORGANIZATION:
120         component->SetString(kField, kCompanyNameField);
121         break;
122       case i18n::addressinput::RECIPIENT:
123         component->SetString(kField, kFullNameField);
124         component->SetString(
125             "placeholder",
126             l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME));
127         break;
128     }
129
130     switch (components[i].length_hint) {
131       case AddressUiComponent::HINT_LONG:
132         component->SetString(kLength, "long");
133         break;
134       case AddressUiComponent::HINT_SHORT:
135         component->SetString(kLength, "short");
136         break;
137     }
138
139     line->Append(component.release());
140   }
141 }
142
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());
151
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(
159         "value",
160         countries[i] ? countries[i]->country_code() : "separator");
161     country_list->Append(option_details.release());
162   }
163   localized_strings->Set("autofillCountrySelectList", country_list.release());
164
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);
175 }
176
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);
182
183   std::vector<base::string16> values;
184   profile.GetRawMultiInfo(type, &values);
185
186   // |GetRawMultiInfo()| always returns at least one, potentially empty, item.
187   if (values.size() == 1 && values.front().empty())
188     return;
189
190   for (size_t i = 0; i < values.size(); ++i) {
191     (*list)->Set(i, new base::StringValue(values[i]));
192   }
193 }
194
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))
203       values[i] = value;
204   }
205   profile->SetRawMultiInfo(type, values);
206 }
207
208 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
209 // the |args| input.
210 void ExtractPhoneNumberInformation(const base::ListValue* args,
211                                    size_t* index,
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
215   // JavaScript.
216   double number = 0.0;
217   if (!args->GetDouble(0, &number)) {
218     NOTREACHED();
219     return;
220   }
221   *index = number;
222
223   if (!args->GetList(1, phone_number_list)) {
224     NOTREACHED();
225     return;
226   }
227
228   if (!args->GetString(2, country_code)) {
229     NOTREACHED();
230     return;
231   }
232 }
233
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;
244     return;
245   }
246
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) {
250     if (i == index)
251       continue;
252
253     base::string16 existing_value;
254     if (!list->GetString(i, &existing_value)) {
255       NOTREACHED() << "List should have a value at index " << i;
256       continue;
257     }
258     is_duplicate = autofill::i18n::PhoneNumbersMatch(
259         new_value, existing_value, country_code, app_locale);
260   }
261
262   if (is_duplicate)
263     list->Remove(index, NULL);
264 }
265
266 scoped_ptr<base::ListValue> ValidatePhoneArguments(
267     const base::ListValue* args) {
268   size_t index = 0;
269   std::string country_code;
270   const base::ListValue* extracted_list = NULL;
271   ExtractPhoneNumberInformation(args, &index, &extracted_list, &country_code);
272
273   scoped_ptr<base::ListValue> list(extracted_list->DeepCopy());
274   RemoveDuplicatePhoneNumberAtIndex(index, country_code, list.get());
275   return list.Pass();
276 }
277
278 }  // namespace
279
280 namespace options {
281
282 AutofillOptionsHandler::AutofillOptionsHandler()
283     : personal_data_(NULL) {}
284
285 AutofillOptionsHandler::~AutofillOptionsHandler() {
286   if (personal_data_)
287     personal_data_->RemoveObserver(this);
288 }
289
290 /////////////////////////////////////////////////////////////////////////////
291 // OptionsPageUIHandler implementation:
292 void AutofillOptionsHandler::GetLocalizedValues(
293     base::DictionaryValue* localized_strings) {
294   DCHECK(localized_strings);
295
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)
310   };
311
312   RegisterStrings(localized_strings, resources, arraysize(resources));
313   RegisterTitle(localized_strings, "autofillOptionsPage",
314                 IDS_AUTOFILL_OPTIONS_TITLE);
315
316   localized_strings->SetString("helpUrl", autofill::kHelpURL);
317   SetAddressOverlayStrings(localized_strings);
318   SetCreditCardOverlayStrings(localized_strings);
319 }
320
321 void AutofillOptionsHandler::InitializeHandler() {
322   // personal_data_ is NULL in guest mode on Chrome OS.
323   if (personal_data_)
324     personal_data_->AddObserver(this);
325 }
326
327 void AutofillOptionsHandler::InitializePage() {
328   if (personal_data_)
329     LoadAutofillData();
330 }
331
332 void AutofillOptionsHandler::RegisterMessages() {
333   personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile(
334       Profile::FromWebUI(web_ui()));
335
336   web_ui()->RegisterMessageCallback(
337       "removeData",
338       base::Bind(&AutofillOptionsHandler::RemoveData,
339                  base::Unretained(this)));
340   web_ui()->RegisterMessageCallback(
341       "loadAddressEditor",
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(
353       "setAddress",
354       base::Bind(&AutofillOptionsHandler::SetAddress, base::Unretained(this)));
355   web_ui()->RegisterMessageCallback(
356       "setCreditCard",
357       base::Bind(&AutofillOptionsHandler::SetCreditCard,
358                  base::Unretained(this)));
359   web_ui()->RegisterMessageCallback(
360       "validatePhoneNumbers",
361       base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers,
362                  base::Unretained(this)));
363 }
364
365 /////////////////////////////////////////////////////////////////////////////
366 // PersonalDataManagerObserver implementation:
367 void AutofillOptionsHandler::OnPersonalDataChanged() {
368   LoadAutofillData();
369 }
370
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);
386 }
387
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));
398 }
399
400 void AutofillOptionsHandler::LoadAutofillData() {
401   if (!IsPersonalDataLoaded())
402     return;
403
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());
409
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);
416   }
417
418   web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses);
419
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);
434   }
435
436   web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
437                                    credit_cards);
438 }
439
440 void AutofillOptionsHandler::RemoveData(const base::ListValue* args) {
441   DCHECK(IsPersonalDataLoaded());
442
443   std::string guid;
444   if (!args->GetString(0, &guid)) {
445     NOTREACHED();
446     return;
447   }
448
449   personal_data_->RemoveByGUID(guid);
450 }
451
452 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue* args) {
453   DCHECK(IsPersonalDataLoaded());
454
455   std::string guid;
456   if (!args->GetString(0, &guid)) {
457     NOTREACHED();
458     return;
459   }
460
461   AutofillProfile* profile = personal_data_->GetProfileByGUID(guid);
462   if (!profile) {
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.
468     return;
469   }
470
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());
476   address.SetString(
477       kCompanyNameField, profile->GetRawInfo(autofill::COMPANY_NAME));
478   address.SetString(kAddressLineField,
479                     profile->GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS));
480   address.SetString(
481       kCityField, profile->GetRawInfo(autofill::ADDRESS_HOME_CITY));
482   address.SetString(
483       kStateField, profile->GetRawInfo(autofill::ADDRESS_HOME_STATE));
484   address.SetString(
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());
498
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());
504
505   web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address);
506 }
507
508 void AutofillOptionsHandler::LoadAddressEditorComponents(
509     const base::ListValue* args) {
510   std::string country_code;
511   if (!args->GetString(0, &country_code)) {
512     NOTREACHED();
513     return;
514   }
515
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);
523
524   web_ui()->CallJavascriptFunction(
525       "AutofillEditAddressOverlay.loadAddressComponents", input);
526 }
527
528 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue* args) {
529   DCHECK(IsPersonalDataLoaded());
530
531   std::string guid;
532   if (!args->GetString(0, &guid)) {
533     NOTREACHED();
534     return;
535   }
536
537   CreditCard* credit_card = personal_data_->GetCreditCardByGUID(guid);
538   if (!credit_card) {
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.
544     return;
545   }
546
547   base::DictionaryValue credit_card_data;
548   credit_card_data.SetString("guid", credit_card->guid());
549   credit_card_data.SetString(
550       "nameOnCard",
551       credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME));
552   credit_card_data.SetString(
553       "creditCardNumber",
554       credit_card->GetRawInfo(autofill::CREDIT_CARD_NUMBER));
555   credit_card_data.SetString(
556       "expirationMonth",
557       credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH));
558   credit_card_data.SetString(
559       "expirationYear",
560       credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR));
561
562   web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
563                                    credit_card_data);
564 }
565
566 void AutofillOptionsHandler::SetAddress(const base::ListValue* args) {
567   if (!IsPersonalDataLoaded())
568     return;
569
570   int arg_counter = 0;
571   std::string guid;
572   if (!args->GetString(arg_counter++, &guid)) {
573     NOTREACHED();
574     return;
575   }
576
577   AutofillProfile profile(guid, kSettingsOrigin);
578
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);
583
584   if (args->GetString(arg_counter++, &value))
585     profile.SetRawInfo(autofill::COMPANY_NAME, value);
586
587   if (args->GetString(arg_counter++, &value))
588     profile.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, value);
589
590   if (args->GetString(arg_counter++, &value))
591     profile.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY, value);
592
593   if (args->GetString(arg_counter++, &value))
594     profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, value);
595
596   if (args->GetString(arg_counter++, &value))
597     profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, value);
598
599   if (args->GetString(arg_counter++, &value))
600     profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, value);
601
602   if (args->GetString(arg_counter++, &value))
603     profile.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE, value);
604
605   if (args->GetString(arg_counter++, &value))
606     profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY, value);
607
608   if (args->GetList(arg_counter++, &list_value))
609     SetValueList(list_value, autofill::PHONE_HOME_WHOLE_NUMBER, &profile);
610
611   if (args->GetList(arg_counter++, &list_value))
612     SetValueList(list_value, autofill::EMAIL_ADDRESS, &profile);
613
614   if (args->GetString(arg_counter++, &value))
615     profile.set_language_code(base::UTF16ToUTF8(value));
616
617   if (!base::IsValidGUID(profile.guid())) {
618     profile.set_guid(base::GenerateGUID());
619     personal_data_->AddProfile(profile);
620   } else {
621     personal_data_->UpdateProfile(profile);
622   }
623 }
624
625 void AutofillOptionsHandler::SetCreditCard(const base::ListValue* args) {
626   if (!IsPersonalDataLoaded())
627     return;
628
629   std::string guid;
630   if (!args->GetString(0, &guid)) {
631     NOTREACHED();
632     return;
633   }
634
635   CreditCard credit_card(guid, kSettingsOrigin);
636
637   base::string16 value;
638   if (args->GetString(1, &value))
639     credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME, value);
640
641   if (args->GetString(2, &value))
642     credit_card.SetRawInfo(autofill::CREDIT_CARD_NUMBER, value);
643
644   if (args->GetString(3, &value))
645     credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, value);
646
647   if (args->GetString(4, &value))
648     credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, value);
649
650   if (!base::IsValidGUID(credit_card.guid())) {
651     credit_card.set_guid(base::GenerateGUID());
652     personal_data_->AddCreditCard(credit_card);
653   } else {
654     personal_data_->UpdateCreditCard(credit_card);
655   }
656 }
657
658 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue* args) {
659   if (!IsPersonalDataLoaded())
660     return;
661
662   scoped_ptr<base::ListValue> list_value = ValidatePhoneArguments(args);
663
664   web_ui()->CallJavascriptFunction(
665     "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value);
666 }
667
668 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
669   return personal_data_ && personal_data_->IsDataLoaded();
670 }
671
672 }  // namespace options