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