Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / extensions / api / autofill_private / autofill_private_api.cc
blob79b1735857d7e71ab27fbc5856b249d0b5c61c40
1 // Copyright 2015 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/extensions/api/autofill_private/autofill_private_api.h"
7 #include "base/guid.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "chrome/browser/autofill/personal_data_manager_factory.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/common/extensions/api/autofill_private.h"
13 #include "chrome/grit/generated_resources.h"
14 #include "components/autofill/core/browser/autofill_profile.h"
15 #include "components/autofill/core/browser/personal_data_manager.h"
16 #include "extensions/browser/extension_function.h"
17 #include "extensions/browser/extension_function_registry.h"
18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h"
19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h"
20 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h"
21 #include "ui/base/l10n/l10n_util.h"
23 namespace autofill_private = extensions::api::autofill_private;
24 namespace addressinput = i18n::addressinput;
26 namespace {
28 static const char kSettingsOrigin[] = "Chrome settings";
29 static const char kErrorDataUnavailable[] = "Autofill data unavailable.";
31 // Fills |components| with the address UI components that should be used to
32 // input an address for |country_code| when UI BCP 47 language code is
33 // |ui_language_code|.
34 void PopulateAddressComponents(
35 const std::string& country_code,
36 const std::string& ui_language_code,
37 autofill_private::AddressComponents* address_components) {
38 DCHECK(address_components);
40 i18n::addressinput::Localization localization;
41 localization.SetGetter(l10n_util::GetStringUTF8);
42 std::string best_address_language_code;
43 std::vector<addressinput::AddressUiComponent> components =
44 i18n::addressinput::BuildComponents(
45 country_code,
46 localization,
47 ui_language_code,
48 &best_address_language_code);
49 if (components.empty()) {
50 static const char kDefaultCountryCode[] = "US";
51 components = i18n::addressinput::BuildComponents(
52 kDefaultCountryCode,
53 localization,
54 ui_language_code,
55 &best_address_language_code);
57 address_components->language_code = best_address_language_code;
58 DCHECK(!components.empty());
60 autofill_private::AddressComponentRow* row = nullptr;
61 for (size_t i = 0; i < components.size(); ++i) {
62 if (!row ||
63 components[i - 1].length_hint ==
64 addressinput::AddressUiComponent::HINT_LONG ||
65 components[i].length_hint ==
66 addressinput::AddressUiComponent::HINT_LONG) {
67 row = new autofill_private::AddressComponentRow;
68 address_components->components.push_back(make_linked_ptr(row));
71 scoped_ptr<autofill_private::AddressComponent>
72 component(new autofill_private::AddressComponent);
73 component->field_name = components[i].name;
75 switch (components[i].field) {
76 case i18n::addressinput::COUNTRY:
77 component->field =
78 autofill_private::AddressField::ADDRESS_FIELD_COUNTRY_CODE;
79 break;
80 case i18n::addressinput::ADMIN_AREA:
81 component->field =
82 autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LEVEL_1;
83 break;
84 case i18n::addressinput::LOCALITY:
85 component->field =
86 autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LEVEL_2;
87 break;
88 case i18n::addressinput::DEPENDENT_LOCALITY:
89 component->field =
90 autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LEVEL_3;
91 break;
92 case i18n::addressinput::SORTING_CODE:
93 component->field =
94 autofill_private::AddressField::ADDRESS_FIELD_SORTING_CODE;
95 break;
96 case i18n::addressinput::POSTAL_CODE:
97 component->field =
98 autofill_private::AddressField::ADDRESS_FIELD_POSTAL_CODE;
99 break;
100 case i18n::addressinput::STREET_ADDRESS:
101 component->field =
102 autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LINES;
103 break;
104 case i18n::addressinput::ORGANIZATION:
105 component->field =
106 autofill_private::AddressField::ADDRESS_FIELD_COMPANY_NAME;
107 break;
108 case i18n::addressinput::RECIPIENT:
109 component->field =
110 autofill_private::AddressField::ADDRESS_FIELD_FULL_NAME;
111 break;
114 switch (components[i].length_hint) {
115 case addressinput::AddressUiComponent::HINT_LONG:
116 component->is_long_field = true;
117 break;
118 case addressinput::AddressUiComponent::HINT_SHORT:
119 component->is_long_field = false;
120 break;
123 row->row.push_back(make_linked_ptr(component.release()));
127 // Searches the |list| for the value at |index|. If this value is present in
128 // any of the rest of the list, then the item (at |index|) is removed. The
129 // comparison of phone number values is done on normalized versions of the phone
130 // number values.
131 void RemoveDuplicatePhoneNumberAtIndex(
132 size_t index, const std::string& country_code, base::ListValue* list) {
133 base::string16 new_value;
134 if (!list->GetString(index, &new_value)) {
135 NOTREACHED() << "List should have a value at index " << index;
136 return;
139 bool is_duplicate = false;
140 std::string app_locale = g_browser_process->GetApplicationLocale();
141 for (size_t i = 0; i < list->GetSize() && !is_duplicate; ++i) {
142 if (i == index)
143 continue;
145 base::string16 existing_value;
146 if (!list->GetString(i, &existing_value)) {
147 NOTREACHED() << "List should have a value at index " << i;
148 continue;
150 is_duplicate = autofill::i18n::PhoneNumbersMatch(
151 new_value, existing_value, country_code, app_locale);
154 if (is_duplicate)
155 list->Remove(index, nullptr);
158 } // namespace
160 namespace extensions {
162 ////////////////////////////////////////////////////////////////////////////////
163 // AutofillPrivateSaveAddressFunction
165 AutofillPrivateSaveAddressFunction::AutofillPrivateSaveAddressFunction()
166 : chrome_details_(this) {}
168 AutofillPrivateSaveAddressFunction::~AutofillPrivateSaveAddressFunction() {}
170 ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() {
171 scoped_ptr<api::autofill_private::SaveAddress::Params> parameters =
172 api::autofill_private::SaveAddress::Params::Create(*args_);
173 EXTENSION_FUNCTION_VALIDATE(parameters.get());
175 autofill::PersonalDataManager* personal_data =
176 autofill::PersonalDataManagerFactory::GetForProfile(
177 chrome_details_.GetProfile());
178 if (!personal_data || !personal_data->IsDataLoaded()) {
179 error_ = kErrorDataUnavailable;
180 return RespondNow(NoArguments());
183 api::autofill_private::AddressEntry* address = &parameters->address;
185 std::string guid = address->guid ? *address->guid : "";
186 autofill::AutofillProfile profile(guid, kSettingsOrigin);
188 // Strings from JavaScript use UTF-8 encoding. This container is used as an
189 // intermediate container for functions which require UTF-16 strings.
190 std::vector<base::string16> string16Container;
192 if (address->full_names) {
193 std::string full_name;
194 if (!address->full_names->empty())
195 full_name = address->full_names->at(0);
196 profile.SetInfo(autofill::AutofillType(autofill::NAME_FULL),
197 base::UTF8ToUTF16(full_name),
198 g_browser_process->GetApplicationLocale());
201 if (address->company_name) {
202 profile.SetRawInfo(
203 autofill::COMPANY_NAME,
204 base::UTF8ToUTF16(*address->company_name));
207 if (address->address_lines) {
208 profile.SetRawInfo(
209 autofill::ADDRESS_HOME_STREET_ADDRESS,
210 base::UTF8ToUTF16(*address->address_lines));
213 if (address->address_level1) {
214 profile.SetRawInfo(
215 autofill::ADDRESS_HOME_CITY,
216 base::UTF8ToUTF16(*address->address_level1));
219 if (address->address_level2) {
220 profile.SetRawInfo(
221 autofill::ADDRESS_HOME_STATE,
222 base::UTF8ToUTF16(*address->address_level2));
225 if (address->address_level3) {
226 profile.SetRawInfo(
227 autofill::ADDRESS_HOME_DEPENDENT_LOCALITY,
228 base::UTF8ToUTF16(*address->address_level3));
231 if (address->postal_code) {
232 profile.SetRawInfo(
233 autofill::ADDRESS_HOME_ZIP,
234 base::UTF8ToUTF16(*address->postal_code));
237 if (address->sorting_code) {
238 profile.SetRawInfo(
239 autofill::ADDRESS_HOME_SORTING_CODE,
240 base::UTF8ToUTF16(*address->sorting_code));
243 if (address->country_code) {
244 profile.SetRawInfo(
245 autofill::ADDRESS_HOME_COUNTRY,
246 base::UTF8ToUTF16(*address->country_code));
249 if (address->phone_numbers) {
250 std::string phone;
251 if (!address->phone_numbers->empty())
252 phone = address->phone_numbers->at(0);
253 profile.SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER,
254 base::UTF8ToUTF16(phone));
257 if (address->email_addresses) {
258 std::string email;
259 if (!address->email_addresses->empty())
260 email = address->email_addresses->at(0);
261 profile.SetRawInfo(autofill::EMAIL_ADDRESS, base::UTF8ToUTF16(email));
264 if (address->language_code)
265 profile.set_language_code(*address->language_code);
267 if (!base::IsValidGUID(profile.guid())) {
268 profile.set_guid(base::GenerateGUID());
269 personal_data->AddProfile(profile);
270 } else {
271 personal_data->UpdateProfile(profile);
274 return RespondNow(NoArguments());
277 ////////////////////////////////////////////////////////////////////////////////
278 // AutofillPrivateGetAddressComponentsFunction
280 AutofillPrivateGetAddressComponentsFunction::
281 ~AutofillPrivateGetAddressComponentsFunction() {}
283 ExtensionFunction::ResponseAction
284 AutofillPrivateGetAddressComponentsFunction::Run() {
285 scoped_ptr<api::autofill_private::GetAddressComponents::Params> parameters =
286 api::autofill_private::GetAddressComponents::Params::Create(*args_);
287 EXTENSION_FUNCTION_VALIDATE(parameters.get());
289 autofill_private::AddressComponents components;
290 PopulateAddressComponents(
291 parameters->country_code,
292 g_browser_process->GetApplicationLocale(),
293 &components);
295 return RespondNow(OneArgument(components.ToValue().release()));
298 ////////////////////////////////////////////////////////////////////////////////
299 // AutofillPrivateSaveCreditCardFunction
301 AutofillPrivateSaveCreditCardFunction::AutofillPrivateSaveCreditCardFunction()
302 : chrome_details_(this) {}
304 AutofillPrivateSaveCreditCardFunction::
305 ~AutofillPrivateSaveCreditCardFunction() {}
307 ExtensionFunction::ResponseAction AutofillPrivateSaveCreditCardFunction::Run() {
308 scoped_ptr<api::autofill_private::SaveCreditCard::Params> parameters =
309 api::autofill_private::SaveCreditCard::Params::Create(*args_);
310 EXTENSION_FUNCTION_VALIDATE(parameters.get());
312 autofill::PersonalDataManager* personal_data =
313 autofill::PersonalDataManagerFactory::GetForProfile(
314 chrome_details_.GetProfile());
315 if (!personal_data || !personal_data->IsDataLoaded()) {
316 error_ = kErrorDataUnavailable;
317 return RespondNow(NoArguments());
320 api::autofill_private::CreditCardEntry* card = &parameters->card;
322 std::string guid = card->guid ? *card->guid : "";
323 autofill::CreditCard credit_card(guid, kSettingsOrigin);
325 if (card->name) {
326 credit_card.SetRawInfo(
327 autofill::CREDIT_CARD_NAME,
328 base::UTF8ToUTF16(*card->name));
331 if (card->card_number) {
332 credit_card.SetRawInfo(
333 autofill::CREDIT_CARD_NUMBER,
334 base::UTF8ToUTF16(*card->card_number));
337 if (card->expiration_month) {
338 credit_card.SetRawInfo(
339 autofill::CREDIT_CARD_EXP_MONTH,
340 base::UTF8ToUTF16(*card->expiration_month));
343 if (card->expiration_year) {
344 credit_card.SetRawInfo(
345 autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR,
346 base::UTF8ToUTF16(*card->expiration_year));
349 if (!base::IsValidGUID(credit_card.guid())) {
350 credit_card.set_guid(base::GenerateGUID());
351 personal_data->AddCreditCard(credit_card);
352 } else {
353 personal_data->UpdateCreditCard(credit_card);
356 return RespondNow(NoArguments());
359 ////////////////////////////////////////////////////////////////////////////////
360 // AutofillPrivateRemoveEntryFunction
362 AutofillPrivateRemoveEntryFunction::AutofillPrivateRemoveEntryFunction()
363 : chrome_details_(this) {}
365 AutofillPrivateRemoveEntryFunction::~AutofillPrivateRemoveEntryFunction() {}
367 ExtensionFunction::ResponseAction AutofillPrivateRemoveEntryFunction::Run() {
368 scoped_ptr<api::autofill_private::RemoveEntry::Params> parameters =
369 api::autofill_private::RemoveEntry::Params::Create(*args_);
370 EXTENSION_FUNCTION_VALIDATE(parameters.get());
372 autofill::PersonalDataManager* personal_data =
373 autofill::PersonalDataManagerFactory::GetForProfile(
374 chrome_details_.GetProfile());
375 if (!personal_data || !personal_data->IsDataLoaded()) {
376 error_ = kErrorDataUnavailable;
377 return RespondNow(NoArguments());
380 personal_data->RemoveByGUID(parameters->guid);
382 return RespondNow(NoArguments());
385 ////////////////////////////////////////////////////////////////////////////////
386 // AutofillPrivateValidatePhoneNumbersFunction
388 AutofillPrivateValidatePhoneNumbersFunction::
389 ~AutofillPrivateValidatePhoneNumbersFunction() {}
391 ExtensionFunction::ResponseAction
392 AutofillPrivateValidatePhoneNumbersFunction::Run() {
393 scoped_ptr<api::autofill_private::ValidatePhoneNumbers::Params> parameters =
394 api::autofill_private::ValidatePhoneNumbers::Params::Create(*args_);
395 EXTENSION_FUNCTION_VALIDATE(parameters.get());
397 api::autofill_private::ValidatePhoneParams* params = &parameters->params;
399 // Extract the phone numbers into a ListValue.
400 scoped_ptr<base::ListValue> phoneNumbers(new base::ListValue);
401 phoneNumbers->AppendStrings(params->phone_numbers);
403 RemoveDuplicatePhoneNumberAtIndex(
404 params->index_of_new_number, params->country_code, phoneNumbers.get());
406 return RespondNow(OneArgument(phoneNumbers.Pass()));
409 ////////////////////////////////////////////////////////////////////////////////
410 // AutofillPrivateMaskCreditCardFunction
412 AutofillPrivateMaskCreditCardFunction::AutofillPrivateMaskCreditCardFunction()
413 : chrome_details_(this) {}
415 AutofillPrivateMaskCreditCardFunction::
416 ~AutofillPrivateMaskCreditCardFunction() {}
418 ExtensionFunction::ResponseAction AutofillPrivateMaskCreditCardFunction::Run() {
419 scoped_ptr<api::autofill_private::MaskCreditCard::Params> parameters =
420 api::autofill_private::MaskCreditCard::Params::Create(*args_);
421 EXTENSION_FUNCTION_VALIDATE(parameters.get());
423 autofill::PersonalDataManager* personal_data =
424 autofill::PersonalDataManagerFactory::GetForProfile(
425 chrome_details_.GetProfile());
426 if (!personal_data || !personal_data->IsDataLoaded()) {
427 error_ = kErrorDataUnavailable;
428 return RespondNow(NoArguments());
431 personal_data->ResetFullServerCard(parameters->guid);
433 return RespondNow(NoArguments());
436 } // namespace extensions