Index: components/autofill/core/browser/personal_data_manager_mac.mm |
diff --git a/components/autofill/core/browser/personal_data_manager_mac.mm b/components/autofill/core/browser/personal_data_manager_mac.mm |
index 42e517f38d1bbccad25c584f49d20facde02fd65..17c6b93d5d0672e1174404f955bb3e1332bd00ba 100644 |
--- a/components/autofill/core/browser/personal_data_manager_mac.mm |
+++ b/components/autofill/core/browser/personal_data_manager_mac.mm |
@@ -18,6 +18,7 @@ |
#include "base/prefs/pref_service.h" |
#include "base/strings/stringprintf.h" |
#include "base/strings/sys_string_conversions.h" |
+#include "base/time/time.h" |
#include "components/autofill/core/browser/autofill_country.h" |
#include "components/autofill/core/browser/autofill_profile.h" |
#include "components/autofill/core/browser/autofill_type.h" |
@@ -76,9 +77,40 @@ void RecordAccessSkipped(bool skipped) { |
UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBook.AccessSkipped", skipped); |
} |
+// Emits a histogram indicating whether the Address Book contained a me-card. |
+void EmitAddressBookContainedMeCard(bool containedMeCard) { |
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.ContainedMeCard", |
+ containedMeCard); |
+} |
+ |
+// Emits a histogram indicating whether the me-card had a name. |
+void EmitMeCardHadName(bool hadName) { |
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadName", |
+ hadName); |
+} |
+ |
+// Emits a histogram indicating whether the me-card had an address. |
+void EmitMeCardHadAddress(bool hadAddress) { |
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadAddress", |
+ hadAddress); |
+} |
+ |
+// Emits a histogram indicating whether the me-card had an email. |
+void EmitMeCardHadEmail(bool hadEmail) { |
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadEmail", |
+ hadEmail); |
+} |
+ |
+// Emits a histogram indicating whether the me-card had a phone number. |
+void EmitMeCardHadPhoneNumber(bool hadPhoneNumber) { |
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MacAddressBook.MeCard.HadPhoneNumber", |
+ hadPhoneNumber); |
+} |
+ |
ABAddressBook* GetAddressBook(PrefService* pref_service) { |
bool first_access = !HasQueriedMacAddressBook(pref_service); |
+ base::Time start_time = base::Time::Now(); |
// +[ABAddressBook sharedAddressBook] throws an exception internally in |
// circumstances that aren't clear. The exceptions are only observed in crash |
// reports, so it is unknown whether they would be caught by AppKit and nil |
@@ -88,6 +120,13 @@ ABAddressBook* GetAddressBook(PrefService* pref_service) { |
^{ return [ABAddressBook sharedAddressBook]; }); |
UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailable", addressBook != nil); |
+ if (!g_accessed_address_book) { |
+ // The amount of time that the access takes gives a good indication as to |
+ // whether the user was shown a prompt. |
+ UMA_HISTOGRAM_TIMES("Autofill.MacAddressBook.AccessTime", |
+ base::Time::Now() - start_time); |
+ } |
+ |
if (first_access) { |
UMA_HISTOGRAM_BOOLEAN("Autofill.AddressBookAvailableOnFirstAttempt", |
addressBook != nil); |
@@ -121,16 +160,16 @@ class AuxiliaryProfilesImpl { |
bool record_metrics); |
private: |
- void GetAddressBookNames(ABPerson* me, |
+ bool GetAddressBookNames(ABPerson* me, |
NSString* addressLabelRaw, |
AutofillProfile* profile); |
- void GetAddressBookAddress(const std::string& app_locale, |
+ bool GetAddressBookAddress(const std::string& app_locale, |
NSDictionary* address, |
AutofillProfile* profile); |
- void GetAddressBookEmail(ABPerson* me, |
+ bool GetAddressBookEmail(ABPerson* me, |
NSString* addressLabelRaw, |
AutofillProfile* profile); |
- void GetAddressBookPhoneNumbers(ABPerson* me, |
+ bool GetAddressBookPhoneNumbers(ABPerson* me, |
NSString* addressLabelRaw, |
AutofillProfile* profile); |
@@ -169,9 +208,12 @@ void AuxiliaryProfilesImpl::GetAddressBookMeCard(const std::string& app_locale, |
ABAddressBook* addressBook = GetAddressBook(pref_service); |
ABPerson* me = [addressBook me]; |
- if (!me) |
+ if (!me) { |
+ EmitAddressBookContainedMeCard(false); |
return; |
+ } |
+ EmitAddressBookContainedMeCard(true); |
ABMultiValue* addresses = [me valueForProperty:kABAddressProperty]; |
// The number of characters at the end of the GUID to reserve for |
@@ -182,6 +224,11 @@ void AuxiliaryProfilesImpl::GetAddressBookMeCard(const std::string& app_locale, |
const size_t kNumHexDigits = 16; |
const size_t kMaxAddressCount = pow(kNumHexDigits, kNumAddressGUIDChars); |
NSUInteger count = MIN([addresses count], kMaxAddressCount); |
+ |
+ bool hasName = false; |
+ bool hasEmail = false; |
+ bool hasAddress = false; |
+ bool hasPhoneNumber = false; |
for (NSUInteger i = 0; i < count; i++) { |
NSDictionary* address = [addresses valueAtIndex:i]; |
NSString* addressLabelRaw = [addresses labelAtIndex:i]; |
@@ -211,25 +258,32 @@ void AuxiliaryProfilesImpl::GetAddressBookMeCard(const std::string& app_locale, |
DCHECK(base::IsValidGUID(profile->guid())); |
// Fill in name and company information. |
- GetAddressBookNames(me, addressLabelRaw, profile.get()); |
+ hasName |= GetAddressBookNames(me, addressLabelRaw, profile.get()); |
// Fill in address information. |
- GetAddressBookAddress(app_locale, address, profile.get()); |
+ hasEmail |= GetAddressBookAddress(app_locale, address, profile.get()); |
// Fill in email information. |
- GetAddressBookEmail(me, addressLabelRaw, profile.get()); |
+ hasAddress |= GetAddressBookEmail(me, addressLabelRaw, profile.get()); |
// Fill in phone number information. |
- GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get()); |
+ hasPhoneNumber |= |
+ GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get()); |
profiles_.push_back(profile.release()); |
} |
+ |
+ EmitMeCardHadName(hasName); |
+ EmitMeCardHadEmail(hasEmail); |
+ EmitMeCardHadAddress(hasAddress); |
+ EmitMeCardHadPhoneNumber(hasPhoneNumber); |
} |
// Name and company information is stored once in the Address Book against |
// multiple addresses. We replicate that information for each profile. |
// We only propagate the company name to work profiles. |
-void AuxiliaryProfilesImpl::GetAddressBookNames( |
+// Returns whether |me| contains any name information. |
+bool AuxiliaryProfilesImpl::GetAddressBookNames( |
ABPerson* me, |
NSString* addressLabelRaw, |
AutofillProfile* profile) { |
@@ -241,8 +295,14 @@ void AuxiliaryProfilesImpl::GetAddressBookNames( |
profile->SetRawInfo(NAME_FIRST, base::SysNSStringToUTF16(firstName)); |
profile->SetRawInfo(NAME_MIDDLE, base::SysNSStringToUTF16(middleName)); |
profile->SetRawInfo(NAME_LAST, base::SysNSStringToUTF16(lastName)); |
- if ([addressLabelRaw isEqualToString:kABAddressWorkLabel]) |
+ bool hasValidCompanyName = false; |
+ if ([addressLabelRaw isEqualToString:kABAddressWorkLabel]) { |
profile->SetRawInfo(COMPANY_NAME, base::SysNSStringToUTF16(companyName)); |
+ 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.
|
+ } |
+ |
+ return [firstName length] > 0 || [middleName length] > 0 || |
+ [lastName length] > 0 || hasValidCompanyName; |
} |
// Addresss information from the Address Book may span multiple lines. |
@@ -250,10 +310,14 @@ void AuxiliaryProfilesImpl::GetAddressBookNames( |
// second line we join with commas. |
// For example: "c/o John Doe\n1122 Other Avenue\nApt #7" translates to |
// line 1: "c/o John Doe", line 2: "1122 Other Avenue, Apt #7". |
-void AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale, |
+// Returns whether |address| contains any address information. |
+bool AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale, |
NSDictionary* address, |
AutofillProfile* profile) { |
+ bool hasAnyAddressInformation = false; |
if (NSString* addressField = [address objectForKey:kABAddressStreetKey]) { |
+ hasAnyAddressInformation |= [addressField length] > 0; |
+ |
// If there are newlines in the address, split into two lines. |
if ([addressField rangeOfCharacterFromSet: |
[NSCharacterSet newlineCharacterSet]].location != NSNotFound) { |
@@ -278,26 +342,36 @@ void AuxiliaryProfilesImpl::GetAddressBookAddress(const std::string& app_locale, |
} |
} |
- if (NSString* city = [address objectForKey:kABAddressCityKey]) |
+ if (NSString* city = [address objectForKey:kABAddressCityKey]) { |
+ hasAnyAddressInformation |= [city length] > 0; |
profile->SetRawInfo(ADDRESS_HOME_CITY, base::SysNSStringToUTF16(city)); |
+ } |
- if (NSString* state = [address objectForKey:kABAddressStateKey]) |
+ if (NSString* state = [address objectForKey:kABAddressStateKey]) { |
+ hasAnyAddressInformation |= [state length] > 0; |
profile->SetRawInfo(ADDRESS_HOME_STATE, base::SysNSStringToUTF16(state)); |
+ } |
- if (NSString* zip = [address objectForKey:kABAddressZIPKey]) |
+ if (NSString* zip = [address objectForKey:kABAddressZIPKey]) { |
+ hasAnyAddressInformation |= [zip length] > 0; |
profile->SetRawInfo(ADDRESS_HOME_ZIP, base::SysNSStringToUTF16(zip)); |
+ } |
if (NSString* country = [address objectForKey:kABAddressCountryKey]) { |
+ hasAnyAddressInformation |= [country length] > 0; |
profile->SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), |
base::SysNSStringToUTF16(country), |
app_locale); |
} |
+ |
+ 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.
|
} |
// Fills in email address matching current address label. Note that there may |
// be multiple matching email addresses for a given label. We take the |
// first we find (topmost) as preferred. |
-void AuxiliaryProfilesImpl::GetAddressBookEmail( |
+// Returns whether |me| contains an email. |
+bool AuxiliaryProfilesImpl::GetAddressBookEmail( |
ABPerson* me, |
NSString* addressLabelRaw, |
AutofillProfile* profile) { |
@@ -312,16 +386,19 @@ void AuxiliaryProfilesImpl::GetAddressBookEmail( |
} |
} |
profile->SetRawInfo(EMAIL_ADDRESS, base::SysNSStringToUTF16(emailAddress)); |
+ return [emailAddress length] > 0; |
} |
// Fills in telephone numbers. Each of these are special cases. |
// We match two cases: home/tel, work/tel. |
// Note, we traverse in reverse order so that top values in address book |
// take priority. |
-void AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers( |
+// Returns whether |me| contains a phone number. |
+bool AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers( |
ABPerson* me, |
NSString* addressLabelRaw, |
AutofillProfile* profile) { |
+ bool hasPhoneNumber = false; |
ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty]; |
for (NSUInteger k = 0, phoneCount = [phoneNumbers count]; |
k < phoneCount; k++) { |
@@ -332,18 +409,22 @@ void AuxiliaryProfilesImpl::GetAddressBookPhoneNumbers( |
base::string16 homePhone = base::SysNSStringToUTF16( |
[phoneNumbers valueAtIndex:reverseK]); |
profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, homePhone); |
+ hasPhoneNumber |= !homePhone.empty(); |
} else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] && |
[phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) { |
base::string16 workPhone = base::SysNSStringToUTF16( |
[phoneNumbers valueAtIndex:reverseK]); |
profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, workPhone); |
+ hasPhoneNumber |= !workPhone.empty(); |
} else if ([phoneLabelRaw isEqualToString:kABPhoneMobileLabel] || |
[phoneLabelRaw isEqualToString:kABPhoneMainLabel]) { |
base::string16 phone = base::SysNSStringToUTF16( |
[phoneNumbers valueAtIndex:reverseK]); |
profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, phone); |
+ hasPhoneNumber |= !phone.empty(); |
} |
} |
+ return hasPhoneNumber; |
} |
} // namespace |