123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/sync/base/model_type.h"
- #include <stddef.h>
- #include <ostream>
- #include "base/logging.h"
- #include "base/notreached.h"
- #include "base/ranges/algorithm.h"
- #include "base/strings/string_split.h"
- #include "base/values.h"
- #include "components/sync/protocol/entity_specifics.pb.h"
- namespace syncer {
- struct ModelTypeInfo {
- const ModelType model_type;
- // Model Type notification string.
- // This needs to match the corresponding proto message name in sync.proto. It
- // is also used to identify the model type in the SyncModelType
- // histogram_suffix in histograms.xml. Must always be kept in sync.
- const char* const notification_type;
- // Root tag for Model Type
- // This should be the same as the model type but all lowercase.
- const char* const root_tag;
- // String value for Model Type
- // This should be the same as the model type but space separated and the
- // first letter of every word capitalized.
- const char* const model_type_debug_string;
- // Field number of the model type specifics in EntitySpecifics.
- const int specifics_field_number;
- // Model type value from SyncModelTypes enum in enums.xml. Must always be in
- // sync with the enum.
- const ModelTypeForHistograms model_type_histogram_val;
- };
- // Below struct entries are in the same order as their definition in the
- // ModelType enum. When making changes to this list, don't forget to
- // - update the ModelType enum,
- // - update the SyncModelTypes enum in enums.xml, and
- // - update the SyncModelType histogram suffix in histograms.xml.
- // Struct field values should be unique across the entire map.
- const ModelTypeInfo kModelTypeInfoMap[] = {
- {UNSPECIFIED, "", "", "Unspecified", -1,
- ModelTypeForHistograms::kUnspecified},
- {BOOKMARKS, "BOOKMARK", "bookmarks", "Bookmarks",
- sync_pb::EntitySpecifics::kBookmarkFieldNumber,
- ModelTypeForHistograms::kBookmarks},
- {PREFERENCES, "PREFERENCE", "preferences", "Preferences",
- sync_pb::EntitySpecifics::kPreferenceFieldNumber,
- ModelTypeForHistograms::kPreferences},
- {PASSWORDS, "PASSWORD", "passwords", "Passwords",
- sync_pb::EntitySpecifics::kPasswordFieldNumber,
- ModelTypeForHistograms::kPasswords},
- {AUTOFILL_PROFILE, "AUTOFILL_PROFILE", "autofill_profiles",
- "Autofill Profiles", sync_pb::EntitySpecifics::kAutofillProfileFieldNumber,
- ModelTypeForHistograms::kAutofillProfile},
- {AUTOFILL, "AUTOFILL", "autofill", "Autofill",
- sync_pb::EntitySpecifics::kAutofillFieldNumber,
- ModelTypeForHistograms::kAutofill},
- {AUTOFILL_WALLET_DATA, "AUTOFILL_WALLET", "autofill_wallet",
- "Autofill Wallet", sync_pb::EntitySpecifics::kAutofillWalletFieldNumber,
- ModelTypeForHistograms::kAutofillWalletData},
- {AUTOFILL_WALLET_METADATA, "WALLET_METADATA", "autofill_wallet_metadata",
- "Autofill Wallet Metadata",
- sync_pb::EntitySpecifics::kWalletMetadataFieldNumber,
- ModelTypeForHistograms::kAutofillWalletMetadata},
- {AUTOFILL_WALLET_OFFER, "AUTOFILL_OFFER", "autofill_wallet_offer",
- "Autofill Wallet Offer",
- sync_pb::EntitySpecifics::kAutofillOfferFieldNumber,
- ModelTypeForHistograms::kAutofillWalletOffer},
- {THEMES, "THEME", "themes", "Themes",
- sync_pb::EntitySpecifics::kThemeFieldNumber,
- ModelTypeForHistograms::kThemes},
- {TYPED_URLS, "TYPED_URL", "typed_urls", "Typed URLs",
- sync_pb::EntitySpecifics::kTypedUrlFieldNumber,
- ModelTypeForHistograms::kTypedUrls},
- {EXTENSIONS, "EXTENSION", "extensions", "Extensions",
- sync_pb::EntitySpecifics::kExtensionFieldNumber,
- ModelTypeForHistograms::kExtensions},
- {SEARCH_ENGINES, "SEARCH_ENGINE", "search_engines", "Search Engines",
- sync_pb::EntitySpecifics::kSearchEngineFieldNumber,
- ModelTypeForHistograms::kSearchEngines},
- {SESSIONS, "SESSION", "sessions", "Sessions",
- sync_pb::EntitySpecifics::kSessionFieldNumber,
- ModelTypeForHistograms::kSessions},
- {APPS, "APP", "apps", "Apps", sync_pb::EntitySpecifics::kAppFieldNumber,
- ModelTypeForHistograms::kApps},
- {APP_SETTINGS, "APP_SETTING", "app_settings", "App settings",
- sync_pb::EntitySpecifics::kAppSettingFieldNumber,
- ModelTypeForHistograms::kAppSettings},
- {EXTENSION_SETTINGS, "EXTENSION_SETTING", "extension_settings",
- "Extension settings",
- sync_pb::EntitySpecifics::kExtensionSettingFieldNumber,
- ModelTypeForHistograms::kExtensionSettings},
- {HISTORY_DELETE_DIRECTIVES, "HISTORY_DELETE_DIRECTIVE",
- "history_delete_directives", "History Delete Directives",
- sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber,
- ModelTypeForHistograms::kHistoryDeleteDirectices},
- {DICTIONARY, "DICTIONARY", "dictionary", "Dictionary",
- sync_pb::EntitySpecifics::kDictionaryFieldNumber,
- ModelTypeForHistograms::kDictionary},
- {DEVICE_INFO, "DEVICE_INFO", "device_info", "Device Info",
- sync_pb::EntitySpecifics::kDeviceInfoFieldNumber,
- ModelTypeForHistograms::kDeviceInfo},
- {PRIORITY_PREFERENCES, "PRIORITY_PREFERENCE", "priority_preferences",
- "Priority Preferences",
- sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber,
- ModelTypeForHistograms::kPriorityPreferences},
- {SUPERVISED_USER_SETTINGS, "MANAGED_USER_SETTING", "managed_user_settings",
- "Managed User Settings",
- sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber,
- ModelTypeForHistograms::kSupervisedUserSettings},
- {APP_LIST, "APP_LIST", "app_list", "App List",
- sync_pb::EntitySpecifics::kAppListFieldNumber,
- ModelTypeForHistograms::kAppList},
- {ARC_PACKAGE, "ARC_PACKAGE", "arc_package", "Arc Package",
- sync_pb::EntitySpecifics::kArcPackageFieldNumber,
- ModelTypeForHistograms::kArcPackage},
- {PRINTERS, "PRINTER", "printers", "Printers",
- sync_pb::EntitySpecifics::kPrinterFieldNumber,
- ModelTypeForHistograms::kPrinters},
- {READING_LIST, "READING_LIST", "reading_list", "Reading List",
- sync_pb::EntitySpecifics::kReadingListFieldNumber,
- ModelTypeForHistograms::kReadingList},
- {USER_EVENTS, "USER_EVENT", "user_events", "User Events",
- sync_pb::EntitySpecifics::kUserEventFieldNumber,
- ModelTypeForHistograms::kUserEvents},
- {USER_CONSENTS, "USER_CONSENT", "user_consent", "User Consents",
- sync_pb::EntitySpecifics::kUserConsentFieldNumber,
- ModelTypeForHistograms::kUserConsents},
- {SEND_TAB_TO_SELF, "SEND_TAB_TO_SELF", "send_tab_to_self",
- "Send Tab To Self", sync_pb::EntitySpecifics::kSendTabToSelfFieldNumber,
- ModelTypeForHistograms::kSendTabToSelf},
- {SECURITY_EVENTS, "SECURITY_EVENT", "security_events", "Security Events",
- sync_pb::EntitySpecifics::kSecurityEventFieldNumber,
- ModelTypeForHistograms::kSecurityEvents},
- {WIFI_CONFIGURATIONS, "WIFI_CONFIGURATION", "wifi_configurations",
- "Wifi Configurations",
- sync_pb::EntitySpecifics::kWifiConfigurationFieldNumber,
- ModelTypeForHistograms::kWifiConfigurations},
- {WEB_APPS, "WEB_APP", "web_apps", "Web Apps",
- sync_pb::EntitySpecifics::kWebAppFieldNumber,
- ModelTypeForHistograms::kWebApps},
- {OS_PREFERENCES, "OS_PREFERENCE", "os_preferences", "OS Preferences",
- sync_pb::EntitySpecifics::kOsPreferenceFieldNumber,
- ModelTypeForHistograms::kOsPreferences},
- {OS_PRIORITY_PREFERENCES, "OS_PRIORITY_PREFERENCE",
- "os_priority_preferences", "OS Priority Preferences",
- sync_pb::EntitySpecifics::kOsPriorityPreferenceFieldNumber,
- ModelTypeForHistograms::kOsPriorityPreferences},
- {SHARING_MESSAGE, "SHARING_MESSAGE", "sharing_message", "Sharing Message",
- sync_pb::EntitySpecifics::kSharingMessageFieldNumber,
- ModelTypeForHistograms::kSharingMessage},
- {WORKSPACE_DESK, "WORKSPACE_DESK", "workspace_desk", "Workspace Desk",
- sync_pb::EntitySpecifics::kWorkspaceDeskFieldNumber,
- ModelTypeForHistograms::kWorkspaceDesk},
- {HISTORY, "HISTORY", "history", "History",
- sync_pb::EntitySpecifics::kHistoryFieldNumber,
- ModelTypeForHistograms::kHistory},
- {PRINTERS_AUTHORIZATION_SERVERS, "PRINTERS_AUTHORIZATION_SERVER",
- "printers_authorization_servers", "Printers Authorization Servers",
- sync_pb::EntitySpecifics::kPrintersAuthorizationServerFieldNumber,
- ModelTypeForHistograms::kPrintersAuthorizationServers},
- // ---- Proxy types ----
- {PROXY_TABS, "", "", "Proxy tabs", -1, ModelTypeForHistograms::kProxyTabs},
- // ---- Control Types ----
- {NIGORI, "NIGORI", "nigori", "Encryption Keys",
- sync_pb::EntitySpecifics::kNigoriFieldNumber,
- ModelTypeForHistograms::kNigori},
- };
- static_assert(std::size(kModelTypeInfoMap) == GetNumModelTypes(),
- "kModelTypeInfoMap should have GetNumModelTypes() elements");
- static_assert(40 == syncer::GetNumModelTypes(),
- "When adding a new type, update enum SyncModelTypes in enums.xml "
- "and suffix SyncModelType in histograms.xml.");
- static_assert(40 == syncer::GetNumModelTypes(),
- "When adding a new type, update kAllocatorDumpNameAllowlist in "
- "base/trace_event/memory_infra_background_allowlist.cc.");
- void AddDefaultFieldValue(ModelType type, sync_pb::EntitySpecifics* specifics) {
- switch (type) {
- case UNSPECIFIED:
- NOTREACHED() << "No default field value for "
- << ModelTypeToDebugString(type);
- break;
- case BOOKMARKS:
- specifics->mutable_bookmark();
- break;
- case PREFERENCES:
- specifics->mutable_preference();
- break;
- case PASSWORDS:
- specifics->mutable_password();
- break;
- case AUTOFILL_PROFILE:
- specifics->mutable_autofill_profile();
- break;
- case AUTOFILL:
- specifics->mutable_autofill();
- break;
- case AUTOFILL_WALLET_DATA:
- specifics->mutable_autofill_wallet();
- break;
- case AUTOFILL_WALLET_METADATA:
- specifics->mutable_wallet_metadata();
- break;
- case AUTOFILL_WALLET_OFFER:
- specifics->mutable_autofill_offer();
- break;
- case THEMES:
- specifics->mutable_theme();
- break;
- case TYPED_URLS:
- specifics->mutable_typed_url();
- break;
- case EXTENSIONS:
- specifics->mutable_extension();
- break;
- case SEARCH_ENGINES:
- specifics->mutable_search_engine();
- break;
- case SESSIONS:
- specifics->mutable_session();
- break;
- case APPS:
- specifics->mutable_app();
- break;
- case APP_SETTINGS:
- specifics->mutable_app_setting();
- break;
- case EXTENSION_SETTINGS:
- specifics->mutable_extension_setting();
- break;
- case HISTORY_DELETE_DIRECTIVES:
- specifics->mutable_history_delete_directive();
- break;
- case DICTIONARY:
- specifics->mutable_dictionary();
- break;
- case DEVICE_INFO:
- specifics->mutable_device_info();
- break;
- case PRIORITY_PREFERENCES:
- specifics->mutable_priority_preference();
- break;
- case SUPERVISED_USER_SETTINGS:
- specifics->mutable_managed_user_setting();
- break;
- case APP_LIST:
- specifics->mutable_app_list();
- break;
- case ARC_PACKAGE:
- specifics->mutable_arc_package();
- break;
- case PRINTERS:
- specifics->mutable_printer();
- break;
- case PRINTERS_AUTHORIZATION_SERVERS:
- specifics->mutable_printers_authorization_server();
- break;
- case READING_LIST:
- specifics->mutable_reading_list();
- break;
- case USER_EVENTS:
- specifics->mutable_user_event();
- break;
- case SECURITY_EVENTS:
- specifics->mutable_security_event();
- break;
- case USER_CONSENTS:
- specifics->mutable_user_consent();
- break;
- case SEND_TAB_TO_SELF:
- specifics->mutable_send_tab_to_self();
- break;
- case PROXY_TABS:
- NOTREACHED() << "No default field value for "
- << ModelTypeToDebugString(type);
- break;
- case NIGORI:
- specifics->mutable_nigori();
- break;
- case WEB_APPS:
- specifics->mutable_web_app();
- break;
- case WIFI_CONFIGURATIONS:
- specifics->mutable_wifi_configuration();
- break;
- case WORKSPACE_DESK:
- specifics->mutable_workspace_desk();
- break;
- case OS_PREFERENCES:
- specifics->mutable_os_preference();
- break;
- case OS_PRIORITY_PREFERENCES:
- specifics->mutable_os_priority_preference();
- break;
- case SHARING_MESSAGE:
- specifics->mutable_sharing_message();
- break;
- case HISTORY:
- specifics->mutable_history();
- break;
- }
- }
- ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) {
- ModelTypeSet protocol_types = ProtocolTypes();
- for (ModelType type : protocol_types) {
- if (GetSpecificsFieldNumberFromModelType(type) == field_number)
- return type;
- }
- return UNSPECIFIED;
- }
- int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
- DCHECK(ProtocolTypes().Has(model_type))
- << "Only protocol types have field values.";
- return kModelTypeInfoMap[model_type].specifics_field_number;
- }
- ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
- static_assert(40 == syncer::GetNumModelTypes(),
- "When adding new protocol types, the following type lookup "
- "logic must be updated.");
- if (specifics.has_bookmark())
- return BOOKMARKS;
- if (specifics.has_preference())
- return PREFERENCES;
- if (specifics.has_password())
- return PASSWORDS;
- if (specifics.has_autofill_profile())
- return AUTOFILL_PROFILE;
- if (specifics.has_autofill())
- return AUTOFILL;
- if (specifics.has_autofill_wallet())
- return AUTOFILL_WALLET_DATA;
- if (specifics.has_wallet_metadata())
- return AUTOFILL_WALLET_METADATA;
- if (specifics.has_theme())
- return THEMES;
- if (specifics.has_typed_url())
- return TYPED_URLS;
- if (specifics.has_extension())
- return EXTENSIONS;
- if (specifics.has_search_engine())
- return SEARCH_ENGINES;
- if (specifics.has_session())
- return SESSIONS;
- if (specifics.has_app())
- return APPS;
- if (specifics.has_app_setting())
- return APP_SETTINGS;
- if (specifics.has_extension_setting())
- return EXTENSION_SETTINGS;
- if (specifics.has_history_delete_directive())
- return HISTORY_DELETE_DIRECTIVES;
- if (specifics.has_dictionary())
- return DICTIONARY;
- if (specifics.has_device_info())
- return DEVICE_INFO;
- if (specifics.has_priority_preference())
- return PRIORITY_PREFERENCES;
- if (specifics.has_managed_user_setting())
- return SUPERVISED_USER_SETTINGS;
- if (specifics.has_app_list())
- return APP_LIST;
- if (specifics.has_arc_package())
- return ARC_PACKAGE;
- if (specifics.has_printer())
- return PRINTERS;
- if (specifics.has_reading_list())
- return READING_LIST;
- if (specifics.has_user_event())
- return USER_EVENTS;
- if (specifics.has_user_consent())
- return USER_CONSENTS;
- if (specifics.has_nigori())
- return NIGORI;
- if (specifics.has_send_tab_to_self())
- return SEND_TAB_TO_SELF;
- if (specifics.has_security_event())
- return SECURITY_EVENTS;
- if (specifics.has_web_app())
- return WEB_APPS;
- if (specifics.has_wifi_configuration())
- return WIFI_CONFIGURATIONS;
- if (specifics.has_os_preference())
- return OS_PREFERENCES;
- if (specifics.has_os_priority_preference())
- return OS_PRIORITY_PREFERENCES;
- if (specifics.has_sharing_message())
- return SHARING_MESSAGE;
- if (specifics.has_autofill_offer())
- return AUTOFILL_WALLET_OFFER;
- if (specifics.has_workspace_desk())
- return WORKSPACE_DESK;
- if (specifics.has_history())
- return HISTORY;
- if (specifics.has_printers_authorization_server())
- return PRINTERS_AUTHORIZATION_SERVERS;
- // This client version doesn't understand |specifics|.
- DVLOG(1) << "Unknown datatype in sync proto.";
- return UNSPECIFIED;
- }
- ModelTypeSet EncryptableUserTypes() {
- static_assert(40 == syncer::GetNumModelTypes(),
- "If adding an unencryptable type, remove from "
- "encryptable_user_types below.");
- ModelTypeSet encryptable_user_types = UserTypes();
- // Wallet data is not encrypted since it actually originates on the server.
- encryptable_user_types.Remove(AUTOFILL_WALLET_DATA);
- encryptable_user_types.Remove(AUTOFILL_WALLET_OFFER);
- // Commit-only types are never encrypted since they are consumed server-side.
- encryptable_user_types.RemoveAll(CommitOnlyTypes());
- // Other types that are never encrypted because consumed server-side.
- encryptable_user_types.Remove(HISTORY);
- encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
- encryptable_user_types.Remove(DEVICE_INFO);
- // Never encrypted because also written server-side.
- encryptable_user_types.Remove(PRIORITY_PREFERENCES);
- encryptable_user_types.Remove(OS_PRIORITY_PREFERENCES);
- encryptable_user_types.Remove(SUPERVISED_USER_SETTINGS);
- // Proxy types have no sync representation and are therefore not encrypted.
- // Note however that proxy types map to one or more protocol types, which
- // may or may not be encrypted themselves.
- encryptable_user_types.RetainAll(ProtocolTypes());
- return encryptable_user_types;
- }
- const char* ModelTypeToDebugString(ModelType model_type) {
- // This is used for displaying debug information.
- return kModelTypeInfoMap[model_type].model_type_debug_string;
- }
- const char* ModelTypeToHistogramSuffix(ModelType model_type) {
- // We use the same string that is used for notification types because they
- // satisfy all we need (being stable and explanatory).
- return kModelTypeInfoMap[model_type].notification_type;
- }
- ModelTypeForHistograms ModelTypeHistogramValue(ModelType model_type) {
- return kModelTypeInfoMap[model_type].model_type_histogram_val;
- }
- int ModelTypeToStableIdentifier(ModelType model_type) {
- // Make sure the value is stable and positive.
- return static_cast<int>(ModelTypeHistogramValue(model_type)) + 1;
- }
- std::unique_ptr<base::Value> ModelTypeToValue(ModelType model_type) {
- return std::make_unique<base::Value>(ModelTypeToDebugString(model_type));
- }
- std::string ModelTypeSetToDebugString(ModelTypeSet model_types) {
- std::string result;
- for (ModelType type : model_types) {
- if (!result.empty()) {
- result += ", ";
- }
- result += ModelTypeToDebugString(type);
- }
- return result;
- }
- std::ostream& operator<<(std::ostream& out, ModelTypeSet model_type_set) {
- return out << ModelTypeSetToDebugString(model_type_set);
- }
- std::unique_ptr<base::ListValue> ModelTypeSetToValue(ModelTypeSet model_types) {
- std::unique_ptr<base::ListValue> value(new base::ListValue());
- for (ModelType type : model_types) {
- value->Append(ModelTypeToDebugString(type));
- }
- return value;
- }
- // TODO(zea): remove all hardcoded tags in model associators and have them use
- // this instead.
- std::string ModelTypeToRootTag(ModelType type) {
- DCHECK(ProtocolTypes().Has(type));
- DCHECK(IsRealDataType(type));
- const std::string root_tag = std::string(kModelTypeInfoMap[type].root_tag);
- DCHECK(!root_tag.empty());
- return "google_chrome_" + root_tag;
- }
- const char* GetModelTypeRootTag(ModelType model_type) {
- return kModelTypeInfoMap[model_type].root_tag;
- }
- bool RealModelTypeToNotificationType(ModelType model_type,
- std::string* notification_type) {
- if (ProtocolTypes().Has(model_type)) {
- *notification_type = kModelTypeInfoMap[model_type].notification_type;
- return true;
- }
- notification_type->clear();
- return false;
- }
- bool NotificationTypeToRealModelType(const std::string& notification_type,
- ModelType* model_type) {
- auto* iter = base::ranges::find(kModelTypeInfoMap, notification_type,
- &ModelTypeInfo::notification_type);
- if (iter == std::end(kModelTypeInfoMap)) {
- return false;
- }
- if (!IsRealDataType(iter->model_type)) {
- return false;
- }
- *model_type = iter->model_type;
- return true;
- }
- bool IsRealDataType(ModelType model_type) {
- return model_type >= FIRST_REAL_MODEL_TYPE &&
- model_type <= LAST_REAL_MODEL_TYPE;
- }
- bool IsActOnceDataType(ModelType model_type) {
- return model_type == HISTORY_DELETE_DIRECTIVES;
- }
- bool IsTypeWithServerGeneratedRoot(ModelType model_type) {
- return model_type == BOOKMARKS || model_type == NIGORI;
- }
- bool IsTypeWithClientGeneratedRoot(ModelType model_type) {
- return IsRealDataType(model_type) &&
- !IsTypeWithServerGeneratedRoot(model_type);
- }
- } // namespace syncer
|