NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / autofill_options_handler.cc
blob99d79a7f862288116d5f044c6f112b3cd8990a50
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/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 "ui/base/l10n/l10n_util.h"
32 #include "ui/base/webui/web_ui_util.h"
34 using autofill::AutofillCountry;
35 using autofill::ServerFieldType;
36 using autofill::AutofillProfile;
37 using autofill::CreditCard;
38 using autofill::PersonalDataManager;
40 namespace {
42 const char kSettingsOrigin[] = "Chrome settings";
44 // Sets data related to the country <select>.
45 void SetCountryData(const PersonalDataManager& manager,
46 base::DictionaryValue* localized_strings) {
47 autofill::CountryComboboxModel model(manager);
48 const std::vector<AutofillCountry*>& countries = model.countries();
49 localized_strings->SetString("defaultCountryCode",
50 countries.front()->country_code());
52 // An ordered list of options to show in the <select>.
53 scoped_ptr<base::ListValue> country_list(new base::ListValue());
54 // A dictionary of postal code and state info, keyed on country code.
55 scoped_ptr<base::DictionaryValue> country_data(new base::DictionaryValue());
56 for (size_t i = 0; i < countries.size(); ++i) {
57 scoped_ptr<base::DictionaryValue> option_details(
58 new base::DictionaryValue());
59 option_details->SetString("name", model.GetItemAt(i));
60 option_details->SetString(
61 "value",
62 countries[i] ? countries[i]->country_code() : "separator");
63 country_list->Append(option_details.release());
65 if (!countries[i])
66 continue;
68 scoped_ptr<base::DictionaryValue> details(new base::DictionaryValue());
69 details->SetString("postalCodeLabel", countries[i]->postal_code_label());
70 details->SetString("stateLabel", countries[i]->state_label());
71 country_data->Set(countries[i]->country_code(), details.release());
74 localized_strings->Set("autofillCountrySelectList", country_list.release());
75 localized_strings->Set("autofillCountryData", country_data.release());
78 // Get the multi-valued element for |type| and return it in |ListValue| form.
79 void GetValueList(const AutofillProfile& profile,
80 ServerFieldType type,
81 scoped_ptr<base::ListValue>* list) {
82 list->reset(new base::ListValue);
84 std::vector<base::string16> values;
85 profile.GetRawMultiInfo(type, &values);
87 // |GetRawMultiInfo()| always returns at least one, potentially empty, item.
88 if (values.size() == 1 && values.front().empty())
89 return;
91 for (size_t i = 0; i < values.size(); ++i) {
92 (*list)->Set(i, new base::StringValue(values[i]));
96 // Set the multi-valued element for |type| from input |list| values.
97 void SetValueList(const base::ListValue* list,
98 ServerFieldType type,
99 AutofillProfile* profile) {
100 std::vector<base::string16> values(list->GetSize());
101 for (size_t i = 0; i < list->GetSize(); ++i) {
102 base::string16 value;
103 if (list->GetString(i, &value))
104 values[i] = value;
106 profile->SetRawMultiInfo(type, values);
109 // Get the multi-valued element for |type| and return it in |ListValue| form.
110 void GetNameList(const AutofillProfile& profile,
111 scoped_ptr<base::ListValue>* names) {
112 names->reset(new base::ListValue);
114 std::vector<base::string16> first_names;
115 std::vector<base::string16> middle_names;
116 std::vector<base::string16> last_names;
117 profile.GetRawMultiInfo(autofill::NAME_FIRST, &first_names);
118 profile.GetRawMultiInfo(autofill::NAME_MIDDLE, &middle_names);
119 profile.GetRawMultiInfo(autofill::NAME_LAST, &last_names);
120 DCHECK_EQ(first_names.size(), middle_names.size());
121 DCHECK_EQ(first_names.size(), last_names.size());
123 // |GetRawMultiInfo()| always returns at least one, potentially empty, item.
124 if (first_names.size() == 1 && first_names.front().empty() &&
125 middle_names.front().empty() && last_names.front().empty()) {
126 return;
129 for (size_t i = 0; i < first_names.size(); ++i) {
130 base::ListValue* name = new base::ListValue; // owned by |list|
131 name->Set(0, new base::StringValue(first_names[i]));
132 name->Set(1, new base::StringValue(middle_names[i]));
133 name->Set(2, new base::StringValue(last_names[i]));
134 (*names)->Set(i, name);
138 // Set the multi-valued element for |type| from input |list| values.
139 void SetNameList(const base::ListValue* names, AutofillProfile* profile) {
140 const size_t size = names->GetSize();
141 std::vector<base::string16> first_names(size);
142 std::vector<base::string16> middle_names(size);
143 std::vector<base::string16> last_names(size);
145 for (size_t i = 0; i < size; ++i) {
146 const base::ListValue* name;
147 bool success = names->GetList(i, &name);
148 DCHECK(success);
150 base::string16 first_name;
151 success = name->GetString(0, &first_name);
152 DCHECK(success);
153 first_names[i] = first_name;
155 base::string16 middle_name;
156 success = name->GetString(1, &middle_name);
157 DCHECK(success);
158 middle_names[i] = middle_name;
160 base::string16 last_name;
161 success = name->GetString(2, &last_name);
162 DCHECK(success);
163 last_names[i] = last_name;
166 profile->SetRawMultiInfo(autofill::NAME_FIRST, first_names);
167 profile->SetRawMultiInfo(autofill::NAME_MIDDLE, middle_names);
168 profile->SetRawMultiInfo(autofill::NAME_LAST, last_names);
171 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
172 // the |args| input.
173 void ExtractPhoneNumberInformation(const base::ListValue* args,
174 size_t* index,
175 const base::ListValue** phone_number_list,
176 std::string* country_code) {
177 // Retrieve index as a |double|, as that is how it comes across from
178 // JavaScript.
179 double number = 0.0;
180 if (!args->GetDouble(0, &number)) {
181 NOTREACHED();
182 return;
184 *index = number;
186 if (!args->GetList(1, phone_number_list)) {
187 NOTREACHED();
188 return;
191 if (!args->GetString(2, country_code)) {
192 NOTREACHED();
193 return;
197 // Searches the |list| for the value at |index|. If this value is present
198 // in any of the rest of the list, then the item (at |index|) is removed.
199 // The comparison of phone number values is done on normalized versions of the
200 // phone number values.
201 void RemoveDuplicatePhoneNumberAtIndex(size_t index,
202 const std::string& country_code,
203 base::ListValue* list) {
204 base::string16 new_value;
205 if (!list->GetString(index, &new_value)) {
206 NOTREACHED() << "List should have a value at index " << index;
207 return;
210 bool is_duplicate = false;
211 std::string app_locale = g_browser_process->GetApplicationLocale();
212 for (size_t i = 0; i < list->GetSize() && !is_duplicate; ++i) {
213 if (i == index)
214 continue;
216 base::string16 existing_value;
217 if (!list->GetString(i, &existing_value)) {
218 NOTREACHED() << "List should have a value at index " << i;
219 continue;
221 is_duplicate = autofill::i18n::PhoneNumbersMatch(
222 new_value, existing_value, country_code, app_locale);
225 if (is_duplicate)
226 list->Remove(index, NULL);
229 scoped_ptr<base::ListValue> ValidatePhoneArguments(
230 const base::ListValue* args) {
231 size_t index = 0;
232 std::string country_code;
233 const base::ListValue* extracted_list = NULL;
234 ExtractPhoneNumberInformation(args, &index, &extracted_list, &country_code);
236 scoped_ptr<base::ListValue> list(extracted_list->DeepCopy());
237 RemoveDuplicatePhoneNumberAtIndex(index, country_code, list.get());
238 return list.Pass();
241 } // namespace
243 namespace options {
245 AutofillOptionsHandler::AutofillOptionsHandler()
246 : personal_data_(NULL) {}
248 AutofillOptionsHandler::~AutofillOptionsHandler() {
249 if (personal_data_)
250 personal_data_->RemoveObserver(this);
253 /////////////////////////////////////////////////////////////////////////////
254 // OptionsPageUIHandler implementation:
255 void AutofillOptionsHandler::GetLocalizedValues(
256 base::DictionaryValue* localized_strings) {
257 DCHECK(localized_strings);
259 static OptionsStringResource resources[] = {
260 { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME },
261 { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME },
262 { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON },
263 { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON },
264 { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON },
265 { "helpButton", IDS_AUTOFILL_HELP_LABEL },
266 { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION },
267 { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION },
268 { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION },
269 { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION },
270 #if defined(OS_MACOSX)
271 { "auxiliaryProfilesEnabled", IDS_AUTOFILL_USE_MAC_ADDRESS_BOOK },
272 #endif // defined(OS_MACOSX)
275 RegisterStrings(localized_strings, resources, arraysize(resources));
276 RegisterTitle(localized_strings, "autofillOptionsPage",
277 IDS_AUTOFILL_OPTIONS_TITLE);
279 localized_strings->SetString("helpUrl", autofill::kHelpURL);
280 SetAddressOverlayStrings(localized_strings);
281 SetCreditCardOverlayStrings(localized_strings);
284 void AutofillOptionsHandler::InitializeHandler() {
285 // personal_data_ is NULL in guest mode on Chrome OS.
286 if (personal_data_)
287 personal_data_->AddObserver(this);
290 void AutofillOptionsHandler::InitializePage() {
291 if (personal_data_)
292 LoadAutofillData();
295 void AutofillOptionsHandler::RegisterMessages() {
296 personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile(
297 Profile::FromWebUI(web_ui()));
299 web_ui()->RegisterMessageCallback(
300 "removeData",
301 base::Bind(&AutofillOptionsHandler::RemoveData,
302 base::Unretained(this)));
303 web_ui()->RegisterMessageCallback(
304 "loadAddressEditor",
305 base::Bind(&AutofillOptionsHandler::LoadAddressEditor,
306 base::Unretained(this)));
307 web_ui()->RegisterMessageCallback(
308 "loadCreditCardEditor",
309 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor,
310 base::Unretained(this)));
311 web_ui()->RegisterMessageCallback(
312 "setAddress",
313 base::Bind(&AutofillOptionsHandler::SetAddress, base::Unretained(this)));
314 web_ui()->RegisterMessageCallback(
315 "setCreditCard",
316 base::Bind(&AutofillOptionsHandler::SetCreditCard,
317 base::Unretained(this)));
318 web_ui()->RegisterMessageCallback(
319 "validatePhoneNumbers",
320 base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers,
321 base::Unretained(this)));
324 /////////////////////////////////////////////////////////////////////////////
325 // PersonalDataManagerObserver implementation:
326 void AutofillOptionsHandler::OnPersonalDataChanged() {
327 LoadAutofillData();
330 void AutofillOptionsHandler::SetAddressOverlayStrings(
331 base::DictionaryValue* localized_strings) {
332 localized_strings->SetString("autofillEditAddressTitle",
333 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION));
334 localized_strings->SetString("autofillFirstNameLabel",
335 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_FIRST_NAME));
336 localized_strings->SetString("autofillMiddleNameLabel",
337 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_MIDDLE_NAME));
338 localized_strings->SetString("autofillLastNameLabel",
339 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_LAST_NAME));
340 localized_strings->SetString("autofillCompanyNameLabel",
341 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COMPANY_NAME));
342 localized_strings->SetString("autofillAddrLine1Label",
343 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADDRESS_LINE_1));
344 localized_strings->SetString("autofillAddrLine2Label",
345 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADDRESS_LINE_2));
346 localized_strings->SetString("autofillCityLabel",
347 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CITY));
348 localized_strings->SetString("autofillCountryLabel",
349 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY));
350 localized_strings->SetString("autofillPhoneLabel",
351 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE));
352 localized_strings->SetString("autofillEmailLabel",
353 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL));
354 localized_strings->SetString("autofillAddFirstNamePlaceholder",
355 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_FIRST_NAME));
356 localized_strings->SetString("autofillAddMiddleNamePlaceholder",
357 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_MIDDLE_NAME));
358 localized_strings->SetString("autofillAddLastNamePlaceholder",
359 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_LAST_NAME));
360 localized_strings->SetString("autofillAddPhonePlaceholder",
361 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE));
362 localized_strings->SetString("autofillAddEmailPlaceholder",
363 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_EMAIL));
364 SetCountryData(*personal_data_, localized_strings);
367 void AutofillOptionsHandler::SetCreditCardOverlayStrings(
368 base::DictionaryValue* localized_strings) {
369 localized_strings->SetString("autofillEditCreditCardTitle",
370 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION));
371 localized_strings->SetString("nameOnCardLabel",
372 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD));
373 localized_strings->SetString("creditCardNumberLabel",
374 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER));
375 localized_strings->SetString("creditCardExpirationDateLabel",
376 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE));
379 void AutofillOptionsHandler::LoadAutofillData() {
380 if (!IsPersonalDataLoaded())
381 return;
383 const std::vector<AutofillProfile*>& profiles =
384 personal_data_->web_profiles();
385 std::vector<base::string16> labels;
386 AutofillProfile::CreateDifferentiatingLabels(profiles, &labels);
387 DCHECK_EQ(labels.size(), profiles.size());
389 base::ListValue addresses;
390 for (size_t i = 0; i < profiles.size(); ++i) {
391 base::ListValue* entry = new base::ListValue();
392 entry->Append(new base::StringValue(profiles[i]->guid()));
393 entry->Append(new base::StringValue(labels[i]));
394 addresses.Append(entry);
397 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses);
399 base::ListValue credit_cards;
400 const std::vector<CreditCard*>& cards = personal_data_->GetCreditCards();
401 for (std::vector<CreditCard*>::const_iterator iter = cards.begin();
402 iter != cards.end(); ++iter) {
403 const CreditCard* card = *iter;
404 // TODO(estade): this should be a dictionary.
405 base::ListValue* entry = new base::ListValue();
406 entry->Append(new base::StringValue(card->guid()));
407 entry->Append(new base::StringValue(card->Label()));
408 entry->Append(new base::StringValue(
409 webui::GetBitmapDataUrlFromResource(
410 CreditCard::IconResourceId(card->type()))));
411 entry->Append(new base::StringValue(card->TypeForDisplay()));
412 credit_cards.Append(entry);
415 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
416 credit_cards);
419 void AutofillOptionsHandler::RemoveData(const base::ListValue* args) {
420 DCHECK(IsPersonalDataLoaded());
422 std::string guid;
423 if (!args->GetString(0, &guid)) {
424 NOTREACHED();
425 return;
428 personal_data_->RemoveByGUID(guid);
431 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue* args) {
432 DCHECK(IsPersonalDataLoaded());
434 std::string guid;
435 if (!args->GetString(0, &guid)) {
436 NOTREACHED();
437 return;
440 AutofillProfile* profile = personal_data_->GetProfileByGUID(guid);
441 if (!profile) {
442 // There is a race where a user can click once on the close button and
443 // quickly click again on the list item before the item is removed (since
444 // the list is not updated until the model tells the list an item has been
445 // removed). This will activate the editor for a profile that has been
446 // removed. Do nothing in that case.
447 return;
450 base::DictionaryValue address;
451 address.SetString("guid", profile->guid());
452 scoped_ptr<base::ListValue> list;
453 GetNameList(*profile, &list);
454 address.Set("fullName", list.release());
455 address.SetString("companyName", profile->GetRawInfo(autofill::COMPANY_NAME));
456 address.SetString("addrLine1",
457 profile->GetRawInfo(autofill::ADDRESS_HOME_LINE1));
458 address.SetString("addrLine2",
459 profile->GetRawInfo(autofill::ADDRESS_HOME_LINE2));
460 address.SetString("city", profile->GetRawInfo(autofill::ADDRESS_HOME_CITY));
461 address.SetString("state", profile->GetRawInfo(autofill::ADDRESS_HOME_STATE));
462 address.SetString("postalCode",
463 profile->GetRawInfo(autofill::ADDRESS_HOME_ZIP));
464 address.SetString("country",
465 profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
466 GetValueList(*profile, autofill::PHONE_HOME_WHOLE_NUMBER, &list);
467 address.Set("phone", list.release());
468 GetValueList(*profile, autofill::EMAIL_ADDRESS, &list);
469 address.Set("email", list.release());
471 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address);
474 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue* args) {
475 DCHECK(IsPersonalDataLoaded());
477 std::string guid;
478 if (!args->GetString(0, &guid)) {
479 NOTREACHED();
480 return;
483 CreditCard* credit_card = personal_data_->GetCreditCardByGUID(guid);
484 if (!credit_card) {
485 // There is a race where a user can click once on the close button and
486 // quickly click again on the list item before the item is removed (since
487 // the list is not updated until the model tells the list an item has been
488 // removed). This will activate the editor for a profile that has been
489 // removed. Do nothing in that case.
490 return;
493 base::DictionaryValue credit_card_data;
494 credit_card_data.SetString("guid", credit_card->guid());
495 credit_card_data.SetString(
496 "nameOnCard",
497 credit_card->GetRawInfo(autofill::CREDIT_CARD_NAME));
498 credit_card_data.SetString(
499 "creditCardNumber",
500 credit_card->GetRawInfo(autofill::CREDIT_CARD_NUMBER));
501 credit_card_data.SetString(
502 "expirationMonth",
503 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH));
504 credit_card_data.SetString(
505 "expirationYear",
506 credit_card->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR));
508 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
509 credit_card_data);
512 void AutofillOptionsHandler::SetAddress(const base::ListValue* args) {
513 if (!IsPersonalDataLoaded())
514 return;
516 std::string guid;
517 if (!args->GetString(0, &guid)) {
518 NOTREACHED();
519 return;
522 AutofillProfile profile(guid, kSettingsOrigin);
524 std::string country_code;
525 base::string16 value;
526 const base::ListValue* list_value;
527 if (args->GetList(1, &list_value))
528 SetNameList(list_value, &profile);
530 if (args->GetString(2, &value))
531 profile.SetRawInfo(autofill::COMPANY_NAME, value);
533 if (args->GetString(3, &value))
534 profile.SetRawInfo(autofill::ADDRESS_HOME_LINE1, value);
536 if (args->GetString(4, &value))
537 profile.SetRawInfo(autofill::ADDRESS_HOME_LINE2, value);
539 if (args->GetString(5, &value))
540 profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, value);
542 if (args->GetString(6, &value))
543 profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, value);
545 if (args->GetString(7, &value))
546 profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, value);
548 if (args->GetString(8, &country_code))
549 profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY,
550 base::ASCIIToUTF16(country_code));
552 if (args->GetList(9, &list_value))
553 SetValueList(list_value, autofill::PHONE_HOME_WHOLE_NUMBER, &profile);
555 if (args->GetList(10, &list_value))
556 SetValueList(list_value, autofill::EMAIL_ADDRESS, &profile);
558 if (!base::IsValidGUID(profile.guid())) {
559 profile.set_guid(base::GenerateGUID());
560 personal_data_->AddProfile(profile);
561 } else {
562 personal_data_->UpdateProfile(profile);
566 void AutofillOptionsHandler::SetCreditCard(const base::ListValue* args) {
567 if (!IsPersonalDataLoaded())
568 return;
570 std::string guid;
571 if (!args->GetString(0, &guid)) {
572 NOTREACHED();
573 return;
576 CreditCard credit_card(guid, kSettingsOrigin);
578 base::string16 value;
579 if (args->GetString(1, &value))
580 credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME, value);
582 if (args->GetString(2, &value))
583 credit_card.SetRawInfo(autofill::CREDIT_CARD_NUMBER, value);
585 if (args->GetString(3, &value))
586 credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, value);
588 if (args->GetString(4, &value))
589 credit_card.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, value);
591 if (!base::IsValidGUID(credit_card.guid())) {
592 credit_card.set_guid(base::GenerateGUID());
593 personal_data_->AddCreditCard(credit_card);
594 } else {
595 personal_data_->UpdateCreditCard(credit_card);
599 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue* args) {
600 if (!IsPersonalDataLoaded())
601 return;
603 scoped_ptr<base::ListValue> list_value = ValidatePhoneArguments(args);
605 web_ui()->CallJavascriptFunction(
606 "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value);
609 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
610 return personal_data_ && personal_data_->IsDataLoaded();
613 } // namespace options