Commit aa87453f authored by sebsg's avatar sebsg Committed by Commit Bot

[Autofill] Sync the new validity state bitfield.

Bug: 748223
Change-Id: I93fd4f4e326fe5b272ae4b8816a3c744621b3949
Reviewed-on: https://chromium-review.googlesource.com/675768
Commit-Queue: Sebastien Seguin-Gagnon <sebsg@chromium.org>
Reviewed-by: default avatarRoger McFarlane <rogerm@chromium.org>
Reviewed-by: default avatarNicolas Zea <zea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505896}
parent 7b3e51dd
...@@ -192,19 +192,24 @@ void GetFieldsForDistinguishingProfiles( ...@@ -192,19 +192,24 @@ void GetFieldsForDistinguishingProfiles(
} }
// Constants for the validity bitfield. // Constants for the validity bitfield.
static const size_t validity_bits_per_type = 2; static const size_t kValidityBitsPerType = 2;
static const size_t number_supported_types_for_validation = 7;
// The order is important to ensure a consistent bitfield value. New values // The order is important to ensure a consistent bitfield value. New values
// should be added at the end NOT at the start or middle. // should be added at the end NOT at the start or middle.
static const ServerFieldType static const ServerFieldType kSupportedTypesForValidation[] = {
supported_types_for_validation[number_supported_types_for_validation] = { ADDRESS_HOME_COUNTRY,
ADDRESS_HOME_COUNTRY, ADDRESS_HOME_STATE,
ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP,
ADDRESS_HOME_ZIP, ADDRESS_HOME_CITY,
ADDRESS_HOME_CITY, ADDRESS_HOME_DEPENDENT_LOCALITY,
ADDRESS_HOME_DEPENDENT_LOCALITY, EMAIL_ADDRESS,
EMAIL_ADDRESS, PHONE_HOME_WHOLE_NUMBER};
PHONE_HOME_WHOLE_NUMBER};
static const size_t kNumSupportedTypesForValidation =
sizeof(kSupportedTypesForValidation) /
sizeof(kSupportedTypesForValidation[0]);
static_assert(kNumSupportedTypesForValidation * kValidityBitsPerType <= 64,
"Not enough bits to encode profile validity information!");
} // namespace } // namespace
...@@ -263,6 +268,7 @@ AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) { ...@@ -263,6 +268,7 @@ AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {
server_id_ = profile.server_id(); server_id_ = profile.server_id();
has_converted_ = profile.has_converted(); has_converted_ = profile.has_converted();
SetValidityFromBitfieldValue(profile.GetValidityBitfieldValue());
return *this; return *this;
} }
...@@ -363,6 +369,7 @@ int AutofillProfile::Compare(const AutofillProfile& profile) const { ...@@ -363,6 +369,7 @@ int AutofillProfile::Compare(const AutofillProfile& profile) const {
bool AutofillProfile::EqualsSansOrigin(const AutofillProfile& profile) const { bool AutofillProfile::EqualsSansOrigin(const AutofillProfile& profile) const {
return guid() == profile.guid() && return guid() == profile.guid() &&
language_code() == profile.language_code() && language_code() == profile.language_code() &&
GetValidityBitfieldValue() == profile.GetValidityBitfieldValue() &&
Compare(profile) == 0; Compare(profile) == 0;
} }
...@@ -717,42 +724,38 @@ void AutofillProfile::SetValidityState(ServerFieldType type, ...@@ -717,42 +724,38 @@ void AutofillProfile::SetValidityState(ServerFieldType type,
if (!IsValidationSupportedForType(type)) if (!IsValidationSupportedForType(type))
return; return;
std::map<ServerFieldType, ValidityState>::iterator it = validity_states_[type] = validity;
validity_states_.find(type);
if (it != validity_states_.end()) {
it->second = validity;
} else {
validity_states_.insert(std::make_pair(type, validity));
}
} }
bool AutofillProfile::IsValidationSupportedForType(ServerFieldType type) const { bool AutofillProfile::IsValidationSupportedForType(ServerFieldType type) const {
return std::find(supported_types_for_validation, for (auto supported_type : kSupportedTypesForValidation) {
supported_types_for_validation + if (type == supported_type)
number_supported_types_for_validation, return true;
type) != }
supported_types_for_validation + number_supported_types_for_validation; return false;
} }
int AutofillProfile::GetValidityBitfieldValue() const { int AutofillProfile::GetValidityBitfieldValue() const {
int validity_value = 0; int validity_value = 0;
size_t field_type_shift = 0; size_t field_type_shift = 0;
for (ServerFieldType supported_type : supported_types_for_validation) { for (ServerFieldType supported_type : kSupportedTypesForValidation) {
DCHECK(GetValidityState(supported_type) != UNSUPPORTED); DCHECK(GetValidityState(supported_type) != UNSUPPORTED);
validity_value |= GetValidityState(supported_type) << field_type_shift; validity_value |= GetValidityState(supported_type) << field_type_shift;
field_type_shift += validity_bits_per_type; field_type_shift += kValidityBitsPerType;
} }
// Check the the shift is still in range.
DCHECK_LE(field_type_shift, 64U);
return validity_value; return validity_value;
} }
void AutofillProfile::SetValidityFromBitfieldValue(int bitfield_value) { void AutofillProfile::SetValidityFromBitfieldValue(int bitfield_value) {
// Compute the bitmask based on the number a bits per type. For example, this // Compute the bitmask based on the number a bits per type. For example, this
// could be the two least significant bits (0b11). // could be the two least significant bits (0b11).
const int kBitmask = (1 << validity_bits_per_type) - 1; const int kBitmask = (1 << kValidityBitsPerType) - 1;
for (ServerFieldType supported_type : supported_types_for_validation) { for (ServerFieldType supported_type : kSupportedTypesForValidation) {
// Apply the bitmask to the bitfield value to get the validity value of the // Apply the bitmask to the bitfield value to get the validity value of the
// current |supported_type|. // current |supported_type|.
int validity_value = bitfield_value & kBitmask; int validity_value = bitfield_value & kBitmask;
...@@ -765,7 +768,7 @@ void AutofillProfile::SetValidityFromBitfieldValue(int bitfield_value) { ...@@ -765,7 +768,7 @@ void AutofillProfile::SetValidityFromBitfieldValue(int bitfield_value) {
static_cast<ValidityState>(validity_value)); static_cast<ValidityState>(validity_value));
// Shift the bitfield value to access the validity of the next field type. // Shift the bitfield value to access the validity of the next field type.
bitfield_value = bitfield_value >> validity_bits_per_type; bitfield_value = bitfield_value >> kValidityBitsPerType;
} }
} }
...@@ -928,6 +931,7 @@ FormGroup* AutofillProfile::MutableFormGroupForType(const AutofillType& type) { ...@@ -928,6 +931,7 @@ FormGroup* AutofillProfile::MutableFormGroupForType(const AutofillType& type) {
bool AutofillProfile::EqualsSansGuid(const AutofillProfile& profile) const { bool AutofillProfile::EqualsSansGuid(const AutofillProfile& profile) const {
return origin() == profile.origin() && return origin() == profile.origin() &&
language_code() == profile.language_code() && language_code() == profile.language_code() &&
GetValidityBitfieldValue() == profile.GetValidityBitfieldValue() &&
Compare(profile) == 0; Compare(profile) == 0;
} }
...@@ -948,7 +952,8 @@ std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) { ...@@ -948,7 +952,8 @@ std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " " << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " " << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " "
<< profile.language_code() << " " << profile.language_code() << " "
<< UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)) << " "
<< profile.GetValidityBitfieldValue();
} }
} // namespace autofill } // namespace autofill
...@@ -99,7 +99,7 @@ class AutofillProfile : public AutofillDataModel { ...@@ -99,7 +99,7 @@ class AutofillProfile : public AutofillDataModel {
bool EqualsSansOrigin(const AutofillProfile& profile) const; bool EqualsSansOrigin(const AutofillProfile& profile) const;
// Same as operator==, but ignores differences in guid and cares about // Same as operator==, but ignores differences in guid and cares about
// differences in usage stats. // differences in usage stats and validity state.
bool EqualsForSyncPurposes(const AutofillProfile& profile) const; bool EqualsForSyncPurposes(const AutofillProfile& profile) const;
// Equality operators compare GUIDs, origins, language code, and the contents // Equality operators compare GUIDs, origins, language code, and the contents
......
...@@ -407,6 +407,14 @@ bool AutofillProfileSyncableService::OverwriteProfileWithServerData( ...@@ -407,6 +407,14 @@ bool AutofillProfileSyncableService::OverwriteProfileWithServerData(
diff = true; diff = true;
} }
// Update the validity state bitfield.
if (specifics.has_validity_state_bitfield() &&
specifics.validity_state_bitfield() !=
profile->GetValidityBitfieldValue()) {
profile->SetValidityFromBitfieldValue(specifics.validity_state_bitfield());
diff = true;
}
if (static_cast<size_t>(specifics.use_count()) != profile->use_count()) { if (static_cast<size_t>(specifics.use_count()) != profile->use_count()) {
profile->set_use_count(specifics.use_count()); profile->set_use_count(specifics.use_count());
diff = true; diff = true;
...@@ -471,6 +479,7 @@ void AutofillProfileSyncableService::WriteAutofillProfile( ...@@ -471,6 +479,7 @@ void AutofillProfileSyncableService::WriteAutofillProfile(
LimitData( LimitData(
UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY)))); UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
specifics->set_address_home_language_code(LimitData(profile.language_code())); specifics->set_address_home_language_code(LimitData(profile.language_code()));
specifics->set_validity_state_bitfield(profile.GetValidityBitfieldValue());
// TODO(estade): this should be set_email_address. // TODO(estade): this should be set_email_address.
specifics->add_email_address( specifics->add_email_address(
......
...@@ -1087,14 +1087,15 @@ bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) { ...@@ -1087,14 +1087,15 @@ bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) {
"UPDATE autofill_profiles " "UPDATE autofill_profiles "
"SET guid=?, company_name=?, street_address=?, dependent_locality=?, " "SET guid=?, company_name=?, street_address=?, dependent_locality=?, "
" city=?, state=?, zipcode=?, sorting_code=?, country_code=?, " " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, "
" use_count=?, use_date=?, date_modified=?, origin=?, language_code=? " " use_count=?, use_date=?, date_modified=?, origin=?, "
" language_code=?, validity_bitfield=? "
"WHERE guid=?")); "WHERE guid=?"));
BindAutofillProfileToStatement(profile, BindAutofillProfileToStatement(profile,
update_modification_date update_modification_date
? AutofillClock::Now() ? AutofillClock::Now()
: old_profile->modification_date(), : old_profile->modification_date(),
&s); &s);
s.BindString(14, profile.guid()); s.BindString(15, profile.guid());
bool result = s.Run(); bool result = s.Run();
DCHECK_GT(db_->GetLastChangeCount(), 0); DCHECK_GT(db_->GetLastChangeCount(), 0);
......
...@@ -1635,6 +1635,19 @@ TEST_F(AutofillTableTest, AutofillProfileValidityBitfield) { ...@@ -1635,6 +1635,19 @@ TEST_F(AutofillTableTest, AutofillProfileValidityBitfield) {
table_->GetAutofillProfile(profile.guid()); table_->GetAutofillProfile(profile.guid());
ASSERT_TRUE(db_profile); ASSERT_TRUE(db_profile);
EXPECT_EQ(kValidityBitfieldValue, db_profile->GetValidityBitfieldValue()); EXPECT_EQ(kValidityBitfieldValue, db_profile->GetValidityBitfieldValue());
// Modify the validity of the profile.
const int kOtherValidityBitfieldValue = 1999;
profile.SetValidityFromBitfieldValue(kOtherValidityBitfieldValue);
// Update the profile in the table.
EXPECT_TRUE(table_->UpdateAutofillProfile(profile));
// Get the profile from the table and make sure the validity was updated.
db_profile = table_->GetAutofillProfile(profile.guid());
ASSERT_TRUE(db_profile);
EXPECT_EQ(kOtherValidityBitfieldValue,
db_profile->GetValidityBitfieldValue());
} }
TEST_F(AutofillTableTest, SetGetServerCards) { TEST_F(AutofillTableTest, SetGetServerCards) {
......
...@@ -51,6 +51,11 @@ message AutofillProfileSpecifics { ...@@ -51,6 +51,11 @@ message AutofillProfileSpecifics {
// Phone. // Phone.
repeated string phone_home_whole_number = 13; repeated string phone_home_whole_number = 13;
// Validity bitfield.
// Each set of two bits represents the validity state of a specific part of
// the Autofill address. For more info please refer to autofill_profile.h.
optional int64 validity_state_bitfield = 24;
// Deprecated. // Deprecated.
optional string label = 1 [deprecated = true]; optional string label = 1 [deprecated = true];
optional string phone_fax_whole_number = 14 [deprecated = true]; optional string phone_fax_whole_number = 14 [deprecated = true];
......
...@@ -188,6 +188,7 @@ VISIT_PROTO_FIELDS(const sync_pb::AutofillProfileSpecifics& proto) { ...@@ -188,6 +188,7 @@ VISIT_PROTO_FIELDS(const sync_pb::AutofillProfileSpecifics& proto) {
VISIT(address_home_dependent_locality); VISIT(address_home_dependent_locality);
VISIT(address_home_language_code); VISIT(address_home_language_code);
VISIT_REP(phone_home_whole_number); VISIT_REP(phone_home_whole_number);
VISIT(validity_state_bitfield);
} }
VISIT_PROTO_FIELDS(const sync_pb::AutofillSpecifics& proto) { VISIT_PROTO_FIELDS(const sync_pb::AutofillSpecifics& proto) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment