Add TrimRemoteSpecificsForCaching
- Adds interface for trimming supported fields from EntitySpecifics.
By default returns empty EntitySpecifics proto.
- Adds password implementation of the function clearing all currently
supported fields.
Bug: 1296159
Change-Id: I416c78f4422762e2cad1030ca78838eb2e5c59dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3507175
Reviewed-by: Mikel Astiz <mastiz@chromium.org>
Commit-Queue: Andrii Natiahlyi <natiahlyi@google.com>
Cr-Commit-Position: refs/heads/main@{#982207}
diff --git a/components/password_manager/core/browser/sync/password_proto_utils.cc b/components/password_manager/core/browser/sync/password_proto_utils.cc
index fbcf7a5f..a9083f3 100644
--- a/components/password_manager/core/browser/sync/password_proto_utils.cc
+++ b/components/password_manager/core/browser/sync/password_proto_utils.cc
@@ -102,12 +102,44 @@
return form_issues;
}
+sync_pb::PasswordSpecificsData TrimPasswordSpecificsDataForCaching(
+ const sync_pb::PasswordSpecificsData& password_specifics_data) {
+ sync_pb::PasswordSpecificsData trimmed_password_data =
+ sync_pb::PasswordSpecificsData(password_specifics_data);
+ trimmed_password_data.clear_scheme();
+ trimmed_password_data.clear_signon_realm();
+ trimmed_password_data.clear_origin();
+ trimmed_password_data.clear_action();
+ trimmed_password_data.clear_username_element();
+ trimmed_password_data.clear_username_value();
+ trimmed_password_data.clear_password_element();
+ trimmed_password_data.clear_password_value();
+ trimmed_password_data.clear_date_created();
+ trimmed_password_data.clear_blacklisted();
+ trimmed_password_data.clear_type();
+ trimmed_password_data.clear_times_used();
+ trimmed_password_data.clear_display_name();
+ trimmed_password_data.clear_avatar_url();
+ trimmed_password_data.clear_federation_url();
+ trimmed_password_data.clear_date_last_used();
+ trimmed_password_data.clear_password_issues();
+ trimmed_password_data.clear_date_password_modified_windows_epoch_micros();
+ return trimmed_password_data;
+}
+
sync_pb::PasswordSpecifics SpecificsFromPassword(
const PasswordForm& password_form) {
sync_pb::PasswordSpecifics specifics;
*specifics.mutable_client_only_encrypted_data() =
SpecificsDataFromPassword(password_form);
+ // WARNING: if you are adding support for new `PasswordSpecificsData` fields,
+ // you need to update following functions accordingly:
+ // `TrimPasswordSpecificsDataForCaching`
+ // `TrimRemoteSpecificsForCachingPreservesOnlyUnknownFields`
+ DCHECK_EQ(0u, TrimPasswordSpecificsDataForCaching(
+ specifics.client_only_encrypted_data())
+ .ByteSizeLong());
return specifics;
}
diff --git a/components/password_manager/core/browser/sync/password_proto_utils.h b/components/password_manager/core/browser/sync/password_proto_utils.h
index 9d69c14..ef32d0f 100644
--- a/components/password_manager/core/browser/sync/password_proto_utils.h
+++ b/components/password_manager/core/browser/sync/password_proto_utils.h
@@ -57,6 +57,11 @@
std::vector<PasswordForm> PasswordVectorFromListResult(
const sync_pb::ListPasswordsResult& list_result);
+// Returns a copy of |password_specifics_data| with cleared supported fields
+// that don't need to be preserved in EntityMetadata cache.
+sync_pb::PasswordSpecificsData TrimPasswordSpecificsDataForCaching(
+ const sync_pb::PasswordSpecificsData& password_specifics_data);
+
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SYNC_PASSWORD_PROTO_UTILS_H_
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc
index 4d958ea..6a83eee8 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -843,6 +843,17 @@
sync_enabled_or_disabled_cb_.Run();
}
+sync_pb::EntitySpecifics PasswordSyncBridge::TrimRemoteSpecificsForCaching(
+ const sync_pb::EntitySpecifics& entity_specifics) {
+ DCHECK(entity_specifics.has_password());
+ sync_pb::EntitySpecifics trimmed_entity_specifics;
+ *trimmed_entity_specifics.mutable_password()
+ ->mutable_client_only_encrypted_data() =
+ TrimPasswordSpecificsDataForCaching(
+ entity_specifics.password().client_only_encrypted_data());
+ return trimmed_entity_specifics;
+}
+
std::set<FormPrimaryKey> PasswordSyncBridge::GetUnsyncedPasswordsStorageKeys() {
std::set<FormPrimaryKey> storage_keys;
DCHECK(password_store_sync_);
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.h b/components/password_manager/core/browser/sync/password_sync_bridge.h
index b549e95..6608cba 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge.h
+++ b/components/password_manager/core/browser/sync/password_sync_bridge.h
@@ -63,6 +63,8 @@
bool SupportsGetStorageKey() const override;
void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
delete_metadata_change_list) override;
+ sync_pb::EntitySpecifics TrimRemoteSpecificsForCaching(
+ const sync_pb::EntitySpecifics& entity_specifics) override;
static std::string ComputeClientTagForTesting(
const sync_pb::PasswordSpecificsData& password_data);
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
index 57c45d4..9e4fcba 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -1466,4 +1466,45 @@
EXPECT_FALSE(error);
}
+TEST_F(PasswordSyncBridgeTest,
+ TrimRemoteSpecificsForCachingPreservesOnlyUnknownFields) {
+ sync_pb::EntitySpecifics specifics_with_only_unknown_fields;
+ *specifics_with_only_unknown_fields.mutable_password()
+ ->mutable_client_only_encrypted_data()
+ ->mutable_unknown_fields() = "unknown_fields";
+
+ sync_pb::EntitySpecifics specifics;
+ sync_pb::PasswordSpecificsData* password_data =
+ specifics.mutable_password()->mutable_client_only_encrypted_data();
+ password_data->set_scheme(2);
+ password_data->set_signon_realm(kSignonRealm1);
+ password_data->set_origin("http://www.origin.com/");
+ password_data->set_action("action");
+ password_data->set_username_element("username_element");
+ password_data->set_username_value("username_value");
+ password_data->set_password_element("password_element");
+ password_data->set_password_value("password_value");
+ password_data->set_date_created(1000);
+ password_data->set_blacklisted(false);
+ password_data->set_type(0);
+ password_data->set_times_used(1);
+ password_data->set_display_name("display_name");
+ password_data->set_avatar_url("avatar_url");
+ password_data->set_federation_url("federation_url");
+ password_data->set_date_last_used(1000);
+ *password_data->mutable_password_issues() =
+ CreateSpecificsIssues({InsecureType::kLeaked});
+ password_data->set_date_password_modified_windows_epoch_micros(1000);
+
+ *specifics.mutable_password()
+ ->mutable_client_only_encrypted_data()
+ ->mutable_unknown_fields() = "unknown_fields";
+
+ sync_pb::EntitySpecifics trimmed_specifics =
+ bridge()->TrimRemoteSpecificsForCaching(specifics);
+
+ EXPECT_EQ(trimmed_specifics.SerializeAsString(),
+ specifics_with_only_unknown_fields.SerializeAsString());
+}
+
} // namespace password_manager
diff --git a/components/sync/model/model_type_sync_bridge.cc b/components/sync/model/model_type_sync_bridge.cc
index b6d63fac..626d46d2 100644
--- a/components/sync/model/model_type_sync_bridge.cc
+++ b/components/sync/model/model_type_sync_bridge.cc
@@ -68,6 +68,13 @@
return 0U;
}
+sync_pb::EntitySpecifics ModelTypeSyncBridge::TrimRemoteSpecificsForCaching(
+ const sync_pb::EntitySpecifics& entity_specifics) {
+ // Clears all fields by default to avoid the memory and I/O overhead of an
+ // additional copy of the data.
+ return sync_pb::EntitySpecifics();
+}
+
ModelTypeChangeProcessor* ModelTypeSyncBridge::change_processor() {
return change_processor_.get();
}
diff --git a/components/sync/model/model_type_sync_bridge.h b/components/sync/model/model_type_sync_bridge.h
index b693aaa..734de00 100644
--- a/components/sync/model/model_type_sync_bridge.h
+++ b/components/sync/model/model_type_sync_bridge.h
@@ -198,6 +198,17 @@
// SyncableService by other means.
virtual size_t EstimateSyncOverheadMemoryUsage() const;
+ // Returns a copy of |entity_specifics| where fields that do not need to be
+ // preserved in EntityMetadata cache are cleared. This allows each data type
+ // to specify which fields are supported in the current version. This usually
+ // means all known proto fields (i.e. all except unknown proto fields synced
+ // from more recent versions of the browser) but not always, since there are
+ // cases where a proto field is defined, but its implementation is not
+ // complete yet or exists behind a feature flag.
+ // By default, empty EntitySpecifics is returned.
+ virtual sync_pb::EntitySpecifics TrimRemoteSpecificsForCaching(
+ const sync_pb::EntitySpecifics& entity_specifics);
+
// Needs to be informed about any model change occurring via Delete() and
// Put(). The changing metadata should be stored to persistent storage
// before or atomically with the model changes.