Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: components/autofill/core/browser/personal_data_manager_mac.mm

Issue 1130773004: mac: Add histograms to measure impact of Address Book integration. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/autofill/core/browser/personal_data_manager.h" 5 #include "components/autofill/core/browser/personal_data_manager.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #import <AddressBook/AddressBook.h> 9 #import <AddressBook/AddressBook.h>
10 10
11 #include "base/format_macros.h" 11 #include "base/format_macros.h"
12 #include "base/guid.h" 12 #include "base/guid.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #import "base/mac/scoped_nsexception_enabler.h" 14 #import "base/mac/scoped_nsexception_enabler.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h" 16 #include "base/memory/scoped_vector.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_service.h" 18 #include "base/prefs/pref_service.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/strings/sys_string_conversions.h" 20 #include "base/strings/sys_string_conversions.h"
21 #include "base/time/time.h"
21 #include "components/autofill/core/browser/autofill_country.h" 22 #include "components/autofill/core/browser/autofill_country.h"
22 #include "components/autofill/core/browser/autofill_profile.h" 23 #include "components/autofill/core/browser/autofill_profile.h"
23 #include "components/autofill/core/browser/autofill_type.h" 24 #include "components/autofill/core/browser/autofill_type.h"
24 #include "components/autofill/core/browser/form_structure.h" 25 #include "components/autofill/core/browser/form_structure.h"
25 #include "components/autofill/core/browser/phone_number.h" 26 #include "components/autofill/core/browser/phone_number.h"
26 #include "components/autofill/core/common/autofill_pref_names.h" 27 #include "components/autofill/core/common/autofill_pref_names.h"
27 #include "components/autofill/core/common/form_data.h" 28 #include "components/autofill/core/common/form_data.h"
28 #include "grit/components_strings.h" 29 #include "grit/components_strings.h"
29 #include "ui/base/l10n/l10n_util_mac.h" 30 #include "ui/base/l10n/l10n_util_mac.h"
30 31
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 return pref_service->GetBoolean(prefs::kAutofillUseMacAddressBook); 70 return pref_service->GetBoolean(prefs::kAutofillUseMacAddressBook);
70 } 71 }
71 72
72 // Records a UMA metric indicating whether an attempt to access the Address 73 // Records a UMA metric indicating whether an attempt to access the Address
73 // Book was skipped because doing so would cause the Address Book permissions 74 // Book was skipped because doing so would cause the Address Book permissions
74 // prompt to incorrectly appear. 75 // prompt to incorrectly appear.
75 void RecordAccessSkipped(bool skipped) { 76 void RecordAccessSkipped(bool skipped) {
76 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBook.AccessSkipped", skipped); 77 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBook.AccessSkipped", skipped);
77 } 78 }
78 79
80 // Emits a histogram indicating whether the Address Book contained a me-card.
81 void EmitAddressBookContainedMeCard(bool containedMeCard) {
82 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.ContainedMeCard",
83 containedMeCard);
84 }
85
86 // Emits a histogram indicating whether the me-card had a name.
87 void EmitMeCardHadName(bool hadName) {
88 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadName",
89 hadName);
90 }
91
92 // Emits a histogram indicating whether the me-card had an address.
93 void EmitMeCardHadAddress(bool hadAddress) {
94 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadAddress",
95 hadAddress);
96 }
97
98 // Emits a histogram indicating whether the me-card had an email.
99 void EmitMeCardHadEmail(bool hadEmail) {
100 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadEmail",
101 hadEmail);
102 }
103
104 // Emits a histogram indicating whether the me-card had a phone number.
105 void EmitMeCardHadPhoneNumber(bool hadPhoneNumber) {
106 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadPhoneNumber",
107 hadPhoneNumber);
108 }
109
79 ABAddressBook* GetAddressBook(PrefService* pref_service) { 110 ABAddressBook* GetAddressBook(PrefService* pref_service) {
80 bool first_access = !HasQueriedMacAddressBook(pref_service); 111 bool first_access = !HasQueriedMacAddressBook(pref_service);
81 112
113 base::Time start_time = base::Time::Now();
82 // +[ABAddressBook sharedAddressBook] throws an exception internally in 114 // +[ABAddressBook sharedAddressBook] throws an exception internally in
83 // circumstances that aren't clear. The exceptions are only observed in crash 115 // circumstances that aren't clear. The exceptions are only observed in crash
84 // reports, so it is unknown whether they would be caught by AppKit and nil 116 // reports, so it is unknown whether they would be caught by AppKit and nil
85 // returned, or if they would take down the app. In either case, avoid 117 // returned, or if they would take down the app. In either case, avoid
86 // crashing. http://crbug.com/129022 118 // crashing. http://crbug.com/129022
87 ABAddressBook* addressBook = base::mac::RunBlockIgnoringExceptions( 119 ABAddressBook* addressBook = base::mac::RunBlockIgnoringExceptions(
88 ^{ return [ABAddressBook sharedAddressBook]; }); 120 ^{ return [ABAddressBook sharedAddressBook]; });
89 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailable", addressBook != nil); 121 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailable", addressBook != nil);
90 122
123 if (!g_accessed_address_book) {
124 // The amount of time that the access takes gives a good indication as to
125 // whether the user was shown a prompt.
126 UMA_HISTOGRAM_TIMES("Autofill.MacAddressBook.AccessTime",
127 base::Time::Now() - start_time);
128 }
129
91 if (first_access) { 130 if (first_access) {
92 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailableOnFirstAttempt", 131 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailableOnFirstAttempt",
93 addressBook != nil); 132 addressBook != nil);
94 } 133 }
95 134
96 g_accessed_address_book = true; 135 g_accessed_address_book = true;
97 pref_service->SetBoolean(prefs::kAutofillMacAddressBookQueried, true); 136 pref_service->SetBoolean(prefs::kAutofillMacAddressBookQueried, true);
98 return addressBook; 137 return addressBook;
99 } 138 }
100 139
(...skipping 13 matching lines...) Expand all
114 : profiles_(*profiles) { 153 : profiles_(*profiles) {
115 } 154 }
116 virtual ~AuxiliaryProfilesImpl() {} 155 virtual ~AuxiliaryProfilesImpl() {}
117 156
118 // Import the "me" card from the Mac Address Book and fill in |profiles_|. 157 // Import the "me" card from the Mac Address Book and fill in |profiles_|.
119 void GetAddressBookMeCard(const std::string& app_locale, 158 void GetAddressBookMeCard(const std::string& app_locale,
120 PrefService* pref_service, 159 PrefService* pref_service,
121 bool record_metrics); 160 bool record_metrics);
122 161
123 private: 162 private:
124 void GetAddressBookNames(ABPerson* me, 163 bool GetAddressBookNames(ABPerson* me,
125 NSString* addressLabelRaw, 164 NSString* addressLabelRaw,
126 AutofillProfile* profile); 165 AutofillProfile* profile);
127 void GetAddressBookAddress(const std::string& app_locale, 166 bool GetAddressBookAddress(const std::string& app_locale,
128 NSDictionary* address, 167 NSDictionary* address,
129 AutofillProfile* profile); 168 AutofillProfile* profile);
130 void GetAddressBookEmail(ABPerson* me, 169 bool GetAddressBookEmail(ABPerson* me,
131 NSString* addressLabelRaw, 170 NSString* addressLabelRaw,
132 AutofillProfile* profile); 171 AutofillProfile* profile);
133 void GetAddressBookPhoneNumbers(ABPerson* me, 172 bool GetAddressBookPhoneNumbers(ABPerson* me,
134 NSString* addressLabelRaw, 173 NSString* addressLabelRaw,
135 AutofillProfile* profile); 174 AutofillProfile* profile);
136 175
137 private: 176 private:
138 // A reference to the profiles this class populates. 177 // A reference to the profiles this class populates.
139 ScopedVector<AutofillProfile>& profiles_; 178 ScopedVector<AutofillProfile>& profiles_;
140 179
141 DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfilesImpl); 180 DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfilesImpl);
142 }; 181 };
143 182
(...skipping 18 matching lines...) Expand all
162 RecordAccessSkipped(true); 201 RecordAccessSkipped(true);
163 return; 202 return;
164 } 203 }
165 204
166 if (record_metrics) 205 if (record_metrics)
167 RecordAccessSkipped(false); 206 RecordAccessSkipped(false);
168 207
169 ABAddressBook* addressBook = GetAddressBook(pref_service); 208 ABAddressBook* addressBook = GetAddressBook(pref_service);
170 209
171 ABPerson* me = [addressBook me]; 210 ABPerson* me = [addressBook me];
172 if (!me) 211 if (!me) {
212 EmitAddressBookContainedMeCard(false);
173 return; 213 return;
214 }
174 215
216 EmitAddressBookContainedMeCard(true);
175 ABMultiValue* addresses = [me valueForProperty:kABAddressProperty]; 217 ABMultiValue* addresses = [me valueForProperty:kABAddressProperty];
176 218
177 // The number of characters at the end of the GUID to reserve for 219 // The number of characters at the end of the GUID to reserve for
178 // distinguishing addresses within the "me" card. Cap the number of addresses 220 // distinguishing addresses within the "me" card. Cap the number of addresses
179 // we will fetch to the number that can be distinguished by this fragment of 221 // we will fetch to the number that can be distinguished by this fragment of
180 // the GUID. 222 // the GUID.
181 const size_t kNumAddressGUIDChars = 2; 223 const size_t kNumAddressGUIDChars = 2;
182 const size_t kNumHexDigits = 16; 224 const size_t kNumHexDigits = 16;
183 const size_t kMaxAddressCount = pow(kNumHexDigits, kNumAddressGUIDChars); 225 const size_t kMaxAddressCount = pow(kNumHexDigits, kNumAddressGUIDChars);
184 NSUInteger count = MIN([addresses count], kMaxAddressCount); 226 NSUInteger count = MIN([addresses count], kMaxAddressCount);
227
228 bool hasName = false;
229 bool hasEmail = false;
230 bool hasAddress = false;
231 bool hasPhoneNumber = false;
185 for (NSUInteger i = 0; i < count; i++) { 232 for (NSUInteger i = 0; i < count; i++) {
186 NSDictionary* address = [addresses valueAtIndex:i]; 233 NSDictionary* address = [addresses valueAtIndex:i];
187 NSString* addressLabelRaw = [addresses labelAtIndex:i]; 234 NSString* addressLabelRaw = [addresses labelAtIndex:i];
188 235
189 // Create a new profile where the guid is set to the guid portion of the 236 // Create a new profile where the guid is set to the guid portion of the
190 // |kABUIDProperty| taken from from the "me" address. The format of 237 // |kABUIDProperty| taken from from the "me" address. The format of
191 // the |kABUIDProperty| is "<guid>:ABPerson", so we're stripping off the 238 // the |kABUIDProperty| is "<guid>:ABPerson", so we're stripping off the
192 // raw guid here and using it directly, with one modification: we update the 239 // raw guid here and using it directly, with one modification: we update the
193 // last |kNumAddressGUIDChars| characters in the GUID to reflect the address 240 // last |kNumAddressGUIDChars| characters in the GUID to reflect the address
194 // variant. Note that we capped the number of addresses above, so this is 241 // variant. Note that we capped the number of addresses above, so this is
195 // safe. 242 // safe.
196 const size_t kGUIDLength = 36U; 243 const size_t kGUIDLength = 36U;
197 const size_t kTrimmedGUIDLength = kGUIDLength - kNumAddressGUIDChars; 244 const size_t kTrimmedGUIDLength = kGUIDLength - kNumAddressGUIDChars;
198 std::string guid = base::SysNSStringToUTF8( 245 std::string guid = base::SysNSStringToUTF8(
199 [me valueForProperty:kABUIDProperty]).substr(0, kTrimmedGUIDLength); 246 [me valueForProperty:kABUIDProperty]).substr(0, kTrimmedGUIDLength);
200 247
201 // The format string to print |kNumAddressGUIDChars| hexadecimal characters, 248 // The format string to print |kNumAddressGUIDChars| hexadecimal characters,
202 // left-padded with 0's. 249 // left-padded with 0's.
203 const std::string kAddressGUIDFormat = 250 const std::string kAddressGUIDFormat =
204 base::StringPrintf("%%0%" PRIuS "X", kNumAddressGUIDChars); 251 base::StringPrintf("%%0%" PRIuS "X", kNumAddressGUIDChars);
205 guid += base::StringPrintf(kAddressGUIDFormat.c_str(), i); 252 guid += base::StringPrintf(kAddressGUIDFormat.c_str(), i);
206 DCHECK_EQ(kGUIDLength, guid.size()); 253 DCHECK_EQ(kGUIDLength, guid.size());
207 254
208 scoped_ptr<AutofillProfile> profile( 255 scoped_ptr<AutofillProfile> profile(
209 new AutofillProfile(guid, kAddressBookOrigin)); 256 new AutofillProfile(guid, kAddressBookOrigin));
210 profile->set_record_type(AutofillProfile::AUXILIARY_PROFILE); 257 profile->set_record_type(AutofillProfile::AUXILIARY_PROFILE);
211 DCHECK(base::IsValidGUID(profile->guid())); 258 DCHECK(base::IsValidGUID(profile->guid()));
212 259
213 // Fill in name and company information. 260 // Fill in name and company information.
214 GetAddressBookNames(me, addressLabelRaw, profile.get()); 261 hasName |= GetAddressBookNames(me, addressLabelRaw, profile.get());
215 262
216 // Fill in address information. 263 // Fill in address information.
217 GetAddressBookAddress(app_locale, address, profile.get()); 264 hasEmail |= GetAddressBookAddress(app_locale, address, profile.get());
218 265
219 // Fill in email information. 266 // Fill in email information.
220 GetAddressBookEmail(me, addressLabelRaw, profile.get()); 267 hasAddress |= GetAddressBookEmail(me, addressLabelRaw, profile.get());
221 268
222 // Fill in phone number information. 269 // Fill in phone number information.
223 GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get()); 270 hasPhoneNumber |=
271 GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get());
224 272
225 profiles_.push_back(profile.release()); 273 profiles_.push_back(profile.release());
226 } 274 }
275
276 EmitMeCardHadName(hasName);
277 EmitMeCardHadEmail(hasEmail);
278 EmitMeCardHadAddress(hasAddress);
279 EmitMeCardHadPhoneNumber(hasPhoneNumber);
227 } 280 }
228 281
229 // Name and company information is stored once in the Address Book against 282 // Name and company information is stored once in the Address Book against
230 // multiple addresses. We replicate that information for each profile. 283 // multiple addresses. We replicate that information for each profile.
231 // We only propagate the company name to work profiles. 284 // We only propagate the company name to work profiles.
232 void AuxiliaryProfilesImpl::GetAddressBookNames( 285 // Returns whether |me| contains any name information.
286 bool AuxiliaryProfilesImpl::GetAddressBookNames(
233 ABPerson* me, 287 ABPerson* me,
234 NSString* addressLabelRaw, 288 NSString* addressLabelRaw,
235 AutofillProfile* profile) { 289 AutofillProfile* profile) {
236 NSString* firstName = [me valueForProperty:kABFirstNameProperty]; 290 NSString* firstName = [me valueForProperty:kABFirstNameProperty];
237 NSString* middleName = [me valueForProperty:kABMiddleNameProperty]; 291 NSString* middleName = [me valueForProperty:kABMiddleNameProperty];
238 NSString* lastName = [me valueForProperty:kABLastNameProperty]; 292 NSString* lastName = [me valueForProperty:kABLastNameProperty];
239 NSString* companyName = [me valueForProperty:kABOrganizationProperty]; 293 NSString* companyName = [me valueForProperty:kABOrganizationProperty];
240 294
241 profile->SetRawInfo(NAME_FIRST, base::SysNSStringToUTF16(firstName)); 295 profile->SetRawInfo(NAME_FIRST, base::SysNSStringToUTF16(firstName));
242 profile->SetRawInfo(NAME_MIDDLE, base::SysNSStringToUTF16(middleName)); 296 profile->SetRawInfo(NAME_MIDDLE, base::SysNSStringToUTF16(middleName));
243 profile->SetRawInfo(NAME_LAST, base::SysNSStringToUTF16(lastName)); 297 profile->SetRawInfo(NAME_LAST, base::SysNSStringToUTF16(lastName));
244 if ([addressLabelRaw isEqualToString:kABAddressWorkLabel]) 298 bool hasValidCompanyName = false;
299 if ([addressLabelRaw isEqualToString:kABAddressWorkLabel]) {
245 profile->SetRawInfo(COMPANY_NAME, base::SysNSStringToUTF16(companyName)); 300 profile->SetRawInfo(COMPANY_NAME, base::SysNSStringToUTF16(companyName));
301 hasValidCompanyName = [companyName length] > 0;
Ilya Sherman 2015/05/15 21:14:58 I don't think the company name has much to do with
erikchen 2015/05/15 21:37:23 Done.
302 }
303
304 return [firstName length] > 0 || [middleName length] > 0 ||
305 [lastName length] > 0 || hasValidCompanyName;
246 } 306 }
247 307
248 // Addresss information from the Address Book may span multiple lines. 308 // Addresss information from the Address Book may span multiple lines.
249 // If it does then we represent the address with two lines in the profile. The 309 // If it does then we represent the address with two lines in the profile. The
250 // second line we join with commas. 310 // second line we join with commas.
251 // For example: "c/o John Doe\n1122 Other Avenue\nApt #7" translates to 311 // For example: "c/o John Doe\n1122 Other Avenue\nApt #7" translates to
252 // line 1: "c/o John Doe", line 2: "1122 Other Avenue, Apt #7". 312 // line 1: "c/o John Doe", line 2: "1122 Other Avenue, Apt #7".
253 void AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale, 313 // Returns whether |address| contains any address information.
314 bool AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale,
254 NSDictionary* address, 315 NSDictionary* address,
255 AutofillProfile* profile) { 316 AutofillProfile* profile) {
317 bool hasAnyAddressInformation = false;
256 if (NSString* addressField = [address objectForKey:kABAddressStreetKey]) { 318 if (NSString* addressField = [address objectForKey:kABAddressStreetKey]) {
319 hasAnyAddressInformation |= [addressField length] > 0;
320
257 // If there are newlines in the address, split into two lines. 321 // If there are newlines in the address, split into two lines.
258 if ([addressField rangeOfCharacterFromSet: 322 if ([addressField rangeOfCharacterFromSet:
259 [NSCharacterSet newlineCharacterSet]].location != NSNotFound) { 323 [NSCharacterSet newlineCharacterSet]].location != NSNotFound) {
260 NSArray* chunks = [addressField componentsSeparatedByCharactersInSet: 324 NSArray* chunks = [addressField componentsSeparatedByCharactersInSet:
261 [NSCharacterSet newlineCharacterSet]]; 325 [NSCharacterSet newlineCharacterSet]];
262 DCHECK([chunks count] > 1); 326 DCHECK([chunks count] > 1);
263 327
264 NSString* separator = 328 NSString* separator =
265 l10n_util::GetNSString(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR); 329 l10n_util::GetNSString(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR);
266 330
267 NSString* addressField1 = [chunks objectAtIndex:0]; 331 NSString* addressField1 = [chunks objectAtIndex:0];
268 NSString* addressField2 = 332 NSString* addressField2 =
269 [[chunks subarrayWithRange:NSMakeRange(1, [chunks count] - 1)] 333 [[chunks subarrayWithRange:NSMakeRange(1, [chunks count] - 1)]
270 componentsJoinedByString:separator]; 334 componentsJoinedByString:separator];
271 profile->SetRawInfo(ADDRESS_HOME_LINE1, 335 profile->SetRawInfo(ADDRESS_HOME_LINE1,
272 base::SysNSStringToUTF16(addressField1)); 336 base::SysNSStringToUTF16(addressField1));
273 profile->SetRawInfo(ADDRESS_HOME_LINE2, 337 profile->SetRawInfo(ADDRESS_HOME_LINE2,
274 base::SysNSStringToUTF16(addressField2)); 338 base::SysNSStringToUTF16(addressField2));
275 } else { 339 } else {
276 profile->SetRawInfo(ADDRESS_HOME_LINE1, 340 profile->SetRawInfo(ADDRESS_HOME_LINE1,
277 base::SysNSStringToUTF16(addressField)); 341 base::SysNSStringToUTF16(addressField));
278 } 342 }
279 } 343 }
280 344
281 if (NSString* city = [address objectForKey:kABAddressCityKey]) 345 if (NSString* city = [address objectForKey:kABAddressCityKey]) {
346 hasAnyAddressInformation |= [city length] > 0;
282 profile->SetRawInfo(ADDRESS_HOME_CITY, base::SysNSStringToUTF16(city)); 347 profile->SetRawInfo(ADDRESS_HOME_CITY, base::SysNSStringToUTF16(city));
348 }
283 349
284 if (NSString* state = [address objectForKey:kABAddressStateKey]) 350 if (NSString* state = [address objectForKey:kABAddressStateKey]) {
351 hasAnyAddressInformation |= [state length] > 0;
285 profile->SetRawInfo(ADDRESS_HOME_STATE, base::SysNSStringToUTF16(state)); 352 profile->SetRawInfo(ADDRESS_HOME_STATE, base::SysNSStringToUTF16(state));
353 }
286 354
287 if (NSString* zip = [address objectForKey:kABAddressZIPKey]) 355 if (NSString* zip = [address objectForKey:kABAddressZIPKey]) {
356 hasAnyAddressInformation |= [zip length] > 0;
288 profile->SetRawInfo(ADDRESS_HOME_ZIP, base::SysNSStringToUTF16(zip)); 357 profile->SetRawInfo(ADDRESS_HOME_ZIP, base::SysNSStringToUTF16(zip));
358 }
289 359
290 if (NSString* country = [address objectForKey:kABAddressCountryKey]) { 360 if (NSString* country = [address objectForKey:kABAddressCountryKey]) {
361 hasAnyAddressInformation |= [country length] > 0;
291 profile->SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), 362 profile->SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
292 base::SysNSStringToUTF16(country), 363 base::SysNSStringToUTF16(country),
293 app_locale); 364 app_locale);
294 } 365 }
366
367 return hasAnyAddressInformation;
Ilya Sherman 2015/05/15 21:14:58 I think this is perhaps too lax to be useful. For
erikchen 2015/05/15 21:37:23 Done.
295 } 368 }
296 369
297 // Fills in email address matching current address label. Note that there may 370 // Fills in email address matching current address label. Note that there may
298 // be multiple matching email addresses for a given label. We take the 371 // be multiple matching email addresses for a given label. We take the
299 // first we find (topmost) as preferred. 372 // first we find (topmost) as preferred.
300 void AuxiliaryProfilesImpl::GetAddressBookEmail( 373 // Returns whether |me| contains an email.
374 bool AuxiliaryProfilesImpl::GetAddressBookEmail(
301 ABPerson* me, 375 ABPerson* me,
302 NSString* addressLabelRaw, 376 NSString* addressLabelRaw,
303 AutofillProfile* profile) { 377 AutofillProfile* profile) {
304 ABMultiValue* emailAddresses = [me valueForProperty:kABEmailProperty]; 378 ABMultiValue* emailAddresses = [me valueForProperty:kABEmailProperty];
305 NSString* emailAddress = nil; 379 NSString* emailAddress = nil;
306 for (NSUInteger j = 0, emailCount = [emailAddresses count]; 380 for (NSUInteger j = 0, emailCount = [emailAddresses count];
307 j < emailCount; j++) { 381 j < emailCount; j++) {
308 NSString* emailAddressLabelRaw = [emailAddresses labelAtIndex:j]; 382 NSString* emailAddressLabelRaw = [emailAddresses labelAtIndex:j];
309 if ([emailAddressLabelRaw isEqualToString:addressLabelRaw]) { 383 if ([emailAddressLabelRaw isEqualToString:addressLabelRaw]) {
310 emailAddress = [emailAddresses valueAtIndex:j]; 384 emailAddress = [emailAddresses valueAtIndex:j];
311 break; 385 break;
312 } 386 }
313 } 387 }
314 profile->SetRawInfo(EMAIL_ADDRESS, base::SysNSStringToUTF16(emailAddress)); 388 profile->SetRawInfo(EMAIL_ADDRESS, base::SysNSStringToUTF16(emailAddress));
389 return [emailAddress length] > 0;
315 } 390 }
316 391
317 // Fills in telephone numbers. Each of these are special cases. 392 // Fills in telephone numbers. Each of these are special cases.
318 // We match two cases: home/tel, work/tel. 393 // We match two cases: home/tel, work/tel.
319 // Note, we traverse in reverse order so that top values in address book 394 // Note, we traverse in reverse order so that top values in address book
320 // take priority. 395 // take priority.
321 void AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers( 396 // Returns whether |me| contains a phone number.
397 bool AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers(
322 ABPerson* me, 398 ABPerson* me,
323 NSString* addressLabelRaw, 399 NSString* addressLabelRaw,
324 AutofillProfile* profile) { 400 AutofillProfile* profile) {
401 bool hasPhoneNumber = false;
325 ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty]; 402 ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty];
326 for (NSUInteger k = 0, phoneCount = [phoneNumbers count]; 403 for (NSUInteger k = 0, phoneCount = [phoneNumbers count];
327 k < phoneCount; k++) { 404 k < phoneCount; k++) {
328 NSUInteger reverseK = phoneCount - k - 1; 405 NSUInteger reverseK = phoneCount - k - 1;
329 NSString* phoneLabelRaw = [phoneNumbers labelAtIndex:reverseK]; 406 NSString* phoneLabelRaw = [phoneNumbers labelAtIndex:reverseK];
330 if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] && 407 if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] &&
331 [phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) { 408 [phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) {
332 base::string16 homePhone = base::SysNSStringToUTF16( 409 base::string16 homePhone = base::SysNSStringToUTF16(
333 [phoneNumbers valueAtIndex:reverseK]); 410 [phoneNumbers valueAtIndex:reverseK]);
334 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, homePhone); 411 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, homePhone);
412 hasPhoneNumber |= !homePhone.empty();
335 } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] && 413 } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
336 [phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) { 414 [phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) {
337 base::string16 workPhone = base::SysNSStringToUTF16( 415 base::string16 workPhone = base::SysNSStringToUTF16(
338 [phoneNumbers valueAtIndex:reverseK]); 416 [phoneNumbers valueAtIndex:reverseK]);
339 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, workPhone); 417 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, workPhone);
418 hasPhoneNumber |= !workPhone.empty();
340 } else if ([phoneLabelRaw isEqualToString:kABPhoneMobileLabel] || 419 } else if ([phoneLabelRaw isEqualToString:kABPhoneMobileLabel] ||
341 [phoneLabelRaw isEqualToString:kABPhoneMainLabel]) { 420 [phoneLabelRaw isEqualToString:kABPhoneMainLabel]) {
342 base::string16 phone = base::SysNSStringToUTF16( 421 base::string16 phone = base::SysNSStringToUTF16(
343 [phoneNumbers valueAtIndex:reverseK]); 422 [phoneNumbers valueAtIndex:reverseK]);
344 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, phone); 423 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, phone);
424 hasPhoneNumber |= !phone.empty();
345 } 425 }
346 } 426 }
427 return hasPhoneNumber;
347 } 428 }
348 429
349 } // namespace 430 } // namespace
350 431
351 // Populate |auxiliary_profiles_| with the Address Book data. 432 // Populate |auxiliary_profiles_| with the Address Book data.
352 void PersonalDataManager::LoadAuxiliaryProfiles(bool record_metrics) const { 433 void PersonalDataManager::LoadAuxiliaryProfiles(bool record_metrics) const {
353 AuxiliaryProfilesImpl impl(&auxiliary_profiles_); 434 AuxiliaryProfilesImpl impl(&auxiliary_profiles_);
354 impl.GetAddressBookMeCard(app_locale_, pref_service_, record_metrics); 435 impl.GetAddressBookMeCard(app_locale_, pref_service_, record_metrics);
355 } 436 }
356 437
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 490
410 int PersonalDataManager::AccessAddressBookPromptCount() { 491 int PersonalDataManager::AccessAddressBookPromptCount() {
411 return pref_service_->GetInteger(prefs::kAutofillMacAddressBookShowedCount); 492 return pref_service_->GetInteger(prefs::kAutofillMacAddressBookShowedCount);
412 } 493 }
413 494
414 void PersonalDataManager::BinaryChanging() { 495 void PersonalDataManager::BinaryChanging() {
415 g_binary_changed = true; 496 g_binary_changed = true;
416 } 497 }
417 498
418 } // namespace autofill 499 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698