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

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: Comments from isherman, round five. 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", hadName);
89 }
90
91 // Emits a histogram indicating whether the me-card had an address.
92 void EmitMeCardHadAddress(bool hadAddress) {
93 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadAddress",
94 hadAddress);
95 }
96
97 // Emits a histogram indicating whether the me-card had an email.
98 void EmitMeCardHadEmail(bool hadEmail) {
99 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadEmail", hadEmail);
100 }
101
102 // Emits a histogram indicating whether the me-card had a phone number.
103 void EmitMeCardHadPhoneNumber(bool hadPhoneNumber) {
104 UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadPhoneNumber",
105 hadPhoneNumber);
106 }
107
79 ABAddressBook* GetAddressBook(PrefService* pref_service) { 108 ABAddressBook* GetAddressBook(PrefService* pref_service) {
80 bool first_access = !HasQueriedMacAddressBook(pref_service); 109 bool first_access = !HasQueriedMacAddressBook(pref_service);
81 110
111 base::Time start_time = base::Time::Now();
82 // +[ABAddressBook sharedAddressBook] throws an exception internally in 112 // +[ABAddressBook sharedAddressBook] throws an exception internally in
83 // circumstances that aren't clear. The exceptions are only observed in crash 113 // 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 114 // 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 115 // returned, or if they would take down the app. In either case, avoid
86 // crashing. http://crbug.com/129022 116 // crashing. http://crbug.com/129022
87 ABAddressBook* addressBook = base::mac::RunBlockIgnoringExceptions( 117 ABAddressBook* addressBook = base::mac::RunBlockIgnoringExceptions(
88 ^{ return [ABAddressBook sharedAddressBook]; }); 118 ^{ return [ABAddressBook sharedAddressBook]; });
89 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailable", addressBook != nil); 119 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailable", addressBook != nil);
90 120
121 if (!g_accessed_address_book) {
122 // The amount of time that the access takes gives a good indication as to
123 // whether the user was shown a prompt.
124 UMA_HISTOGRAM_TIMES("Autofill.MacAddressBook.AccessTime",
125 base::Time::Now() - start_time);
126 }
127
91 if (first_access) { 128 if (first_access) {
92 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailableOnFirstAttempt", 129 UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailableOnFirstAttempt",
93 addressBook != nil); 130 addressBook != nil);
94 } 131 }
95 132
96 g_accessed_address_book = true; 133 g_accessed_address_book = true;
97 pref_service->SetBoolean(prefs::kAutofillMacAddressBookQueried, true); 134 pref_service->SetBoolean(prefs::kAutofillMacAddressBookQueried, true);
98 return addressBook; 135 return addressBook;
99 } 136 }
100 137
(...skipping 13 matching lines...) Expand all
114 : profiles_(*profiles) { 151 : profiles_(*profiles) {
115 } 152 }
116 virtual ~AuxiliaryProfilesImpl() {} 153 virtual ~AuxiliaryProfilesImpl() {}
117 154
118 // Import the "me" card from the Mac Address Book and fill in |profiles_|. 155 // Import the "me" card from the Mac Address Book and fill in |profiles_|.
119 void GetAddressBookMeCard(const std::string& app_locale, 156 void GetAddressBookMeCard(const std::string& app_locale,
120 PrefService* pref_service, 157 PrefService* pref_service,
121 bool record_metrics); 158 bool record_metrics);
122 159
123 private: 160 private:
124 void GetAddressBookNames(ABPerson* me, 161 bool GetAddressBookNames(ABPerson* me,
125 NSString* addressLabelRaw, 162 NSString* addressLabelRaw,
126 AutofillProfile* profile); 163 AutofillProfile* profile);
127 void GetAddressBookAddress(const std::string& app_locale, 164 bool GetAddressBookAddress(const std::string& app_locale,
128 NSDictionary* address, 165 NSDictionary* address,
129 AutofillProfile* profile); 166 AutofillProfile* profile);
130 void GetAddressBookEmail(ABPerson* me, 167 bool GetAddressBookEmail(ABPerson* me,
131 NSString* addressLabelRaw, 168 NSString* addressLabelRaw,
132 AutofillProfile* profile); 169 AutofillProfile* profile);
133 void GetAddressBookPhoneNumbers(ABPerson* me, 170 bool GetAddressBookPhoneNumbers(ABPerson* me,
134 NSString* addressLabelRaw, 171 NSString* addressLabelRaw,
135 AutofillProfile* profile); 172 AutofillProfile* profile);
136 173
137 private: 174 private:
138 // A reference to the profiles this class populates. 175 // A reference to the profiles this class populates.
139 ScopedVector<AutofillProfile>& profiles_; 176 ScopedVector<AutofillProfile>& profiles_;
140 177
141 DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfilesImpl); 178 DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfilesImpl);
142 }; 179 };
143 180
(...skipping 18 matching lines...) Expand all
162 RecordAccessSkipped(true); 199 RecordAccessSkipped(true);
163 return; 200 return;
164 } 201 }
165 202
166 if (record_metrics) 203 if (record_metrics)
167 RecordAccessSkipped(false); 204 RecordAccessSkipped(false);
168 205
169 ABAddressBook* addressBook = GetAddressBook(pref_service); 206 ABAddressBook* addressBook = GetAddressBook(pref_service);
170 207
171 ABPerson* me = [addressBook me]; 208 ABPerson* me = [addressBook me];
172 if (!me) 209 if (!me) {
210 EmitAddressBookContainedMeCard(false);
173 return; 211 return;
212 }
174 213
214 EmitAddressBookContainedMeCard(true);
175 ABMultiValue* addresses = [me valueForProperty:kABAddressProperty]; 215 ABMultiValue* addresses = [me valueForProperty:kABAddressProperty];
176 216
177 // The number of characters at the end of the GUID to reserve for 217 // 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 218 // 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 219 // we will fetch to the number that can be distinguished by this fragment of
180 // the GUID. 220 // the GUID.
181 const size_t kNumAddressGUIDChars = 2; 221 const size_t kNumAddressGUIDChars = 2;
182 const size_t kNumHexDigits = 16; 222 const size_t kNumHexDigits = 16;
183 const size_t kMaxAddressCount = pow(kNumHexDigits, kNumAddressGUIDChars); 223 const size_t kMaxAddressCount = pow(kNumHexDigits, kNumAddressGUIDChars);
184 NSUInteger count = MIN([addresses count], kMaxAddressCount); 224 NSUInteger count = MIN([addresses count], kMaxAddressCount);
225
226 bool hasName = false;
227 bool hasEmail = false;
228 bool hasAddress = false;
229 bool hasPhoneNumber = false;
185 for (NSUInteger i = 0; i < count; i++) { 230 for (NSUInteger i = 0; i < count; i++) {
186 NSDictionary* address = [addresses valueAtIndex:i]; 231 NSDictionary* address = [addresses valueAtIndex:i];
187 NSString* addressLabelRaw = [addresses labelAtIndex:i]; 232 NSString* addressLabelRaw = [addresses labelAtIndex:i];
188 233
189 // Create a new profile where the guid is set to the guid portion of the 234 // 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 235 // |kABUIDProperty| taken from from the "me" address. The format of
191 // the |kABUIDProperty| is "<guid>:ABPerson", so we're stripping off the 236 // 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 237 // raw guid here and using it directly, with one modification: we update the
193 // last |kNumAddressGUIDChars| characters in the GUID to reflect the address 238 // last |kNumAddressGUIDChars| characters in the GUID to reflect the address
194 // variant. Note that we capped the number of addresses above, so this is 239 // variant. Note that we capped the number of addresses above, so this is
195 // safe. 240 // safe.
196 const size_t kGUIDLength = 36U; 241 const size_t kGUIDLength = 36U;
197 const size_t kTrimmedGUIDLength = kGUIDLength - kNumAddressGUIDChars; 242 const size_t kTrimmedGUIDLength = kGUIDLength - kNumAddressGUIDChars;
198 std::string guid = base::SysNSStringToUTF8( 243 std::string guid = base::SysNSStringToUTF8(
199 [me valueForProperty:kABUIDProperty]).substr(0, kTrimmedGUIDLength); 244 [me valueForProperty:kABUIDProperty]).substr(0, kTrimmedGUIDLength);
200 245
201 // The format string to print |kNumAddressGUIDChars| hexadecimal characters, 246 // The format string to print |kNumAddressGUIDChars| hexadecimal characters,
202 // left-padded with 0's. 247 // left-padded with 0's.
203 const std::string kAddressGUIDFormat = 248 const std::string kAddressGUIDFormat =
204 base::StringPrintf("%%0%" PRIuS "X", kNumAddressGUIDChars); 249 base::StringPrintf("%%0%" PRIuS "X", kNumAddressGUIDChars);
205 guid += base::StringPrintf(kAddressGUIDFormat.c_str(), i); 250 guid += base::StringPrintf(kAddressGUIDFormat.c_str(), i);
206 DCHECK_EQ(kGUIDLength, guid.size()); 251 DCHECK_EQ(kGUIDLength, guid.size());
207 252
208 scoped_ptr<AutofillProfile> profile( 253 scoped_ptr<AutofillProfile> profile(
209 new AutofillProfile(guid, kAddressBookOrigin)); 254 new AutofillProfile(guid, kAddressBookOrigin));
210 profile->set_record_type(AutofillProfile::AUXILIARY_PROFILE); 255 profile->set_record_type(AutofillProfile::AUXILIARY_PROFILE);
211 DCHECK(base::IsValidGUID(profile->guid())); 256 DCHECK(base::IsValidGUID(profile->guid()));
212 257
213 // Fill in name and company information. 258 // Fill in name and company information.
214 GetAddressBookNames(me, addressLabelRaw, profile.get()); 259 hasName |= GetAddressBookNames(me, addressLabelRaw, profile.get());
215 260
216 // Fill in address information. 261 // Fill in address information.
217 GetAddressBookAddress(app_locale, address, profile.get()); 262 hasEmail |= GetAddressBookAddress(app_locale, address, profile.get());
218 263
219 // Fill in email information. 264 // Fill in email information.
220 GetAddressBookEmail(me, addressLabelRaw, profile.get()); 265 hasAddress |= GetAddressBookEmail(me, addressLabelRaw, profile.get());
221 266
222 // Fill in phone number information. 267 // Fill in phone number information.
223 GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get()); 268 hasPhoneNumber |=
269 GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get());
224 270
225 profiles_.push_back(profile.release()); 271 profiles_.push_back(profile.release());
226 } 272 }
273
274 EmitMeCardHadName(hasName);
275 EmitMeCardHadEmail(hasEmail);
276 EmitMeCardHadAddress(hasAddress);
277 EmitMeCardHadPhoneNumber(hasPhoneNumber);
227 } 278 }
228 279
229 // Name and company information is stored once in the Address Book against 280 // Name and company information is stored once in the Address Book against
230 // multiple addresses. We replicate that information for each profile. 281 // multiple addresses. We replicate that information for each profile.
231 // We only propagate the company name to work profiles. 282 // We only propagate the company name to work profiles.
232 void AuxiliaryProfilesImpl::GetAddressBookNames( 283 // Returns whether |me| contains any name information.
233 ABPerson* me, 284 bool AuxiliaryProfilesImpl::GetAddressBookNames(ABPerson* me,
234 NSString* addressLabelRaw, 285 NSString* addressLabelRaw,
235 AutofillProfile* profile) { 286 AutofillProfile* profile) {
236 NSString* firstName = [me valueForProperty:kABFirstNameProperty]; 287 NSString* firstName = [me valueForProperty:kABFirstNameProperty];
237 NSString* middleName = [me valueForProperty:kABMiddleNameProperty]; 288 NSString* middleName = [me valueForProperty:kABMiddleNameProperty];
238 NSString* lastName = [me valueForProperty:kABLastNameProperty]; 289 NSString* lastName = [me valueForProperty:kABLastNameProperty];
239 NSString* companyName = [me valueForProperty:kABOrganizationProperty]; 290 NSString* companyName = [me valueForProperty:kABOrganizationProperty];
240 291
241 profile->SetRawInfo(NAME_FIRST, base::SysNSStringToUTF16(firstName)); 292 profile->SetRawInfo(NAME_FIRST, base::SysNSStringToUTF16(firstName));
242 profile->SetRawInfo(NAME_MIDDLE, base::SysNSStringToUTF16(middleName)); 293 profile->SetRawInfo(NAME_MIDDLE, base::SysNSStringToUTF16(middleName));
243 profile->SetRawInfo(NAME_LAST, base::SysNSStringToUTF16(lastName)); 294 profile->SetRawInfo(NAME_LAST, base::SysNSStringToUTF16(lastName));
244 if ([addressLabelRaw isEqualToString:kABAddressWorkLabel]) 295 if ([addressLabelRaw isEqualToString:kABAddressWorkLabel])
245 profile->SetRawInfo(COMPANY_NAME, base::SysNSStringToUTF16(companyName)); 296 profile->SetRawInfo(COMPANY_NAME, base::SysNSStringToUTF16(companyName));
297
298 return [firstName length] > 0 || [middleName length] > 0 ||
299 [lastName length] > 0;
246 } 300 }
247 301
248 // Addresss information from the Address Book may span multiple lines. 302 // 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 303 // If it does then we represent the address with two lines in the profile. The
250 // second line we join with commas. 304 // second line we join with commas.
251 // For example: "c/o John Doe\n1122 Other Avenue\nApt #7" translates to 305 // 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". 306 // line 1: "c/o John Doe", line 2: "1122 Other Avenue, Apt #7".
253 void AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale, 307 // Returns whether |address| contains a complete address.
308 bool AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale,
254 NSDictionary* address, 309 NSDictionary* address,
255 AutofillProfile* profile) { 310 AutofillProfile* profile) {
311 bool hasStreetAddress = false;
312 bool hasCityOrZip = false;
256 if (NSString* addressField = [address objectForKey:kABAddressStreetKey]) { 313 if (NSString* addressField = [address objectForKey:kABAddressStreetKey]) {
314 hasStreetAddress |= [addressField length] > 0;
315
257 // If there are newlines in the address, split into two lines. 316 // If there are newlines in the address, split into two lines.
258 if ([addressField rangeOfCharacterFromSet: 317 if ([addressField rangeOfCharacterFromSet:
259 [NSCharacterSet newlineCharacterSet]].location != NSNotFound) { 318 [NSCharacterSet newlineCharacterSet]].location != NSNotFound) {
260 NSArray* chunks = [addressField componentsSeparatedByCharactersInSet: 319 NSArray* chunks = [addressField componentsSeparatedByCharactersInSet:
261 [NSCharacterSet newlineCharacterSet]]; 320 [NSCharacterSet newlineCharacterSet]];
262 DCHECK([chunks count] > 1); 321 DCHECK([chunks count] > 1);
263 322
264 NSString* separator = 323 NSString* separator =
265 l10n_util::GetNSString(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR); 324 l10n_util::GetNSString(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR);
266 325
267 NSString* addressField1 = [chunks objectAtIndex:0]; 326 NSString* addressField1 = [chunks objectAtIndex:0];
268 NSString* addressField2 = 327 NSString* addressField2 =
269 [[chunks subarrayWithRange:NSMakeRange(1, [chunks count] - 1)] 328 [[chunks subarrayWithRange:NSMakeRange(1, [chunks count] - 1)]
270 componentsJoinedByString:separator]; 329 componentsJoinedByString:separator];
271 profile->SetRawInfo(ADDRESS_HOME_LINE1, 330 profile->SetRawInfo(ADDRESS_HOME_LINE1,
272 base::SysNSStringToUTF16(addressField1)); 331 base::SysNSStringToUTF16(addressField1));
273 profile->SetRawInfo(ADDRESS_HOME_LINE2, 332 profile->SetRawInfo(ADDRESS_HOME_LINE2,
274 base::SysNSStringToUTF16(addressField2)); 333 base::SysNSStringToUTF16(addressField2));
275 } else { 334 } else {
276 profile->SetRawInfo(ADDRESS_HOME_LINE1, 335 profile->SetRawInfo(ADDRESS_HOME_LINE1,
277 base::SysNSStringToUTF16(addressField)); 336 base::SysNSStringToUTF16(addressField));
278 } 337 }
279 } 338 }
280 339
281 if (NSString* city = [address objectForKey:kABAddressCityKey]) 340 if (NSString* city = [address objectForKey:kABAddressCityKey]) {
341 hasCityOrZip |= [city length] > 0;
282 profile->SetRawInfo(ADDRESS_HOME_CITY, base::SysNSStringToUTF16(city)); 342 profile->SetRawInfo(ADDRESS_HOME_CITY, base::SysNSStringToUTF16(city));
343 }
283 344
284 if (NSString* state = [address objectForKey:kABAddressStateKey]) 345 if (NSString* state = [address objectForKey:kABAddressStateKey])
285 profile->SetRawInfo(ADDRESS_HOME_STATE, base::SysNSStringToUTF16(state)); 346 profile->SetRawInfo(ADDRESS_HOME_STATE, base::SysNSStringToUTF16(state));
286 347
287 if (NSString* zip = [address objectForKey:kABAddressZIPKey]) 348 if (NSString* zip = [address objectForKey:kABAddressZIPKey]) {
349 hasCityOrZip |= [zip length] > 0;
288 profile->SetRawInfo(ADDRESS_HOME_ZIP, base::SysNSStringToUTF16(zip)); 350 profile->SetRawInfo(ADDRESS_HOME_ZIP, base::SysNSStringToUTF16(zip));
351 }
289 352
290 if (NSString* country = [address objectForKey:kABAddressCountryKey]) { 353 if (NSString* country = [address objectForKey:kABAddressCountryKey])
291 profile->SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), 354 profile->SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
292 base::SysNSStringToUTF16(country), 355 base::SysNSStringToUTF16(country),
293 app_locale); 356 app_locale);
294 } 357
358 return hasStreetAddress && hasCityOrZip;
295 } 359 }
296 360
297 // Fills in email address matching current address label. Note that there may 361 // 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 362 // be multiple matching email addresses for a given label. We take the
299 // first we find (topmost) as preferred. 363 // first we find (topmost) as preferred.
300 void AuxiliaryProfilesImpl::GetAddressBookEmail( 364 // Returns whether |me| contains an email.
301 ABPerson* me, 365 bool AuxiliaryProfilesImpl::GetAddressBookEmail(ABPerson* me,
302 NSString* addressLabelRaw, 366 NSString* addressLabelRaw,
303 AutofillProfile* profile) { 367 AutofillProfile* profile) {
304 ABMultiValue* emailAddresses = [me valueForProperty:kABEmailProperty]; 368 ABMultiValue* emailAddresses = [me valueForProperty:kABEmailProperty];
305 NSString* emailAddress = nil; 369 NSString* emailAddress = nil;
306 for (NSUInteger j = 0, emailCount = [emailAddresses count]; 370 for (NSUInteger j = 0, emailCount = [emailAddresses count];
307 j < emailCount; j++) { 371 j < emailCount; j++) {
308 NSString* emailAddressLabelRaw = [emailAddresses labelAtIndex:j]; 372 NSString* emailAddressLabelRaw = [emailAddresses labelAtIndex:j];
309 if ([emailAddressLabelRaw isEqualToString:addressLabelRaw]) { 373 if ([emailAddressLabelRaw isEqualToString:addressLabelRaw]) {
310 emailAddress = [emailAddresses valueAtIndex:j]; 374 emailAddress = [emailAddresses valueAtIndex:j];
311 break; 375 break;
312 } 376 }
313 } 377 }
314 profile->SetRawInfo(EMAIL_ADDRESS, base::SysNSStringToUTF16(emailAddress)); 378 profile->SetRawInfo(EMAIL_ADDRESS, base::SysNSStringToUTF16(emailAddress));
379 return [emailAddress length] > 0;
315 } 380 }
316 381
317 // Fills in telephone numbers. Each of these are special cases. 382 // Fills in telephone numbers. Each of these are special cases.
318 // We match two cases: home/tel, work/tel. 383 // We match two cases: home/tel, work/tel.
319 // Note, we traverse in reverse order so that top values in address book 384 // Note, we traverse in reverse order so that top values in address book
320 // take priority. 385 // take priority.
321 void AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers( 386 // Returns whether |me| contains a phone number.
387 bool AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers(
322 ABPerson* me, 388 ABPerson* me,
323 NSString* addressLabelRaw, 389 NSString* addressLabelRaw,
324 AutofillProfile* profile) { 390 AutofillProfile* profile) {
391 bool hasPhoneNumber = false;
325 ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty]; 392 ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty];
326 for (NSUInteger k = 0, phoneCount = [phoneNumbers count]; 393 for (NSUInteger k = 0, phoneCount = [phoneNumbers count];
327 k < phoneCount; k++) { 394 k < phoneCount; k++) {
328 NSUInteger reverseK = phoneCount - k - 1; 395 NSUInteger reverseK = phoneCount - k - 1;
329 NSString* phoneLabelRaw = [phoneNumbers labelAtIndex:reverseK]; 396 NSString* phoneLabelRaw = [phoneNumbers labelAtIndex:reverseK];
330 if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] && 397 if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] &&
331 [phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) { 398 [phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) {
332 base::string16 homePhone = base::SysNSStringToUTF16( 399 base::string16 homePhone = base::SysNSStringToUTF16(
333 [phoneNumbers valueAtIndex:reverseK]); 400 [phoneNumbers valueAtIndex:reverseK]);
334 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, homePhone); 401 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, homePhone);
402 hasPhoneNumber |= !homePhone.empty();
335 } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] && 403 } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
336 [phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) { 404 [phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) {
337 base::string16 workPhone = base::SysNSStringToUTF16( 405 base::string16 workPhone = base::SysNSStringToUTF16(
338 [phoneNumbers valueAtIndex:reverseK]); 406 [phoneNumbers valueAtIndex:reverseK]);
339 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, workPhone); 407 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, workPhone);
408 hasPhoneNumber |= !workPhone.empty();
340 } else if ([phoneLabelRaw isEqualToString:kABPhoneMobileLabel] || 409 } else if ([phoneLabelRaw isEqualToString:kABPhoneMobileLabel] ||
341 [phoneLabelRaw isEqualToString:kABPhoneMainLabel]) { 410 [phoneLabelRaw isEqualToString:kABPhoneMainLabel]) {
342 base::string16 phone = base::SysNSStringToUTF16( 411 base::string16 phone = base::SysNSStringToUTF16(
343 [phoneNumbers valueAtIndex:reverseK]); 412 [phoneNumbers valueAtIndex:reverseK]);
344 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, phone); 413 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, phone);
414 hasPhoneNumber |= !phone.empty();
345 } 415 }
346 } 416 }
417 return hasPhoneNumber;
347 } 418 }
348 419
349 } // namespace 420 } // namespace
350 421
351 // Populate |auxiliary_profiles_| with the Address Book data. 422 // Populate |auxiliary_profiles_| with the Address Book data.
352 void PersonalDataManager::LoadAuxiliaryProfiles(bool record_metrics) const { 423 void PersonalDataManager::LoadAuxiliaryProfiles(bool record_metrics) const {
353 AuxiliaryProfilesImpl impl(&auxiliary_profiles_); 424 AuxiliaryProfilesImpl impl(&auxiliary_profiles_);
354 impl.GetAddressBookMeCard(app_locale_, pref_service_, record_metrics); 425 impl.GetAddressBookMeCard(app_locale_, pref_service_, record_metrics);
355 } 426 }
356 427
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 480
410 int PersonalDataManager::AccessAddressBookPromptCount() { 481 int PersonalDataManager::AccessAddressBookPromptCount() {
411 return pref_service_->GetInteger(prefs::kAutofillMacAddressBookShowedCount); 482 return pref_service_->GetInteger(prefs::kAutofillMacAddressBookShowedCount);
412 } 483 }
413 484
414 void PersonalDataManager::BinaryChanging() { 485 void PersonalDataManager::BinaryChanging() {
415 g_binary_changed = true; 486 g_binary_changed = true;
416 } 487 }
417 488
418 } // namespace autofill 489 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/autofill_manager.cc ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698