| Index: components/password_manager/core/browser/password_syncable_service.cc
|
| diff --git a/components/password_manager/core/browser/password_syncable_service.cc b/components/password_manager/core/browser/password_syncable_service.cc
|
| index bef3bdc4cc0d971b6d4ce675b2b18fb19b62b2f2..a0d3dc25b0bf6ae2e7f17453f8eb64ea45c101ff 100644
|
| --- a/components/password_manager/core/browser/password_syncable_service.cc
|
| +++ b/components/password_manager/core/browser/password_syncable_service.cc
|
| @@ -16,99 +16,96 @@
|
|
|
| namespace password_manager {
|
|
|
| -namespace {
|
| -
|
| -// Describes the result of merging sync and local passwords.
|
| -enum MergeResult {
|
| - IDENTICAL,
|
| - SYNC,
|
| - LOCAL,
|
| -};
|
| -
|
| -// Merges the local and sync passwords and outputs the entry into
|
| -// |new_password_form|. Returns MergeResult value describing the content of
|
| -// |new_password_form|.
|
| -MergeResult MergeLocalAndSyncPasswords(
|
| - const sync_pb::PasswordSpecificsData& password_specifics,
|
| - const autofill::PasswordForm& password_form,
|
| - autofill::PasswordForm* new_password_form) {
|
| - DCHECK(new_password_form);
|
| - if (password_form.scheme == password_specifics.scheme() &&
|
| - password_form.signon_realm == password_specifics.signon_realm() &&
|
| - password_form.origin.spec() == password_specifics.origin() &&
|
| - password_form.action.spec() == password_specifics.action() &&
|
| - base::UTF16ToUTF8(password_form.username_element) ==
|
| - password_specifics.username_element() &&
|
| - base::UTF16ToUTF8(password_form.password_element) ==
|
| - password_specifics.password_element() &&
|
| - base::UTF16ToUTF8(password_form.username_value) ==
|
| - password_specifics.username_value() &&
|
| - base::UTF16ToUTF8(password_form.password_value) ==
|
| - password_specifics.password_value() &&
|
| - password_form.ssl_valid == password_specifics.ssl_valid() &&
|
| - password_form.preferred == password_specifics.preferred() &&
|
| - password_form.date_created.ToInternalValue() ==
|
| - password_specifics.date_created() &&
|
| - password_form.blacklisted_by_user == password_specifics.blacklisted() &&
|
| - password_form.type == password_specifics.type() &&
|
| - password_form.times_used == password_specifics.times_used()) {
|
| - return IDENTICAL;
|
| - }
|
| +// Converts the |password| into a SyncData object.
|
| +syncer::SyncData SyncDataFromPassword(const autofill::PasswordForm& password);
|
|
|
| - // If the passwords differ, take the one that was created more recently.
|
| - if (base::Time::FromInternalValue(password_specifics.date_created()) <
|
| - password_form.date_created) {
|
| - *new_password_form = password_form;
|
| - return LOCAL;
|
| - }
|
| +// Extracts the |PasswordForm| data from sync's protobuf format.
|
| +autofill::PasswordForm PasswordFromSpecifics(
|
| + const sync_pb::PasswordSpecificsData& password);
|
|
|
| - PasswordFromSpecifics(password_specifics, new_password_form);
|
| - return SYNC;
|
| -}
|
| +// Returns the unique tag that will serve as the sync identifier for the
|
| +// |password| entry.
|
| +std::string MakePasswordSyncTag(const sync_pb::PasswordSpecificsData& password);
|
| +std::string MakePasswordSyncTag(const autofill::PasswordForm& password);
|
|
|
| -std::string MakePasswordSyncTag(const std::string& origin_url,
|
| - const std::string& username_element,
|
| - const std::string& username_value,
|
| - const std::string& password_element,
|
| - const std::string& signon_realm) {
|
| - return net::EscapePath(origin_url) + "|" +
|
| - net::EscapePath(username_element) + "|" +
|
| - net::EscapePath(username_value) + "|" +
|
| - net::EscapePath(password_element) + "|" +
|
| - net::EscapePath(signon_realm);
|
| -}
|
| +namespace {
|
|
|
| -std::string MakePasswordSyncTag(const autofill::PasswordForm& password) {
|
| - return MakePasswordSyncTag(password.origin.spec(),
|
| - base::UTF16ToUTF8(password.username_element),
|
| - base::UTF16ToUTF8(password.username_value),
|
| - base::UTF16ToUTF8(password.password_element),
|
| - password.signon_realm);
|
| +// Returns true iff |password_specifics| and |password_specifics| are equal
|
| +// memberwise.
|
| +bool AreLocalAndSyncPasswordsEqual(
|
| + const sync_pb::PasswordSpecificsData& password_specifics,
|
| + const autofill::PasswordForm& password_form) {
|
| + return (password_form.scheme == password_specifics.scheme() &&
|
| + password_form.signon_realm == password_specifics.signon_realm() &&
|
| + password_form.origin.spec() == password_specifics.origin() &&
|
| + password_form.action.spec() == password_specifics.action() &&
|
| + base::UTF16ToUTF8(password_form.username_element) ==
|
| + password_specifics.username_element() &&
|
| + base::UTF16ToUTF8(password_form.password_element) ==
|
| + password_specifics.password_element() &&
|
| + base::UTF16ToUTF8(password_form.username_value) ==
|
| + password_specifics.username_value() &&
|
| + base::UTF16ToUTF8(password_form.password_value) ==
|
| + password_specifics.password_value() &&
|
| + password_form.ssl_valid == password_specifics.ssl_valid() &&
|
| + password_form.preferred == password_specifics.preferred() &&
|
| + password_form.date_created.ToInternalValue() ==
|
| + password_specifics.date_created() &&
|
| + password_form.blacklisted_by_user ==
|
| + password_specifics.blacklisted() &&
|
| + password_form.type == password_specifics.type() &&
|
| + password_form.times_used == password_specifics.times_used());
|
| }
|
|
|
| syncer::SyncChange::SyncChangeType GetSyncChangeType(
|
| PasswordStoreChange::Type type) {
|
| switch (type) {
|
| - case PasswordStoreChange::ADD:
|
| - return syncer::SyncChange::ACTION_ADD;
|
| - case PasswordStoreChange::UPDATE:
|
| - return syncer::SyncChange::ACTION_UPDATE;
|
| - case PasswordStoreChange::REMOVE:
|
| - return syncer::SyncChange::ACTION_DELETE;
|
| + case PasswordStoreChange::ADD: return syncer::SyncChange::ACTION_ADD;
|
| + case PasswordStoreChange::UPDATE: return syncer::SyncChange::ACTION_UPDATE;
|
| + case PasswordStoreChange::REMOVE: return syncer::SyncChange::ACTION_DELETE;
|
| }
|
| NOTREACHED();
|
| return syncer::SyncChange::ACTION_INVALID;
|
| }
|
|
|
| -void AppendChanges(const PasswordStoreChangeList& new_changes,
|
| - PasswordStoreChangeList* all_changes) {
|
| - all_changes->insert(all_changes->end(),
|
| - new_changes.begin(),
|
| - new_changes.end());
|
| +// Creates a PasswordForm from |specifics| and |sync_time|, appends it to
|
| +// |entries|.
|
| +void AppendPasswordFromSpecifics(
|
| + const sync_pb::PasswordSpecificsData& specifics,
|
| + base::Time sync_time,
|
| + ScopedVector<autofill::PasswordForm>* entries) {
|
| + entries->push_back(
|
| + new autofill::PasswordForm(PasswordFromSpecifics(specifics)));
|
| + entries->back()->date_synced = sync_time;
|
| }
|
|
|
| } // namespace
|
|
|
| +struct PasswordSyncableService::SyncEntries {
|
| + ScopedVector<autofill::PasswordForm>* EntriesForChangeType(
|
| + syncer::SyncChange::SyncChangeType type) {
|
| + switch (type) {
|
| + case syncer::SyncChange::ACTION_ADD: return &new_entries;
|
| + case syncer::SyncChange::ACTION_UPDATE: return &updated_entries;
|
| + case syncer::SyncChange::ACTION_DELETE: return &deleted_entries;
|
| + case syncer::SyncChange::ACTION_INVALID: return NULL;
|
| + }
|
| + NOTREACHED();
|
| + return NULL;
|
| + }
|
| +
|
| + // List that contains the entries that are known only to sync.
|
| + ScopedVector<autofill::PasswordForm> new_entries;
|
| +
|
| + // List that contains the entries that are known to both sync and the local
|
| + // database but have updates in sync. They need to be updated in the local
|
| + // database.
|
| + ScopedVector<autofill::PasswordForm> updated_entries;
|
| +
|
| + // The list of entries to be deleted from the local database.
|
| + ScopedVector<autofill::PasswordForm> deleted_entries;
|
| +};
|
| +
|
| PasswordSyncableService::PasswordSyncableService(
|
| PasswordStoreSync* password_store)
|
| : password_store_(password_store),
|
| @@ -151,13 +148,7 @@ syncer::SyncMergeResult PasswordSyncableService::MergeDataAndStartSyncing(
|
|
|
| merge_result.set_num_items_before_association(new_local_entries.size());
|
|
|
| - // List that contains the entries that are known only to sync.
|
| - ScopedVector<autofill::PasswordForm> new_sync_entries;
|
| -
|
| - // List that contains the entries that are known to both sync and db but
|
| - // have updates in sync. They need to be updated in the passwords db.
|
| - ScopedVector<autofill::PasswordForm> updated_sync_entries;
|
| -
|
| + SyncEntries sync_entries;
|
| // Changes from password db that need to be propagated to sync.
|
| syncer::SyncChangeList updated_db_entries;
|
| for (syncer::SyncDataList::const_iterator sync_iter =
|
| @@ -165,25 +156,22 @@ syncer::SyncMergeResult PasswordSyncableService::MergeDataAndStartSyncing(
|
| sync_iter != initial_sync_data.end(); ++sync_iter) {
|
| CreateOrUpdateEntry(*sync_iter,
|
| &new_local_entries,
|
| - &new_sync_entries,
|
| - &updated_sync_entries,
|
| + &sync_entries,
|
| &updated_db_entries);
|
| }
|
|
|
| - WriteToPasswordStore(new_sync_entries.get(),
|
| - updated_sync_entries.get(),
|
| - PasswordForms());
|
| + WriteToPasswordStore(sync_entries);
|
|
|
| merge_result.set_num_items_after_association(
|
| - merge_result.num_items_before_association() + new_sync_entries.size());
|
| + merge_result.num_items_before_association() +
|
| + sync_entries.new_entries.size());
|
|
|
| - merge_result.set_num_items_added(new_sync_entries.size());
|
| + merge_result.set_num_items_added(sync_entries.new_entries.size());
|
|
|
| - merge_result.set_num_items_modified(updated_sync_entries.size());
|
| + merge_result.set_num_items_modified(sync_entries.updated_entries.size());
|
|
|
| for (PasswordEntryMap::iterator it = new_local_entries.begin();
|
| - it != new_local_entries.end();
|
| - ++it) {
|
| + it != new_local_entries.end(); ++it) {
|
| updated_db_entries.push_back(
|
| syncer::SyncChange(FROM_HERE,
|
| syncer::SyncChange::ACTION_ADD,
|
| @@ -223,45 +211,23 @@ syncer::SyncError PasswordSyncableService::ProcessSyncChanges(
|
| const syncer::SyncChangeList& change_list) {
|
| DCHECK(CalledOnValidThread());
|
| base::AutoReset<bool> processing_changes(&is_processing_sync_changes_, true);
|
| - // The |db_entries_map| and associated vectors are filled only in case of
|
| - // update change.
|
| - ScopedVector<autofill::PasswordForm> new_sync_entries;
|
| - ScopedVector<autofill::PasswordForm> updated_sync_entries;
|
| - ScopedVector<autofill::PasswordForm> deleted_entries;
|
| + SyncEntries sync_entries;
|
| base::Time time_now = base::Time::Now();
|
|
|
| for (syncer::SyncChangeList::const_iterator it = change_list.begin();
|
| - it != change_list.end();
|
| - ++it) {
|
| + it != change_list.end(); ++it) {
|
| const sync_pb::EntitySpecifics& specifics = it->sync_data().GetSpecifics();
|
| - scoped_ptr<autofill::PasswordForm> form(new autofill::PasswordForm);
|
| - PasswordFromSpecifics(specifics.password().client_only_encrypted_data(),
|
| - form.get());
|
| - switch (it->change_type()) {
|
| - case syncer::SyncChange::ACTION_ADD: {
|
| - form->date_synced = time_now;
|
| - new_sync_entries.push_back(form.release());
|
| - break;
|
| - }
|
| - case syncer::SyncChange::ACTION_UPDATE: {
|
| - form->date_synced = time_now;
|
| - updated_sync_entries.push_back(form.release());
|
| - break;
|
| - }
|
| -
|
| - case syncer::SyncChange::ACTION_DELETE: {
|
| - deleted_entries.push_back(form.release());
|
| - break;
|
| - }
|
| - case syncer::SyncChange::ACTION_INVALID:
|
| - return sync_error_factory_->CreateAndUploadError(
|
| - FROM_HERE,
|
| - "Failed to process sync changes for passwords datatype.");
|
| + ScopedVector<autofill::PasswordForm>* entries =
|
| + sync_entries.EntriesForChangeType(it->change_type());
|
| + if (!entries) {
|
| + return sync_error_factory_->CreateAndUploadError(
|
| + FROM_HERE,
|
| + "Failed to process sync changes for passwords datatype.");
|
| }
|
| + AppendPasswordFromSpecifics(
|
| + specifics.password().client_only_encrypted_data(), time_now, entries);
|
| }
|
| - WriteToPasswordStore(new_sync_entries.get(),
|
| - updated_sync_entries.get(),
|
| - deleted_entries.get());
|
| + WriteToPasswordStore(sync_entries);
|
| return syncer::SyncError();
|
| }
|
|
|
| @@ -283,8 +249,7 @@ void PasswordSyncableService::ActOnPasswordStoreChanges(
|
| return;
|
| syncer::SyncChangeList sync_changes;
|
| for (PasswordStoreChangeList::const_iterator it = local_changes.begin();
|
| - it != local_changes.end();
|
| - ++it) {
|
| + it != local_changes.end(); ++it) {
|
| syncer::SyncData data = (it->type() == PasswordStoreChange::REMOVE ?
|
| syncer::SyncData::CreateLocalDelete(MakePasswordSyncTag(it->form()),
|
| syncer::PASSWORDS) :
|
| @@ -318,57 +283,37 @@ bool PasswordSyncableService::ReadFromPasswordStore(
|
| if (!passwords_entry_map)
|
| return true;
|
|
|
| + PasswordEntryMap& entry_map = *passwords_entry_map;
|
| for (PasswordForms::iterator it = password_entries->begin();
|
| it != password_entries->end(); ++it) {
|
| autofill::PasswordForm* password_form = *it;
|
| - passwords_entry_map->insert(
|
| - std::make_pair(MakePasswordSyncTag(*password_form), password_form));
|
| + entry_map[MakePasswordSyncTag(*password_form)] = password_form;
|
| }
|
|
|
| return true;
|
| }
|
|
|
| -void PasswordSyncableService::WriteToPasswordStore(
|
| - const PasswordForms& new_entries,
|
| - const PasswordForms& updated_entries,
|
| - const PasswordForms& deleted_entries) {
|
| +void PasswordSyncableService::WriteToPasswordStore(const SyncEntries& entries) {
|
| PasswordStoreChangeList changes;
|
| - for (std::vector<autofill::PasswordForm*>::const_iterator it =
|
| - new_entries.begin();
|
| - it != new_entries.end();
|
| - ++it) {
|
| - AppendChanges(password_store_->AddLoginImpl(**it), &changes);
|
| - }
|
| -
|
| - for (std::vector<autofill::PasswordForm*>::const_iterator it =
|
| - updated_entries.begin();
|
| - it != updated_entries.end();
|
| - ++it) {
|
| - AppendChanges(password_store_->UpdateLoginImpl(**it), &changes);
|
| - }
|
| -
|
| - for (std::vector<autofill::PasswordForm*>::const_iterator it =
|
| - deleted_entries.begin();
|
| - it != deleted_entries.end();
|
| - ++it) {
|
| - AppendChanges(password_store_->RemoveLoginImpl(**it), &changes);
|
| - }
|
| + WriteEntriesToDatabase(&PasswordStoreSync::AddLoginImpl,
|
| + entries.new_entries.get(),
|
| + &changes);
|
| + WriteEntriesToDatabase(&PasswordStoreSync::UpdateLoginImpl,
|
| + entries.updated_entries.get(),
|
| + &changes);
|
| + WriteEntriesToDatabase(&PasswordStoreSync::RemoveLoginImpl,
|
| + entries.deleted_entries.get(),
|
| + &changes);
|
|
|
| // We have to notify password store observers of the change by hand since
|
| // we use internal password store interfaces to make changes synchronously.
|
| - NotifyPasswordStoreOfLoginChanges(changes);
|
| -}
|
| -
|
| -void PasswordSyncableService::NotifyPasswordStoreOfLoginChanges(
|
| - const PasswordStoreChangeList& changes) {
|
| password_store_->NotifyLoginsChanged(changes);
|
| }
|
|
|
| void PasswordSyncableService::CreateOrUpdateEntry(
|
| const syncer::SyncData& data,
|
| - PasswordEntryMap* umatched_data_from_password_db,
|
| - ScopedVector<autofill::PasswordForm>* new_sync_entries,
|
| - ScopedVector<autofill::PasswordForm>* updated_sync_entries,
|
| + PasswordEntryMap* unmatched_data_from_password_db,
|
| + SyncEntries* sync_entries,
|
| syncer::SyncChangeList* updated_db_entries) {
|
| const sync_pb::EntitySpecifics& specifics = data.GetSpecifics();
|
| const sync_pb::PasswordSpecificsData& password_specifics(
|
| @@ -377,39 +322,48 @@ void PasswordSyncableService::CreateOrUpdateEntry(
|
|
|
| // Check whether the data from sync is already in the password store.
|
| PasswordEntryMap::iterator existing_local_entry_iter =
|
| - umatched_data_from_password_db->find(tag);
|
| + unmatched_data_from_password_db->find(tag);
|
| base::Time time_now = base::Time::Now();
|
| - if (existing_local_entry_iter == umatched_data_from_password_db->end()) {
|
| + if (existing_local_entry_iter == unmatched_data_from_password_db->end()) {
|
| // The sync data is not in the password store, so we need to create it in
|
| // the password store. Add the entry to the new_entries list.
|
| - scoped_ptr<autofill::PasswordForm> new_password(new autofill::PasswordForm);
|
| - new_password->date_synced = time_now;
|
| - PasswordFromSpecifics(password_specifics, new_password.get());
|
| - new_sync_entries->push_back(new_password.release());
|
| + AppendPasswordFromSpecifics(password_specifics, time_now,
|
| + &sync_entries->new_entries);
|
| } else {
|
| // The entry is in password store. If the entries are not identical, then
|
| // the entries need to be merged.
|
| - scoped_ptr<autofill::PasswordForm> new_password(new autofill::PasswordForm);
|
| - switch (MergeLocalAndSyncPasswords(password_specifics,
|
| - *existing_local_entry_iter->second,
|
| - new_password.get())) {
|
| - case IDENTICAL:
|
| - break;
|
| - case SYNC:
|
| - new_password->date_synced = time_now;
|
| - updated_sync_entries->push_back(new_password.release());
|
| - break;
|
| - case LOCAL:
|
| + // If the passwords differ, take the one that was created more recently.
|
| + const autofill::PasswordForm& password_form =
|
| + *existing_local_entry_iter->second;
|
| + if (!AreLocalAndSyncPasswordsEqual(password_specifics, password_form)) {
|
| + if (base::Time::FromInternalValue(password_specifics.date_created()) <
|
| + password_form.date_created) {
|
| updated_db_entries->push_back(
|
| syncer::SyncChange(FROM_HERE,
|
| syncer::SyncChange::ACTION_UPDATE,
|
| - SyncDataFromPassword(*new_password)));
|
| - break;
|
| + SyncDataFromPassword(password_form)));
|
| + } else {
|
| + AppendPasswordFromSpecifics(password_specifics, time_now,
|
| + &sync_entries->updated_entries);
|
| + }
|
| }
|
| // Remove the entry from the entry map to indicate a match has been found.
|
| // Entries that remain in the map at the end of associating all sync entries
|
| // will be treated as additions that need to be propagated to sync.
|
| - umatched_data_from_password_db->erase(existing_local_entry_iter);
|
| + unmatched_data_from_password_db->erase(existing_local_entry_iter);
|
| + }
|
| +}
|
| +
|
| +void PasswordSyncableService::WriteEntriesToDatabase(
|
| + DatabaseOperation operation,
|
| + const PasswordForms& entries,
|
| + PasswordStoreChangeList* all_changes) {
|
| + for (PasswordForms::const_iterator it = entries.begin();
|
| + it != entries.end(); ++it) {
|
| + PasswordStoreChangeList new_changes = (password_store_->*operation)(**it);
|
| + all_changes->insert(all_changes->end(),
|
| + new_changes.begin(),
|
| + new_changes.end());
|
| }
|
| }
|
|
|
| @@ -418,60 +372,67 @@ syncer::SyncData SyncDataFromPassword(
|
| sync_pb::EntitySpecifics password_data;
|
| sync_pb::PasswordSpecificsData* password_specifics =
|
| password_data.mutable_password()->mutable_client_only_encrypted_data();
|
| - password_specifics->set_scheme(password_form.scheme);
|
| - password_specifics->set_signon_realm(password_form.signon_realm);
|
| +#define CopyField(field) password_specifics->set_ ## field(password_form.field)
|
| +#define CopyStringField(field) \
|
| + password_specifics->set_ ## field(base::UTF16ToUTF8(password_form.field))
|
| + CopyField(scheme);
|
| + CopyField(signon_realm);
|
| password_specifics->set_origin(password_form.origin.spec());
|
| password_specifics->set_action(password_form.action.spec());
|
| - password_specifics->set_username_element(
|
| - base::UTF16ToUTF8(password_form.username_element));
|
| - password_specifics->set_password_element(
|
| - base::UTF16ToUTF8(password_form.password_element));
|
| - password_specifics->set_username_value(
|
| - base::UTF16ToUTF8(password_form.username_value));
|
| - password_specifics->set_password_value(
|
| - base::UTF16ToUTF8(password_form.password_value));
|
| - password_specifics->set_ssl_valid(password_form.ssl_valid);
|
| - password_specifics->set_preferred(password_form.preferred);
|
| + CopyStringField(username_element);
|
| + CopyStringField(password_element);
|
| + CopyStringField(username_value);
|
| + CopyStringField(password_value);
|
| + CopyField(ssl_valid);
|
| + CopyField(preferred);
|
| password_specifics->set_date_created(
|
| password_form.date_created.ToInternalValue());
|
| password_specifics->set_blacklisted(password_form.blacklisted_by_user);
|
| - password_specifics->set_type(password_form.type);
|
| - password_specifics->set_times_used(password_form.times_used);
|
| + CopyField(type);
|
| + CopyField(times_used);
|
| +#undef CopyStringField
|
| +#undef CopyField
|
|
|
| std::string tag = MakePasswordSyncTag(*password_specifics);
|
| return syncer::SyncData::CreateLocalData(tag, tag, password_data);
|
| }
|
|
|
| -void PasswordFromSpecifics(const sync_pb::PasswordSpecificsData& password,
|
| - autofill::PasswordForm* new_password) {
|
| - new_password->scheme =
|
| +autofill::PasswordForm PasswordFromSpecifics(
|
| + const sync_pb::PasswordSpecificsData& password) {
|
| + autofill::PasswordForm new_password;
|
| + new_password.scheme =
|
| static_cast<autofill::PasswordForm::Scheme>(password.scheme());
|
| - new_password->signon_realm = password.signon_realm();
|
| - new_password->origin = GURL(password.origin());
|
| - new_password->action = GURL(password.action());
|
| - new_password->username_element =
|
| + new_password.signon_realm = password.signon_realm();
|
| + new_password.origin = GURL(password.origin());
|
| + new_password.action = GURL(password.action());
|
| + new_password.username_element =
|
| base::UTF8ToUTF16(password.username_element());
|
| - new_password->password_element =
|
| + new_password.password_element =
|
| base::UTF8ToUTF16(password.password_element());
|
| - new_password->username_value = base::UTF8ToUTF16(password.username_value());
|
| - new_password->password_value = base::UTF8ToUTF16(password.password_value());
|
| - new_password->ssl_valid = password.ssl_valid();
|
| - new_password->preferred = password.preferred();
|
| - new_password->date_created =
|
| + new_password.username_value = base::UTF8ToUTF16(password.username_value());
|
| + new_password.password_value = base::UTF8ToUTF16(password.password_value());
|
| + new_password.ssl_valid = password.ssl_valid();
|
| + new_password.preferred = password.preferred();
|
| + new_password.date_created =
|
| base::Time::FromInternalValue(password.date_created());
|
| - new_password->blacklisted_by_user = password.blacklisted();
|
| - new_password->type =
|
| + new_password.blacklisted_by_user = password.blacklisted();
|
| + new_password.type =
|
| static_cast<autofill::PasswordForm::Type>(password.type());
|
| - new_password->times_used = password.times_used();
|
| + new_password.times_used = password.times_used();
|
| + return new_password;
|
| }
|
|
|
| std::string MakePasswordSyncTag(
|
| const sync_pb::PasswordSpecificsData& password) {
|
| - return MakePasswordSyncTag(password.origin(),
|
| - password.username_element(),
|
| - password.username_value(),
|
| - password.password_element(),
|
| - password.signon_realm());
|
| + return MakePasswordSyncTag(PasswordFromSpecifics(password));
|
| +}
|
| +
|
| +std::string MakePasswordSyncTag(const autofill::PasswordForm& password) {
|
| + return (net::EscapePath(password.origin.spec()) + "|" +
|
| + net::EscapePath(base::UTF16ToUTF8(password.username_element)) + "|" +
|
| + net::EscapePath(base::UTF16ToUTF8(password.username_value)) + "|" +
|
| + net::EscapePath(base::UTF16ToUTF8(password.password_element)) + "|" +
|
| + net::EscapePath(password.signon_realm));
|
| }
|
|
|
| } // namespace password_manager
|
|
|