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

Unified Diff: chrome/browser/autofill/personal_data_manager.cc

Issue 6676031: Autofill database migration to clean up bogus profiles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move to Lingesh's observer mechanism. Created 9 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/autofill/personal_data_manager.cc
diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc
index 287ce9484f4b200d272bfa591b9b67acf57ff668..91f0c8955c0363b4ae4209a5498c0ed2ec8448d1 100644
--- a/chrome/browser/autofill/personal_data_manager.cc
+++ b/chrome/browser/autofill/personal_data_manager.cc
@@ -11,12 +11,15 @@
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill-inl.h"
+#include "chrome/browser/autofill/autofill_country.h"
Ilya Sherman 2011/03/16 23:07:16 nit: No longer needed.
dhollowa 2011/03/17 00:02:42 Done.
#include "chrome/browser/autofill/autofill_field.h"
#include "chrome/browser/autofill/autofill_metrics.h"
#include "chrome/browser/autofill/form_structure.h"
#include "chrome/browser/autofill/phone_number.h"
+#include "chrome/browser/autofill/select_control_handler.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
@@ -82,6 +85,15 @@ bool IsValidEmail(const string16& value) {
return re.match(WebKit::WebString(StringToLowerASCII(value))) != -1;
}
+// Valid for US zip codes only.
+bool IsValidZip(const string16& value) {
+ // Basic US zip code matching.
+ const string16 kZipPattern = ASCIIToUTF16("^\\d{5}(-\\d{4})?$");
+ WebKit::WebRegularExpression re(WebKit::WebString(kZipPattern),
+ WebKit::WebTextCaseInsensitive);
+ return re.match(WebKit::WebString(StringToLowerASCII(value))) != -1;
+}
+
// Returns true if minimum requirements for import of a given |profile| have
// been met. An address submitted via a form must have at least these fields
// filled. No verification of validity of the contents is preformed. This is
@@ -166,6 +178,31 @@ void PersonalDataManager::RemoveObserver(
observers_.RemoveObserver(observer);
}
+// The |PersonalDataManager| is set up as a listener of the sync service in
+// |EmptyMigrationTrash| in the case where sync is not yet ready to receive
+// changes. This method, |OnStateChange| acts as a deferred call to
+// |EmptyMigrationTrash| once the sync service becomes available.
Ilya Sherman 2011/03/16 23:07:16 We already call into EmptyMigrationTrash() at vari
dhollowa 2011/03/17 00:02:42 It does the "empty" sooner in the cycle. I.e. as
+void PersonalDataManager::OnStateChanged() {
+ if (!profile_ || profile_->IsOffTheRecord())
+ return;
+
+ WebDataService* web_data_service =
+ profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
+ if (!web_data_service) {
+ NOTREACHED();
+ return;
+ }
+
+ ProfileSyncService* sync_service = profile_->GetProfileSyncService();
+ if (!sync_service)
+ return;
+
+ if (sync_service->ShouldPushChanges()) {
+ web_data_service->EmptyMigrationTrash(true);
+ sync_service->RemoveObserver(this);
+ }
+}
+
bool PersonalDataManager::ImportFormData(
const std::vector<const FormStructure*>& form_structures,
const CreditCard** imported_credit_card) {
@@ -253,12 +290,15 @@ bool PersonalDataManager::ImportFormData(
}
}
- if (field_type.field_type() == EMAIL_ADDRESS && !IsValidEmail(value))
- continue;
-
- imported_profile->SetInfo(AutofillType(field_type.field_type()),
- value);
+ imported_profile->SetInfo(AutofillType(field_type.field_type()), value);
++importable_fields;
+
+ // Reject profiles with invalid country information.
+ if (field_type.field_type() == ADDRESS_HOME_COUNTRY &&
+ !value.empty() && imported_profile->CountryCode().empty()) {
+ imported_profile.reset();
+ break;
+ }
}
}
}
@@ -270,8 +310,11 @@ bool PersonalDataManager::ImportFormData(
if (importable_credit_card_fields < kMinCreditCardImportSize)
local_imported_credit_card.reset();
- if (imported_profile.get() && !IsMinimumAddress(*imported_profile.get()))
+ // Reject if minimum address and validation requirements are not met.
+ if (imported_profile.get() &&
+ !IsValidLearnableProfile(*imported_profile.get())) {
imported_profile.reset();
+ }
if (local_imported_credit_card.get() &&
!CreditCard::IsCreditCardNumber(local_imported_credit_card->GetFieldText(
@@ -629,6 +672,88 @@ void PersonalDataManager::Init(Profile* profile) {
LoadCreditCards();
}
+// static
+bool PersonalDataManager::IsValidLearnableProfile(
+ const AutofillProfile& profile) {
+ if (!IsMinimumAddress(profile))
+ return false;
+
+ string16 email = profile.GetFieldText(AutofillType(EMAIL_ADDRESS));
+ if (!email.empty() && !IsValidEmail(email))
+ return false;
+
+ // Reject profiles with invalid US state information.
+ string16 state = profile.GetFieldText(AutofillType(ADDRESS_HOME_STATE));
+ if (profile.CountryCode() == "US" &&
+ !state.empty() && !autofill::IsValidState(state)) {
+ return false;
+ }
+
+ // Reject profiles with invalid US zip information.
+ string16 zip = profile.GetFieldText(AutofillType(ADDRESS_HOME_ZIP));
+ if (profile.CountryCode() == "US" && !zip.empty() && !IsValidZip(zip))
+ return false;
+
+ return true;
+}
+
+// static
+bool PersonalDataManager::MergeProfile(
+ const AutofillProfile& profile,
+ const std::vector<AutofillProfile*>& existing_profiles,
+ std::vector<AutofillProfile>* merged_profiles) {
+ DCHECK(merged_profiles);
+ merged_profiles->clear();
+
+ // Set to true if |profile| is merged into |existing_profiles|.
+ bool merged = false;
+
+ // First preference is to add missing values to an existing profile.
+ // Only merge with the first match.
+ for (std::vector<AutofillProfile*>::const_iterator iter =
+ existing_profiles.begin();
+ iter != existing_profiles.end(); ++iter) {
+ if (!merged) {
+ if (profile.IsSubsetOf(**iter)) {
+ // In this case, the existing profile already contains all of the data
+ // in |profile|, so consider the profiles already merged.
+ merged = true;
+ } else if ((*iter)->IntersectionOfTypesHasEqualValues(profile)) {
+ // |profile| contains all of the data in this profile, plus more.
+ merged = true;
+ (*iter)->MergeWith(profile);
+ }
+ }
+ merged_profiles->push_back(**iter);
+ }
+
+ // The second preference, if not merged above, is to alter non-primary values
+ // where the primary values match.
+ // Again, only merge with the first match.
+ if (!merged) {
+ merged_profiles->clear();
+ for (std::vector<AutofillProfile*>::const_iterator iter =
+ existing_profiles.begin();
+ iter != existing_profiles.end(); ++iter) {
+ if (!merged) {
+ if (!profile.PrimaryValue().empty() &&
+ (*iter)->PrimaryValue() == profile.PrimaryValue()) {
+ merged = true;
+ (*iter)->OverwriteWith(profile);
+ }
+ }
+ merged_profiles->push_back(**iter);
+ }
+ }
+
+ // Finally, if the new profile was not merged with an existing profile then
+ // add the new profile to the list.
+ if (!merged)
+ merged_profiles->push_back(profile);
+
+ return merged;
+}
+
void PersonalDataManager::LoadProfiles() {
WebDataService* web_data_service =
profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
@@ -679,6 +804,7 @@ void PersonalDataManager::ReceiveLoadedProfiles(WebDataService::Handle h,
}
LogProfileCount();
+ EmptyMigrationTrash();
}
void PersonalDataManager::ReceiveLoadedCreditCards(
@@ -719,62 +845,6 @@ void PersonalDataManager::SaveImportedProfile(
AddProfile(imported_profile);
}
-bool PersonalDataManager::MergeProfile(
- const AutofillProfile& profile,
- const std::vector<AutofillProfile*>& existing_profiles,
- std::vector<AutofillProfile>* merged_profiles) {
- DCHECK(merged_profiles);
- merged_profiles->clear();
-
- // Set to true if |profile| is merged into |existing_profiles|.
- bool merged = false;
-
- // First preference is to add missing values to an existing profile.
- // Only merge with the first match.
- for (std::vector<AutofillProfile*>::const_iterator iter =
- existing_profiles.begin();
- iter != existing_profiles.end(); ++iter) {
- if (!merged) {
- if (profile.IsSubsetOf(**iter)) {
- // In this case, the existing profile already contains all of the data
- // in |profile|, so consider the profiles already merged.
- merged = true;
- } else if ((*iter)->IntersectionOfTypesHasEqualValues(profile)) {
- // |profile| contains all of the data in this profile, plus more.
- merged = true;
- (*iter)->MergeWith(profile);
- }
- }
- merged_profiles->push_back(**iter);
- }
-
- // The second preference, if not merged above, is to alter non-primary values
- // where the primary values match.
- // Again, only merge with the first match.
- if (!merged) {
- merged_profiles->clear();
- for (std::vector<AutofillProfile*>::const_iterator iter =
- existing_profiles.begin();
- iter != existing_profiles.end(); ++iter) {
- if (!merged) {
- if (!profile.PrimaryValue().empty() &&
- (*iter)->PrimaryValue() == profile.PrimaryValue()) {
- merged = true;
- (*iter)->OverwriteWith(profile);
- }
- }
- merged_profiles->push_back(**iter);
- }
- }
-
- // Finally, if the new profile was not merged with an existing profile then
- // add the new profile to the list.
- if (!merged)
- merged_profiles->push_back(profile);
-
- return merged;
-}
-
void PersonalDataManager::SaveImportedCreditCard(
const CreditCard& imported_credit_card) {
@@ -814,6 +884,32 @@ void PersonalDataManager::SaveImportedCreditCard(
SetCreditCards(&creditcards);
}
+void PersonalDataManager::EmptyMigrationTrash() {
+ if (!profile_ || profile_->IsOffTheRecord())
+ return;
+
+ WebDataService* web_data_service =
+ profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
+ if (!web_data_service) {
+ NOTREACHED();
+ return;
+ }
+
+ ProfileSyncService* sync_service = profile_->GetProfileSyncService();
+ if (!sync_service)
+ return;
+
+ if (!sync_service->HasSyncSetupCompleted()) {
+ web_data_service->EmptyMigrationTrash(false);
+ } else if (sync_service->ShouldPushChanges()) {
+ web_data_service->EmptyMigrationTrash(true);
+ } else {
+ // Install ourself as a listener so we can empty the trash once the
+ // sync service becomes available.
+ if (!sync_service->HasObserver(this))
+ sync_service->AddObserver(this);
+ }
+}
void PersonalDataManager::LogProfileCount() const {
if (!g_has_logged_profile_count) {

Powered by Google App Engine
This is Rietveld 408576698