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.
4
5 #include "chrome/browser/extensions/api/autofill_private/autofill_util.h"
6
7 #include <stddef.h>
8
9 #include <utility>
10 #include <vector>
11
12 #include "base/strings/string_split.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/extensions/api/settings_private/prefs_util.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/extensions/api/autofill_private.h"
18 #include "chrome/common/pref_names.h"
19 #include "components/autofill/core/browser/autofill_type.h"
20 #include "components/autofill/core/browser/data_model/autofill_profile.h"
21 #include "components/autofill/core/browser/data_model/credit_card.h"
22 #include "components/autofill/core/browser/field_types.h"
23 #include "components/autofill/core/browser/geo/autofill_country.h"
24 #include "components/autofill/core/browser/ui/country_combobox_model.h"
25 #include "components/prefs/pref_service.h"
26 #include "components/strings/grit/components_strings.h"
27 #include "ui/base/l10n/l10n_util.h"
28
29 namespace autofill_private = extensions::api::autofill_private;
30
31 namespace {
32
33 // Get the multi-valued element for |type| and return it as a |vector|.
34 // TODO(khorimoto): remove this function since multi-valued types are
35 // deprecated.
GetValueList(const autofill::AutofillProfile & profile,autofill::ServerFieldType type)36 std::unique_ptr<std::vector<std::string>> GetValueList(
37 const autofill::AutofillProfile& profile,
38 autofill::ServerFieldType type) {
39 std::unique_ptr<std::vector<std::string>> list(new std::vector<std::string>);
40
41 std::vector<base::string16> values;
42 if (autofill::AutofillType(type).group() == autofill::NAME) {
43 values.push_back(
44 profile.GetInfo(autofill::AutofillType(type),
45 g_browser_process->GetApplicationLocale()));
46 } else {
47 values.push_back(profile.GetRawInfo(type));
48 }
49
50 // |Get[Raw]MultiInfo()| always returns at least one, potentially empty, item.
51 // If this is the case, there is no info to return, so return an empty vector.
52 if (values.size() == 1 && values.front().empty())
53 return list;
54
55 for (const base::string16& value16 : values)
56 list->push_back(base::UTF16ToUTF8(value16));
57
58 return list;
59 }
60
61 // Gets the string corresponding to |type| from |profile|.
GetStringFromProfile(const autofill::AutofillProfile & profile,const autofill::ServerFieldType & type)62 std::unique_ptr<std::string> GetStringFromProfile(
63 const autofill::AutofillProfile& profile,
64 const autofill::ServerFieldType& type) {
65 return std::make_unique<std::string>(
66 base::UTF16ToUTF8(profile.GetRawInfo(type)));
67 }
68
ProfileToAddressEntry(const autofill::AutofillProfile & profile,const base::string16 & label)69 autofill_private::AddressEntry ProfileToAddressEntry(
70 const autofill::AutofillProfile& profile,
71 const base::string16& label) {
72 autofill_private::AddressEntry address;
73
74 // Add all address fields to the entry.
75 address.guid.reset(new std::string(profile.guid()));
76 address.full_names = GetValueList(profile, autofill::NAME_FULL);
77 address.company_name.reset(
78 GetStringFromProfile(profile, autofill::COMPANY_NAME).release());
79 address.address_lines.reset(
80 GetStringFromProfile(profile, autofill::ADDRESS_HOME_STREET_ADDRESS)
81 .release());
82 address.address_level1.reset(
83 GetStringFromProfile(profile, autofill::ADDRESS_HOME_STATE).release());
84 address.address_level2.reset(
85 GetStringFromProfile(profile, autofill::ADDRESS_HOME_CITY).release());
86 address.address_level3.reset(
87 GetStringFromProfile(profile, autofill::ADDRESS_HOME_DEPENDENT_LOCALITY)
88 .release());
89 address.postal_code.reset(
90 GetStringFromProfile(profile, autofill::ADDRESS_HOME_ZIP).release());
91 address.sorting_code.reset(
92 GetStringFromProfile(profile, autofill::ADDRESS_HOME_SORTING_CODE)
93 .release());
94 address.country_code.reset(
95 GetStringFromProfile(profile, autofill::ADDRESS_HOME_COUNTRY).release());
96 address.phone_numbers =
97 GetValueList(profile, autofill::PHONE_HOME_WHOLE_NUMBER);
98 address.email_addresses = GetValueList(profile, autofill::EMAIL_ADDRESS);
99 address.language_code.reset(new std::string(profile.language_code()));
100
101 // Parse |label| so that it can be used to create address metadata.
102 base::string16 separator =
103 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
104 std::vector<base::string16> label_pieces = base::SplitStringUsingSubstr(
105 label, separator, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
106
107 // Create address metadata and add it to |address|.
108 std::unique_ptr<autofill_private::AutofillMetadata> metadata(
109 new autofill_private::AutofillMetadata);
110 metadata->summary_label = base::UTF16ToUTF8(label_pieces[0]);
111 metadata->summary_sublabel.reset(new std::string(base::UTF16ToUTF8(
112 label.substr(label_pieces[0].size()))));
113 metadata->is_local.reset(new bool(
114 profile.record_type() == autofill::AutofillProfile::LOCAL_PROFILE));
115 address.metadata = std::move(metadata);
116
117 return address;
118 }
119
CountryToCountryEntry(autofill::AutofillCountry * country)120 autofill_private::CountryEntry CountryToCountryEntry(
121 autofill::AutofillCountry* country) {
122 autofill_private::CountryEntry entry;
123
124 // A null |country| means "insert a space here", so we add a country w/o a
125 // |name| or |country_code| to the list and let the UI handle it.
126 if (country) {
127 entry.name.reset(new std::string(base::UTF16ToUTF8(country->name())));
128 entry.country_code.reset(new std::string(country->country_code()));
129 }
130
131 return entry;
132 }
133
CreditCardToCreditCardEntry(const autofill::CreditCard & credit_card,const autofill::PersonalDataManager & personal_data)134 autofill_private::CreditCardEntry CreditCardToCreditCardEntry(
135 const autofill::CreditCard& credit_card,
136 const autofill::PersonalDataManager& personal_data) {
137 autofill_private::CreditCardEntry card;
138
139 // Add all credit card fields to the entry.
140 card.guid.reset(new std::string(credit_card.guid()));
141 card.name.reset(new std::string(base::UTF16ToUTF8(
142 credit_card.GetRawInfo(autofill::CREDIT_CARD_NAME_FULL))));
143 card.card_number.reset(new std::string(
144 base::UTF16ToUTF8(credit_card.GetRawInfo(autofill::CREDIT_CARD_NUMBER))));
145 card.expiration_month.reset(new std::string(base::UTF16ToUTF8(
146 credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH))));
147 card.expiration_year.reset(new std::string(base::UTF16ToUTF8(
148 credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR))));
149 if (!credit_card.nickname().empty()) {
150 card.nickname.reset(
151 new std::string(base::UTF16ToUTF8(credit_card.nickname())));
152 }
153
154 // Create address metadata and add it to |address|.
155 std::unique_ptr<autofill_private::AutofillMetadata> metadata(
156 new autofill_private::AutofillMetadata);
157 std::pair<base::string16, base::string16> label_pieces =
158 credit_card.LabelPieces();
159 metadata->summary_label = base::UTF16ToUTF8(label_pieces.first);
160 metadata->summary_sublabel.reset(new std::string(base::UTF16ToUTF8(
161 label_pieces.second)));
162 metadata->is_local.reset(new bool(
163 credit_card.record_type() == autofill::CreditCard::LOCAL_CARD));
164 metadata->is_cached.reset(new bool(
165 credit_card.record_type() == autofill::CreditCard::FULL_SERVER_CARD));
166 // IsValid() checks if both card number and expiration date are valid.
167 // IsServerCard() checks whether there is a duplicated server card in
168 // |personal_data|.
169 metadata->is_migratable.reset(new bool(
170 credit_card.IsValid() && !personal_data.IsServerCard(&credit_card)));
171 card.metadata = std::move(metadata);
172
173 return card;
174 }
175
176 } // namespace
177
178 namespace extensions {
179
180 namespace autofill_util {
181
GenerateAddressList(const autofill::PersonalDataManager & personal_data)182 AddressEntryList GenerateAddressList(
183 const autofill::PersonalDataManager& personal_data) {
184 const std::vector<autofill::AutofillProfile*>& profiles =
185 personal_data.GetProfiles();
186 std::vector<base::string16> labels;
187 autofill::AutofillProfile::CreateDifferentiatingLabels(
188 profiles,
189 g_browser_process->GetApplicationLocale(),
190 &labels);
191 DCHECK_EQ(labels.size(), profiles.size());
192
193 AddressEntryList list;
194 for (size_t i = 0; i < profiles.size(); ++i)
195 list.push_back(ProfileToAddressEntry(*profiles[i], labels[i]));
196
197 return list;
198 }
199
GenerateCountryList(const autofill::PersonalDataManager & personal_data)200 CountryEntryList GenerateCountryList(
201 const autofill::PersonalDataManager& personal_data) {
202 autofill::CountryComboboxModel model;
203 model.SetCountries(personal_data,
204 base::RepeatingCallback<bool(const std::string&)>(),
205 g_browser_process->GetApplicationLocale());
206 const std::vector<std::unique_ptr<autofill::AutofillCountry>>& countries =
207 model.countries();
208
209 CountryEntryList list;
210
211 for (const auto& country : countries)
212 list.push_back(CountryToCountryEntry(country.get()));
213
214 return list;
215 }
216
GenerateCreditCardList(const autofill::PersonalDataManager & personal_data)217 CreditCardEntryList GenerateCreditCardList(
218 const autofill::PersonalDataManager& personal_data) {
219 const std::vector<autofill::CreditCard*>& cards =
220 personal_data.GetCreditCards();
221
222 CreditCardEntryList list;
223 for (const autofill::CreditCard* card : cards)
224 list.push_back(CreditCardToCreditCardEntry(*card, personal_data));
225
226 return list;
227 }
228
229 } // namespace autofill_util
230
231 } // namespace extensions
232