Commit 0d91c6b9 authored by Matthias Körber's avatar Matthias Körber Committed by Commit Bot

[Autofill][Slimshady] BridgeUtils merging and tests for structured names

Adds logic to merge the names stored in a local and remote profile.
Adepts the bridge util tests to work with structured names.

Change-Id: Ide42931f3f36809b9f72a666e2941ce1418f040d
Bug: 1099202
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2358672
Commit-Queue: Matthias Körber <koerber@google.com>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798703}
parent 9af7e14d
......@@ -568,7 +568,18 @@ void AutofillProfile::OverwriteDataFrom(const AutofillProfile& profile) {
// values.
std::string language_code_value = language_code();
std::string origin_value = origin();
base::string16 name_full_value = GetRawInfo(NAME_FULL);
// Structured names should not be simply overwritten but it should be
// attempted to merge the names.
bool use_structured_name = base::FeatureList::IsEnabled(
features::kAutofillEnableSupportForMoreStructureInNames);
bool is_structured_name_mergeable = false;
NameInfo name_info = GetNameInfo();
if (use_structured_name) {
is_structured_name_mergeable =
name_info.IsStructuredNameMergeable(profile.GetNameInfo());
name_info.MergeStructuredName(profile.GetNameInfo());
}
*this = profile;
......@@ -576,8 +587,23 @@ void AutofillProfile::OverwriteDataFrom(const AutofillProfile& profile) {
set_origin(origin_value);
if (language_code().empty())
set_language_code(language_code_value);
if (!HasRawInfo(NAME_FULL))
SetRawInfo(NAME_FULL, name_full_value);
// For structured names, use the merged name if possible.
if (is_structured_name_mergeable) {
name_ = name_info;
return;
}
// For structured names, if the full name of |profile| is empty, maintain the
// complete name structure. Note, this should only happen if the complete name
// is empty. For the legacy implementation, set the full name if |profile|
// does not contain a full name.
if (!HasRawInfo(NAME_FULL)) {
if (use_structured_name) {
name_ = name_info;
} else {
SetRawInfo(NAME_FULL, name_info.GetRawInfo(NAME_FULL));
}
}
}
bool AutofillProfile::MergeDataFrom(const AutofillProfile& profile,
......@@ -1209,16 +1235,38 @@ bool AutofillProfile::EqualsSansGuid(const AutofillProfile& profile) const {
}
std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
return os << (profile.record_type() == AutofillProfile::LOCAL_PROFILE
return os
<< (profile.record_type() == AutofillProfile::LOCAL_PROFILE
? profile.guid()
: base::HexEncode(profile.server_id().data(),
profile.server_id().size()))
<< " " << profile.origin() << " "
<< UTF16ToUTF8(profile.GetRawInfo(NAME_FULL)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(NAME_FIRST)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(NAME_MIDDLE)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(NAME_LAST)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(EMAIL_ADDRESS)) << " "
<< "("
<< base::NumberToString(profile.GetVerificationStatusInt(NAME_FULL))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(NAME_FIRST)) << " "
<< "("
<< base::NumberToString(profile.GetVerificationStatusInt(NAME_FIRST))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(NAME_MIDDLE)) << " "
<< "("
<< base::NumberToString(profile.GetVerificationStatusInt(NAME_MIDDLE))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(NAME_LAST)) << " "
<< "("
<< base::NumberToString(profile.GetVerificationStatusInt(NAME_LAST))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(NAME_LAST_FIRST)) << " "
<< "("
<< base::NumberToString(
profile.GetVerificationStatusInt(NAME_LAST_FIRST))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(NAME_LAST_CONJUNCTION))
<< " "
<< "("
<< base::NumberToString(
profile.GetVerificationStatusInt(NAME_LAST_CONJUNCTION))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(NAME_LAST_SECOND)) << " "
<< "("
<< base::NumberToString(
profile.GetVerificationStatusInt(NAME_LAST_SECOND))
<< ") " << UTF16ToUTF8(profile.GetRawInfo(EMAIL_ADDRESS)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(COMPANY_NAME)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE1)) << " "
<< UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE2)) << " "
......
......@@ -48,12 +48,24 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile(
return base::nullopt;
}
updated->OverwriteDataFrom(*remote);
// TODO(jkrcal): if |updated| deviates from |remote|, we should sync it back
// up. The only way |updated| can differ is having some extra fields
// compared to |remote|. Thus, this cannot lead to an infinite loop of
// commits from two clients as each commit decreases the set of empty
// TODO(crbug.com/1117022l): if |updated| deviates from |remote|, we should
// sync it back up. The only way |updated| can differ is having some extra
// fields compared to |remote|. Thus, this cannot lead to an infinite loop
// of commits from two clients as each commit decreases the set of empty
// fields. This invariant depends on the implementation of
// OverwriteDataFrom() and thus should be enforced by a DCHECK.
//
// With structured names the situation changes a bit,
// but maintains its character.
// If the name stored in |remote| is mergeable with the local |name|, the
// merge operation is performed. Otherwise the name structure of |local| is
// maintained iff |remote| contains an empty name.
// A merge operations manipulates the name towards a better total
// verification status of the stored tokens. Consequently, it is not
// possible to get into a merging loop of two competing clients.
// As in the legacy implementation, |OverwriteDataForm()| can change the
// profile in a deterministic way and a direct sync-back would be
// reasonable.
if (!updated->EqualsForSyncPurposes(*local_with_same_storage_key)) {
// We need to write back locally new changes in this entry.
......
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