| Index: components/autofill/browser/personal_data_manager_mac.mm
|
| diff --git a/components/autofill/browser/personal_data_manager_mac.mm b/components/autofill/browser/personal_data_manager_mac.mm
|
| deleted file mode 100644
|
| index 08487bd85e14303454931a5a5270c497909a3b3b..0000000000000000000000000000000000000000
|
| --- a/components/autofill/browser/personal_data_manager_mac.mm
|
| +++ /dev/null
|
| @@ -1,272 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "components/autofill/browser/personal_data_manager.h"
|
| -
|
| -#include <math.h>
|
| -
|
| -#import <AddressBook/AddressBook.h>
|
| -
|
| -#include "base/format_macros.h"
|
| -#include "base/guid.h"
|
| -#include "base/logging.h"
|
| -#import "base/mac/scoped_nsexception_enabler.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/memory/scoped_vector.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "components/autofill/browser/autofill_country.h"
|
| -#include "components/autofill/browser/autofill_profile.h"
|
| -#include "components/autofill/browser/phone_number.h"
|
| -#include "grit/component_strings.h"
|
| -#include "ui/base/l10n/l10n_util_mac.h"
|
| -
|
| -namespace autofill {
|
| -namespace {
|
| -
|
| -const char kAddressBookOrigin[] = "OS X Address Book";
|
| -
|
| -// This implementation makes use of the Address Book API. Profiles are
|
| -// generated that correspond to addresses in the "me" card that reside in the
|
| -// user's Address Book. The caller passes a vector of profiles into the
|
| -// the constructer and then initiate the fetch from the Mac Address Book "me"
|
| -// card using the main |GetAddressBookMeCard()| method. This clears any
|
| -// existing addresses and populates new addresses derived from the data found
|
| -// in the "me" card.
|
| -class AuxiliaryProfilesImpl {
|
| - public:
|
| - // Constructor takes a reference to the |profiles| that will be filled in
|
| - // by the subsequent call to |GetAddressBookMeCard()|. |profiles| may not
|
| - // be NULL.
|
| - explicit AuxiliaryProfilesImpl(ScopedVector<AutofillProfile>* profiles)
|
| - : profiles_(*profiles) {
|
| - }
|
| - virtual ~AuxiliaryProfilesImpl() {}
|
| -
|
| - // Import the "me" card from the Mac Address Book and fill in |profiles_|.
|
| - void GetAddressBookMeCard(const std::string& app_locale);
|
| -
|
| - private:
|
| - void GetAddressBookNames(ABPerson* me,
|
| - NSString* addressLabelRaw,
|
| - AutofillProfile* profile);
|
| - void GetAddressBookAddress(const std::string& app_locale,
|
| - NSDictionary* address,
|
| - AutofillProfile* profile);
|
| - void GetAddressBookEmail(ABPerson* me,
|
| - NSString* addressLabelRaw,
|
| - AutofillProfile* profile);
|
| - void GetAddressBookPhoneNumbers(ABPerson* me,
|
| - NSString* addressLabelRaw,
|
| - AutofillProfile* profile);
|
| -
|
| - private:
|
| - // A reference to the profiles this class populates.
|
| - ScopedVector<AutofillProfile>& profiles_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfilesImpl);
|
| -};
|
| -
|
| -// This method uses the |ABAddressBook| system service to fetch the "me" card
|
| -// from the active user's address book. It looks for the user address
|
| -// information and translates it to the internal list of |AutofillProfile| data
|
| -// structures.
|
| -void AuxiliaryProfilesImpl::GetAddressBookMeCard(
|
| - const std::string& app_locale) {
|
| - profiles_.clear();
|
| -
|
| - // +[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
|
| - // returned, or if they would take down the app. In either case, avoid
|
| - // crashing. http://crbug.com/129022
|
| - ABAddressBook* addressBook = base::mac::RunBlockIgnoringExceptions(^{
|
| - return [ABAddressBook sharedAddressBook];
|
| - });
|
| - ABPerson* me = [addressBook me];
|
| - if (!me)
|
| - return;
|
| -
|
| - ABMultiValue* addresses = [me valueForProperty:kABAddressProperty];
|
| -
|
| - // The number of characters at the end of the GUID to reserve for
|
| - // distinguishing addresses within the "me" card. Cap the number of addresses
|
| - // we will fetch to the number that can be distinguished by this fragment of
|
| - // the GUID.
|
| - const size_t kNumAddressGUIDChars = 2;
|
| - const size_t kNumHexDigits = 16;
|
| - const size_t kMaxAddressCount = pow(kNumHexDigits, kNumAddressGUIDChars);
|
| - NSUInteger count = MIN([addresses count], kMaxAddressCount);
|
| - for (NSUInteger i = 0; i < count; i++) {
|
| - NSDictionary* address = [addresses valueAtIndex:i];
|
| - NSString* addressLabelRaw = [addresses labelAtIndex:i];
|
| -
|
| - // Create a new profile where the guid is set to the guid portion of the
|
| - // |kABUIDProperty| taken from from the "me" address. The format of
|
| - // the |kABUIDProperty| is "<guid>:ABPerson", so we're stripping off the
|
| - // raw guid here and using it directly, with one modification: we update the
|
| - // last |kNumAddressGUIDChars| characters in the GUID to reflect the address
|
| - // variant. Note that we capped the number of addresses above, so this is
|
| - // safe.
|
| - const size_t kGUIDLength = 36U;
|
| - const size_t kTrimmedGUIDLength = kGUIDLength - kNumAddressGUIDChars;
|
| - std::string guid = base::SysNSStringToUTF8(
|
| - [me valueForProperty:kABUIDProperty]).substr(0, kTrimmedGUIDLength);
|
| -
|
| - // The format string to print |kNumAddressGUIDChars| hexadecimal characters,
|
| - // left-padded with 0's.
|
| - const std::string kAddressGUIDFormat =
|
| - base::StringPrintf("%%0%" PRIuS "X", kNumAddressGUIDChars);
|
| - guid += base::StringPrintf(kAddressGUIDFormat.c_str(), i);
|
| - DCHECK_EQ(kGUIDLength, guid.size());
|
| -
|
| - scoped_ptr<AutofillProfile> profile(
|
| - new AutofillProfile(guid, kAddressBookOrigin));
|
| - DCHECK(base::IsValidGUID(profile->guid()));
|
| -
|
| - // Fill in name and company information.
|
| - GetAddressBookNames(me, addressLabelRaw, profile.get());
|
| -
|
| - // Fill in address information.
|
| - GetAddressBookAddress(app_locale, address, profile.get());
|
| -
|
| - // Fill in email information.
|
| - GetAddressBookEmail(me, addressLabelRaw, profile.get());
|
| -
|
| - // Fill in phone number information.
|
| - GetAddressBookPhoneNumbers(me, addressLabelRaw, profile.get());
|
| -
|
| - profiles_.push_back(profile.release());
|
| - }
|
| -}
|
| -
|
| -// 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(
|
| - ABPerson* me,
|
| - NSString* addressLabelRaw,
|
| - AutofillProfile* profile) {
|
| - NSString* firstName = [me valueForProperty:kABFirstNameProperty];
|
| - NSString* middleName = [me valueForProperty:kABMiddleNameProperty];
|
| - NSString* lastName = [me valueForProperty:kABLastNameProperty];
|
| - NSString* companyName = [me valueForProperty:kABOrganizationProperty];
|
| -
|
| - 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])
|
| - profile->SetRawInfo(COMPANY_NAME, base::SysNSStringToUTF16(companyName));
|
| -}
|
| -
|
| -// Addresss information from the Address Book may span multiple lines.
|
| -// If it does then we represent the address with two lines in the profile. The
|
| -// 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,
|
| - NSDictionary* address,
|
| - AutofillProfile* profile) {
|
| - if (NSString* addressField = [address objectForKey:kABAddressStreetKey]) {
|
| - // If there are newlines in the address, split into two lines.
|
| - if ([addressField rangeOfCharacterFromSet:
|
| - [NSCharacterSet newlineCharacterSet]].location != NSNotFound) {
|
| - NSArray* chunks = [addressField componentsSeparatedByCharactersInSet:
|
| - [NSCharacterSet newlineCharacterSet]];
|
| - DCHECK([chunks count] > 1);
|
| -
|
| - NSString* separator = l10n_util::GetNSString(
|
| - IDS_AUTOFILL_MAC_ADDRESS_LINE_SEPARATOR);
|
| -
|
| - NSString* addressField1 = [chunks objectAtIndex:0];
|
| - NSString* addressField2 =
|
| - [[chunks subarrayWithRange:NSMakeRange(1, [chunks count] - 1)]
|
| - componentsJoinedByString:separator];
|
| - profile->SetRawInfo(ADDRESS_HOME_LINE1,
|
| - base::SysNSStringToUTF16(addressField1));
|
| - profile->SetRawInfo(ADDRESS_HOME_LINE2,
|
| - base::SysNSStringToUTF16(addressField2));
|
| - } else {
|
| - profile->SetRawInfo(ADDRESS_HOME_LINE1,
|
| - base::SysNSStringToUTF16(addressField));
|
| - }
|
| - }
|
| -
|
| - if (NSString* city = [address objectForKey:kABAddressCityKey])
|
| - profile->SetRawInfo(ADDRESS_HOME_CITY, base::SysNSStringToUTF16(city));
|
| -
|
| - if (NSString* state = [address objectForKey:kABAddressStateKey])
|
| - profile->SetRawInfo(ADDRESS_HOME_STATE, base::SysNSStringToUTF16(state));
|
| -
|
| - if (NSString* zip = [address objectForKey:kABAddressZIPKey])
|
| - profile->SetRawInfo(ADDRESS_HOME_ZIP, base::SysNSStringToUTF16(zip));
|
| -
|
| - if (NSString* country = [address objectForKey:kABAddressCountryKey]) {
|
| - profile->SetInfo(ADDRESS_HOME_COUNTRY,
|
| - base::SysNSStringToUTF16(country),
|
| - app_locale);
|
| - }
|
| -}
|
| -
|
| -// 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(
|
| - ABPerson* me,
|
| - NSString* addressLabelRaw,
|
| - AutofillProfile* profile) {
|
| - ABMultiValue* emailAddresses = [me valueForProperty:kABEmailProperty];
|
| - NSString* emailAddress = nil;
|
| - for (NSUInteger j = 0, emailCount = [emailAddresses count];
|
| - j < emailCount; j++) {
|
| - NSString* emailAddressLabelRaw = [emailAddresses labelAtIndex:j];
|
| - if ([emailAddressLabelRaw isEqualToString:addressLabelRaw]) {
|
| - emailAddress = [emailAddresses valueAtIndex:j];
|
| - break;
|
| - }
|
| - }
|
| - profile->SetRawInfo(EMAIL_ADDRESS, base::SysNSStringToUTF16(emailAddress));
|
| -}
|
| -
|
| -// 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(
|
| - ABPerson* me,
|
| - NSString* addressLabelRaw,
|
| - AutofillProfile* profile) {
|
| - ABMultiValue* phoneNumbers = [me valueForProperty:kABPhoneProperty];
|
| - for (NSUInteger k = 0, phoneCount = [phoneNumbers count];
|
| - k < phoneCount; k++) {
|
| - NSUInteger reverseK = phoneCount - k - 1;
|
| - NSString* phoneLabelRaw = [phoneNumbers labelAtIndex:reverseK];
|
| - if ([addressLabelRaw isEqualToString:kABAddressHomeLabel] &&
|
| - [phoneLabelRaw isEqualToString:kABPhoneHomeLabel]) {
|
| - base::string16 homePhone = base::SysNSStringToUTF16(
|
| - [phoneNumbers valueAtIndex:reverseK]);
|
| - profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, homePhone);
|
| - } else if ([addressLabelRaw isEqualToString:kABAddressWorkLabel] &&
|
| - [phoneLabelRaw isEqualToString:kABPhoneWorkLabel]) {
|
| - base::string16 workPhone = base::SysNSStringToUTF16(
|
| - [phoneNumbers valueAtIndex:reverseK]);
|
| - profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, workPhone);
|
| - } else if ([phoneLabelRaw isEqualToString:kABPhoneMobileLabel] ||
|
| - [phoneLabelRaw isEqualToString:kABPhoneMainLabel]) {
|
| - base::string16 phone = base::SysNSStringToUTF16(
|
| - [phoneNumbers valueAtIndex:reverseK]);
|
| - profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, phone);
|
| - }
|
| - }
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// Populate |auxiliary_profiles_| with the Address Book data.
|
| -void PersonalDataManager::LoadAuxiliaryProfiles() {
|
| - AuxiliaryProfilesImpl impl(&auxiliary_profiles_);
|
| - impl.GetAddressBookMeCard(app_locale_);
|
| -}
|
| -
|
| -} // namespace autofill
|
|
|