Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / autofill_private / autofill_private_api.cc
blob878e4d50e9999578cca109e7673b0fd3f46864bb
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 component->placeholder.reset(new std::string(
112 l10n_util::GetStringUTF8(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME)));
113 break;
116 switch (components[i].length_hint) {
117 case addressinput::AddressUiComponent::HINT_LONG:
118 component->is_long_field = true;
119 break;
120 case addressinput::AddressUiComponent::HINT_SHORT:
121 component->is_long_field = false;
122 break;
125 row->row.push_back(make_linked_ptr(component.release()));
129 // Searches the |list| for the value at |index|. If this value is present in
130 // any of the rest of the list, then the item (at |index|) is removed. The
131 // comparison of phone number values is done on normalized versions of the phone
132 // number values.
133 void RemoveDuplicatePhoneNumberAtIndex(
134 size_t index, const std::string& country_code, base::ListValue* list) {
135 base::string16 new_value;
136 if (!list->GetString(index, &new_value)) {
137 NOTREACHED() << "List should have a value at index " << index;
138 return;
141 bool is_duplicate = false;
142 std::string app_locale = g_browser_process->GetApplicationLocale();
143 for (size_t i = 0; i < list->GetSize() && !is_duplicate; ++i) {
144 if (i == index)
145 continue;
147 base::string16 existing_value;
148 if (!list->GetString(i, &existing_value)) {
149 NOTREACHED() << "List should have a value at index " << i;
150 continue;
152 is_duplicate = autofill::i18n::PhoneNumbersMatch(
153 new_value, existing_value, country_code, app_locale);
156 if (is_duplicate)
157 list->Remove(index, nullptr);
160 } // namespace
162 namespace extensions {
164 ////////////////////////////////////////////////////////////////////////////////
165 // AutofillPrivateSaveAddressFunction
167 AutofillPrivateSaveAddressFunction::AutofillPrivateSaveAddressFunction()
168 : chrome_details_(this) {}
170 AutofillPrivateSaveAddressFunction::~AutofillPrivateSaveAddressFunction() {}
172 ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() {
173 scoped_ptr<api::autofill_private::SaveAddress::Params> parameters =
174 api::autofill_private::SaveAddress::Params::Create(*args_);
175 EXTENSION_FUNCTION_VALIDATE(parameters.get());
177 autofill::PersonalDataManager* personal_data =
178 autofill::PersonalDataManagerFactory::GetForProfile(
179 chrome_details_.GetProfile());
180 if (!personal_data || !personal_data->IsDataLoaded()) {
181 error_ = kErrorDataUnavailable;
182 return RespondNow(NoArguments());
185 api::autofill_private::AddressEntry* address = &parameters->address;
187 std::string guid = address->guid ? *address->guid : "";
188 autofill::AutofillProfile profile(guid, kSettingsOrigin);
190 // Strings from JavaScript use UTF-8 encoding. This container is used as an
191 // intermediate container for functions which require UTF-16 strings.
192 std::vector<base::string16> string16Container;
194 if (address->full_names) {
195 std::string full_name;
196 if (!address->full_names->empty())
197 full_name = address->full_names->at(0);
198 profile.SetInfo(autofill::AutofillType(autofill::NAME_FULL),
199 base::UTF8ToUTF16(full_name),
200 g_browser_process->GetApplicationLocale());
203 if (address->company_name) {
204 profile.SetRawInfo(
205 autofill::COMPANY_NAME,
206 base::UTF8ToUTF16(*address->company_name));
209 if (address->address_lines) {
210 profile.SetRawInfo(
211 autofill::ADDRESS_HOME_STREET_ADDRESS,
212 base::UTF8ToUTF16(*address->address_lines));
215 if (address->address_level1) {
216 profile.SetRawInfo(
217 autofill::ADDRESS_HOME_CITY,
218 base::UTF8ToUTF16(*address->address_level1));
221 if (address->address_level2) {
222 profile.SetRawInfo(
223 autofill::ADDRESS_HOME_STATE,
224 base::UTF8ToUTF16(*address->address_level2));
227 if (address->address_level3) {
228 profile.SetRawInfo(
229 autofill::ADDRESS_HOME_DEPENDENT_LOCALITY,
230 base::UTF8ToUTF16(*address->address_level3));
233 if (address->postal_code) {
234 profile.SetRawInfo(
235 autofill::ADDRESS_HOME_ZIP,
236 base::UTF8ToUTF16(*address->postal_code));
239 if (address->sorting_code) {
240 profile.SetRawInfo(
241 autofill::ADDRESS_HOME_SORTING_CODE,
242 base::UTF8ToUTF16(*address->sorting_code));
245 if (address->country_code) {
246 profile.SetRawInfo(
247 autofill::ADDRESS_HOME_COUNTRY,
248 base::UTF8ToUTF16(*address->country_code));
251 if (address->phone_numbers) {
252 std::string phone;
253 if (!address->phone_numbers->empty())
254 phone = address->phone_numbers->at(0);
255 profile.SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER,
256 base::UTF8ToUTF16(phone));
259 if (address->email_addresses) {
260 std::string email;
261 if (!address->email_addresses->empty())
262 email = address->email_addresses->at(0);
263 profile.SetRawInfo(autofill::EMAIL_ADDRESS, base::UTF8ToUTF16(email));
266 if (address->language_code)
267 profile.set_language_code(*address->language_code);
269 if (!base::IsValidGUID(profile.guid())) {
270 profile.set_guid(base::GenerateGUID());
271 personal_data->AddProfile(profile);
272 } else {
273 personal_data->UpdateProfile(profile);
276 return RespondNow(NoArguments());
279 ////////////////////////////////////////////////////////////////////////////////
280 // AutofillPrivateGetAddressComponentsFunction
282 AutofillPrivateGetAddressComponentsFunction::
283 ~AutofillPrivateGetAddressComponentsFunction() {}
285 ExtensionFunction::ResponseAction
286 AutofillPrivateGetAddressComponentsFunction::Run() {
287 scoped_ptr<api::autofill_private::GetAddressComponents::Params> parameters =
288 api::autofill_private::GetAddressComponents::Params::Create(*args_);
289 EXTENSION_FUNCTION_VALIDATE(parameters.get());
291 autofill_private::AddressComponents components;
292 PopulateAddressComponents(
293 parameters->country_code,
294 g_browser_process->GetApplicationLocale(),
295 &components);
297 return RespondNow(OneArgument(components.ToValue().release()));
300 ////////////////////////////////////////////////////////////////////////////////
301 // AutofillPrivateSaveCreditCardFunction
303 AutofillPrivateSaveCreditCardFunction::AutofillPrivateSaveCreditCardFunction()
304 : chrome_details_(this) {}
306 AutofillPrivateSaveCreditCardFunction::
307 ~AutofillPrivateSaveCreditCardFunction() {}
309 ExtensionFunction::ResponseAction AutofillPrivateSaveCreditCardFunction::Run() {
310 scoped_ptr<api::autofill_private::SaveCreditCard::Params> parameters =
311 api::autofill_private::SaveCreditCard::Params::Create(*args_);
312 EXTENSION_FUNCTION_VALIDATE(parameters.get());
314 autofill::PersonalDataManager* personal_data =
315 autofill::PersonalDataManagerFactory::GetForProfile(
316 chrome_details_.GetProfile());
317 if (!personal_data || !personal_data->IsDataLoaded()) {
318 error_ = kErrorDataUnavailable;
319 return RespondNow(NoArguments());
322 api::autofill_private::CreditCardEntry* card = &parameters->card;
324 std::string guid = card->guid ? *card->guid : "";
325 autofill::CreditCard credit_card(guid, kSettingsOrigin);
327 if (card->name) {
328 credit_card.SetRawInfo(
329 autofill::CREDIT_CARD_NAME,
330 base::UTF8ToUTF16(*card->name));
333 if (card->card_number) {
334 credit_card.SetRawInfo(
335 autofill::CREDIT_CARD_NUMBER,
336 base::UTF8ToUTF16(*card->card_number));
339 if (card->expiration_month) {
340 credit_card.SetRawInfo(
341 autofill::CREDIT_CARD_EXP_MONTH,
342 base::UTF8ToUTF16(*card->expiration_month));
345 if (card->expiration_year) {
346 credit_card.SetRawInfo(
347 autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR,
348 base::UTF8ToUTF16(*card->expiration_year));
351 if (!base::IsValidGUID(credit_card.guid())) {
352 credit_card.set_guid(base::GenerateGUID());
353 personal_data->AddCreditCard(credit_card);
354 } else {
355 personal_data->UpdateCreditCard(credit_card);
358 return RespondNow(NoArguments());
361 ////////////////////////////////////////////////////////////////////////////////
362 // AutofillPrivateRemoveEntryFunction
364 AutofillPrivateRemoveEntryFunction::AutofillPrivateRemoveEntryFunction()
365 : chrome_details_(this) {}
367 AutofillPrivateRemoveEntryFunction::~AutofillPrivateRemoveEntryFunction() {}
369 ExtensionFunction::ResponseAction AutofillPrivateRemoveEntryFunction::Run() {
370 scoped_ptr<api::autofill_private::RemoveEntry::Params> parameters =
371 api::autofill_private::RemoveEntry::Params::Create(*args_);
372 EXTENSION_FUNCTION_VALIDATE(parameters.get());
374 autofill::PersonalDataManager* personal_data =
375 autofill::PersonalDataManagerFactory::GetForProfile(
376 chrome_details_.GetProfile());
377 if (!personal_data || !personal_data->IsDataLoaded()) {
378 error_ = kErrorDataUnavailable;
379 return RespondNow(NoArguments());
382 personal_data->RemoveByGUID(parameters->guid);
384 return RespondNow(NoArguments());
387 ////////////////////////////////////////////////////////////////////////////////
388 // AutofillPrivateValidatePhoneNumbersFunction
390 AutofillPrivateValidatePhoneNumbersFunction::
391 ~AutofillPrivateValidatePhoneNumbersFunction() {}
393 ExtensionFunction::ResponseAction
394 AutofillPrivateValidatePhoneNumbersFunction::Run() {
395 scoped_ptr<api::autofill_private::ValidatePhoneNumbers::Params> parameters =
396 api::autofill_private::ValidatePhoneNumbers::Params::Create(*args_);
397 EXTENSION_FUNCTION_VALIDATE(parameters.get());
399 api::autofill_private::ValidatePhoneParams* params = &parameters->params;
401 // Extract the phone numbers into a ListValue.
402 scoped_ptr<base::ListValue> phoneNumbers(new base::ListValue);
403 phoneNumbers->AppendStrings(params->phone_numbers);
405 RemoveDuplicatePhoneNumberAtIndex(
406 params->index_of_new_number, params->country_code, phoneNumbers.get());
408 return RespondNow(OneArgument(phoneNumbers.Pass()));
411 ////////////////////////////////////////////////////////////////////////////////
412 // AutofillPrivateMaskCreditCardFunction
414 AutofillPrivateMaskCreditCardFunction::AutofillPrivateMaskCreditCardFunction()
415 : chrome_details_(this) {}
417 AutofillPrivateMaskCreditCardFunction::
418 ~AutofillPrivateMaskCreditCardFunction() {}
420 ExtensionFunction::ResponseAction AutofillPrivateMaskCreditCardFunction::Run() {
421 scoped_ptr<api::autofill_private::MaskCreditCard::Params> parameters =
422 api::autofill_private::MaskCreditCard::Params::Create(*args_);
423 EXTENSION_FUNCTION_VALIDATE(parameters.get());
425 autofill::PersonalDataManager* personal_data =
426 autofill::PersonalDataManagerFactory::GetForProfile(
427 chrome_details_.GetProfile());
428 if (!personal_data || !personal_data->IsDataLoaded()) {
429 error_ = kErrorDataUnavailable;
430 return RespondNow(NoArguments());
433 personal_data->ResetFullServerCard(parameters->guid);
435 return RespondNow(NoArguments());
438 } // namespace extensions