model_type.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/sync/base/model_type.h"
  5. #include <stddef.h>
  6. #include <ostream>
  7. #include "base/logging.h"
  8. #include "base/notreached.h"
  9. #include "base/ranges/algorithm.h"
  10. #include "base/strings/string_split.h"
  11. #include "base/values.h"
  12. #include "components/sync/protocol/entity_specifics.pb.h"
  13. namespace syncer {
  14. struct ModelTypeInfo {
  15. const ModelType model_type;
  16. // Model Type notification string.
  17. // This needs to match the corresponding proto message name in sync.proto. It
  18. // is also used to identify the model type in the SyncModelType
  19. // histogram_suffix in histograms.xml. Must always be kept in sync.
  20. const char* const notification_type;
  21. // Root tag for Model Type
  22. // This should be the same as the model type but all lowercase.
  23. const char* const root_tag;
  24. // String value for Model Type
  25. // This should be the same as the model type but space separated and the
  26. // first letter of every word capitalized.
  27. const char* const model_type_debug_string;
  28. // Field number of the model type specifics in EntitySpecifics.
  29. const int specifics_field_number;
  30. // Model type value from SyncModelTypes enum in enums.xml. Must always be in
  31. // sync with the enum.
  32. const ModelTypeForHistograms model_type_histogram_val;
  33. };
  34. // Below struct entries are in the same order as their definition in the
  35. // ModelType enum. When making changes to this list, don't forget to
  36. // - update the ModelType enum,
  37. // - update the SyncModelTypes enum in enums.xml, and
  38. // - update the SyncModelType histogram suffix in histograms.xml.
  39. // Struct field values should be unique across the entire map.
  40. const ModelTypeInfo kModelTypeInfoMap[] = {
  41. {UNSPECIFIED, "", "", "Unspecified", -1,
  42. ModelTypeForHistograms::kUnspecified},
  43. {BOOKMARKS, "BOOKMARK", "bookmarks", "Bookmarks",
  44. sync_pb::EntitySpecifics::kBookmarkFieldNumber,
  45. ModelTypeForHistograms::kBookmarks},
  46. {PREFERENCES, "PREFERENCE", "preferences", "Preferences",
  47. sync_pb::EntitySpecifics::kPreferenceFieldNumber,
  48. ModelTypeForHistograms::kPreferences},
  49. {PASSWORDS, "PASSWORD", "passwords", "Passwords",
  50. sync_pb::EntitySpecifics::kPasswordFieldNumber,
  51. ModelTypeForHistograms::kPasswords},
  52. {AUTOFILL_PROFILE, "AUTOFILL_PROFILE", "autofill_profiles",
  53. "Autofill Profiles", sync_pb::EntitySpecifics::kAutofillProfileFieldNumber,
  54. ModelTypeForHistograms::kAutofillProfile},
  55. {AUTOFILL, "AUTOFILL", "autofill", "Autofill",
  56. sync_pb::EntitySpecifics::kAutofillFieldNumber,
  57. ModelTypeForHistograms::kAutofill},
  58. {AUTOFILL_WALLET_DATA, "AUTOFILL_WALLET", "autofill_wallet",
  59. "Autofill Wallet", sync_pb::EntitySpecifics::kAutofillWalletFieldNumber,
  60. ModelTypeForHistograms::kAutofillWalletData},
  61. {AUTOFILL_WALLET_METADATA, "WALLET_METADATA", "autofill_wallet_metadata",
  62. "Autofill Wallet Metadata",
  63. sync_pb::EntitySpecifics::kWalletMetadataFieldNumber,
  64. ModelTypeForHistograms::kAutofillWalletMetadata},
  65. {AUTOFILL_WALLET_OFFER, "AUTOFILL_OFFER", "autofill_wallet_offer",
  66. "Autofill Wallet Offer",
  67. sync_pb::EntitySpecifics::kAutofillOfferFieldNumber,
  68. ModelTypeForHistograms::kAutofillWalletOffer},
  69. {THEMES, "THEME", "themes", "Themes",
  70. sync_pb::EntitySpecifics::kThemeFieldNumber,
  71. ModelTypeForHistograms::kThemes},
  72. {TYPED_URLS, "TYPED_URL", "typed_urls", "Typed URLs",
  73. sync_pb::EntitySpecifics::kTypedUrlFieldNumber,
  74. ModelTypeForHistograms::kTypedUrls},
  75. {EXTENSIONS, "EXTENSION", "extensions", "Extensions",
  76. sync_pb::EntitySpecifics::kExtensionFieldNumber,
  77. ModelTypeForHistograms::kExtensions},
  78. {SEARCH_ENGINES, "SEARCH_ENGINE", "search_engines", "Search Engines",
  79. sync_pb::EntitySpecifics::kSearchEngineFieldNumber,
  80. ModelTypeForHistograms::kSearchEngines},
  81. {SESSIONS, "SESSION", "sessions", "Sessions",
  82. sync_pb::EntitySpecifics::kSessionFieldNumber,
  83. ModelTypeForHistograms::kSessions},
  84. {APPS, "APP", "apps", "Apps", sync_pb::EntitySpecifics::kAppFieldNumber,
  85. ModelTypeForHistograms::kApps},
  86. {APP_SETTINGS, "APP_SETTING", "app_settings", "App settings",
  87. sync_pb::EntitySpecifics::kAppSettingFieldNumber,
  88. ModelTypeForHistograms::kAppSettings},
  89. {EXTENSION_SETTINGS, "EXTENSION_SETTING", "extension_settings",
  90. "Extension settings",
  91. sync_pb::EntitySpecifics::kExtensionSettingFieldNumber,
  92. ModelTypeForHistograms::kExtensionSettings},
  93. {HISTORY_DELETE_DIRECTIVES, "HISTORY_DELETE_DIRECTIVE",
  94. "history_delete_directives", "History Delete Directives",
  95. sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber,
  96. ModelTypeForHistograms::kHistoryDeleteDirectices},
  97. {DICTIONARY, "DICTIONARY", "dictionary", "Dictionary",
  98. sync_pb::EntitySpecifics::kDictionaryFieldNumber,
  99. ModelTypeForHistograms::kDictionary},
  100. {DEVICE_INFO, "DEVICE_INFO", "device_info", "Device Info",
  101. sync_pb::EntitySpecifics::kDeviceInfoFieldNumber,
  102. ModelTypeForHistograms::kDeviceInfo},
  103. {PRIORITY_PREFERENCES, "PRIORITY_PREFERENCE", "priority_preferences",
  104. "Priority Preferences",
  105. sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber,
  106. ModelTypeForHistograms::kPriorityPreferences},
  107. {SUPERVISED_USER_SETTINGS, "MANAGED_USER_SETTING", "managed_user_settings",
  108. "Managed User Settings",
  109. sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber,
  110. ModelTypeForHistograms::kSupervisedUserSettings},
  111. {APP_LIST, "APP_LIST", "app_list", "App List",
  112. sync_pb::EntitySpecifics::kAppListFieldNumber,
  113. ModelTypeForHistograms::kAppList},
  114. {ARC_PACKAGE, "ARC_PACKAGE", "arc_package", "Arc Package",
  115. sync_pb::EntitySpecifics::kArcPackageFieldNumber,
  116. ModelTypeForHistograms::kArcPackage},
  117. {PRINTERS, "PRINTER", "printers", "Printers",
  118. sync_pb::EntitySpecifics::kPrinterFieldNumber,
  119. ModelTypeForHistograms::kPrinters},
  120. {READING_LIST, "READING_LIST", "reading_list", "Reading List",
  121. sync_pb::EntitySpecifics::kReadingListFieldNumber,
  122. ModelTypeForHistograms::kReadingList},
  123. {USER_EVENTS, "USER_EVENT", "user_events", "User Events",
  124. sync_pb::EntitySpecifics::kUserEventFieldNumber,
  125. ModelTypeForHistograms::kUserEvents},
  126. {USER_CONSENTS, "USER_CONSENT", "user_consent", "User Consents",
  127. sync_pb::EntitySpecifics::kUserConsentFieldNumber,
  128. ModelTypeForHistograms::kUserConsents},
  129. {SEND_TAB_TO_SELF, "SEND_TAB_TO_SELF", "send_tab_to_self",
  130. "Send Tab To Self", sync_pb::EntitySpecifics::kSendTabToSelfFieldNumber,
  131. ModelTypeForHistograms::kSendTabToSelf},
  132. {SECURITY_EVENTS, "SECURITY_EVENT", "security_events", "Security Events",
  133. sync_pb::EntitySpecifics::kSecurityEventFieldNumber,
  134. ModelTypeForHistograms::kSecurityEvents},
  135. {WIFI_CONFIGURATIONS, "WIFI_CONFIGURATION", "wifi_configurations",
  136. "Wifi Configurations",
  137. sync_pb::EntitySpecifics::kWifiConfigurationFieldNumber,
  138. ModelTypeForHistograms::kWifiConfigurations},
  139. {WEB_APPS, "WEB_APP", "web_apps", "Web Apps",
  140. sync_pb::EntitySpecifics::kWebAppFieldNumber,
  141. ModelTypeForHistograms::kWebApps},
  142. {OS_PREFERENCES, "OS_PREFERENCE", "os_preferences", "OS Preferences",
  143. sync_pb::EntitySpecifics::kOsPreferenceFieldNumber,
  144. ModelTypeForHistograms::kOsPreferences},
  145. {OS_PRIORITY_PREFERENCES, "OS_PRIORITY_PREFERENCE",
  146. "os_priority_preferences", "OS Priority Preferences",
  147. sync_pb::EntitySpecifics::kOsPriorityPreferenceFieldNumber,
  148. ModelTypeForHistograms::kOsPriorityPreferences},
  149. {SHARING_MESSAGE, "SHARING_MESSAGE", "sharing_message", "Sharing Message",
  150. sync_pb::EntitySpecifics::kSharingMessageFieldNumber,
  151. ModelTypeForHistograms::kSharingMessage},
  152. {WORKSPACE_DESK, "WORKSPACE_DESK", "workspace_desk", "Workspace Desk",
  153. sync_pb::EntitySpecifics::kWorkspaceDeskFieldNumber,
  154. ModelTypeForHistograms::kWorkspaceDesk},
  155. {HISTORY, "HISTORY", "history", "History",
  156. sync_pb::EntitySpecifics::kHistoryFieldNumber,
  157. ModelTypeForHistograms::kHistory},
  158. {PRINTERS_AUTHORIZATION_SERVERS, "PRINTERS_AUTHORIZATION_SERVER",
  159. "printers_authorization_servers", "Printers Authorization Servers",
  160. sync_pb::EntitySpecifics::kPrintersAuthorizationServerFieldNumber,
  161. ModelTypeForHistograms::kPrintersAuthorizationServers},
  162. // ---- Proxy types ----
  163. {PROXY_TABS, "", "", "Proxy tabs", -1, ModelTypeForHistograms::kProxyTabs},
  164. // ---- Control Types ----
  165. {NIGORI, "NIGORI", "nigori", "Encryption Keys",
  166. sync_pb::EntitySpecifics::kNigoriFieldNumber,
  167. ModelTypeForHistograms::kNigori},
  168. };
  169. static_assert(std::size(kModelTypeInfoMap) == GetNumModelTypes(),
  170. "kModelTypeInfoMap should have GetNumModelTypes() elements");
  171. static_assert(40 == syncer::GetNumModelTypes(),
  172. "When adding a new type, update enum SyncModelTypes in enums.xml "
  173. "and suffix SyncModelType in histograms.xml.");
  174. static_assert(40 == syncer::GetNumModelTypes(),
  175. "When adding a new type, update kAllocatorDumpNameAllowlist in "
  176. "base/trace_event/memory_infra_background_allowlist.cc.");
  177. void AddDefaultFieldValue(ModelType type, sync_pb::EntitySpecifics* specifics) {
  178. switch (type) {
  179. case UNSPECIFIED:
  180. NOTREACHED() << "No default field value for "
  181. << ModelTypeToDebugString(type);
  182. break;
  183. case BOOKMARKS:
  184. specifics->mutable_bookmark();
  185. break;
  186. case PREFERENCES:
  187. specifics->mutable_preference();
  188. break;
  189. case PASSWORDS:
  190. specifics->mutable_password();
  191. break;
  192. case AUTOFILL_PROFILE:
  193. specifics->mutable_autofill_profile();
  194. break;
  195. case AUTOFILL:
  196. specifics->mutable_autofill();
  197. break;
  198. case AUTOFILL_WALLET_DATA:
  199. specifics->mutable_autofill_wallet();
  200. break;
  201. case AUTOFILL_WALLET_METADATA:
  202. specifics->mutable_wallet_metadata();
  203. break;
  204. case AUTOFILL_WALLET_OFFER:
  205. specifics->mutable_autofill_offer();
  206. break;
  207. case THEMES:
  208. specifics->mutable_theme();
  209. break;
  210. case TYPED_URLS:
  211. specifics->mutable_typed_url();
  212. break;
  213. case EXTENSIONS:
  214. specifics->mutable_extension();
  215. break;
  216. case SEARCH_ENGINES:
  217. specifics->mutable_search_engine();
  218. break;
  219. case SESSIONS:
  220. specifics->mutable_session();
  221. break;
  222. case APPS:
  223. specifics->mutable_app();
  224. break;
  225. case APP_SETTINGS:
  226. specifics->mutable_app_setting();
  227. break;
  228. case EXTENSION_SETTINGS:
  229. specifics->mutable_extension_setting();
  230. break;
  231. case HISTORY_DELETE_DIRECTIVES:
  232. specifics->mutable_history_delete_directive();
  233. break;
  234. case DICTIONARY:
  235. specifics->mutable_dictionary();
  236. break;
  237. case DEVICE_INFO:
  238. specifics->mutable_device_info();
  239. break;
  240. case PRIORITY_PREFERENCES:
  241. specifics->mutable_priority_preference();
  242. break;
  243. case SUPERVISED_USER_SETTINGS:
  244. specifics->mutable_managed_user_setting();
  245. break;
  246. case APP_LIST:
  247. specifics->mutable_app_list();
  248. break;
  249. case ARC_PACKAGE:
  250. specifics->mutable_arc_package();
  251. break;
  252. case PRINTERS:
  253. specifics->mutable_printer();
  254. break;
  255. case PRINTERS_AUTHORIZATION_SERVERS:
  256. specifics->mutable_printers_authorization_server();
  257. break;
  258. case READING_LIST:
  259. specifics->mutable_reading_list();
  260. break;
  261. case USER_EVENTS:
  262. specifics->mutable_user_event();
  263. break;
  264. case SECURITY_EVENTS:
  265. specifics->mutable_security_event();
  266. break;
  267. case USER_CONSENTS:
  268. specifics->mutable_user_consent();
  269. break;
  270. case SEND_TAB_TO_SELF:
  271. specifics->mutable_send_tab_to_self();
  272. break;
  273. case PROXY_TABS:
  274. NOTREACHED() << "No default field value for "
  275. << ModelTypeToDebugString(type);
  276. break;
  277. case NIGORI:
  278. specifics->mutable_nigori();
  279. break;
  280. case WEB_APPS:
  281. specifics->mutable_web_app();
  282. break;
  283. case WIFI_CONFIGURATIONS:
  284. specifics->mutable_wifi_configuration();
  285. break;
  286. case WORKSPACE_DESK:
  287. specifics->mutable_workspace_desk();
  288. break;
  289. case OS_PREFERENCES:
  290. specifics->mutable_os_preference();
  291. break;
  292. case OS_PRIORITY_PREFERENCES:
  293. specifics->mutable_os_priority_preference();
  294. break;
  295. case SHARING_MESSAGE:
  296. specifics->mutable_sharing_message();
  297. break;
  298. case HISTORY:
  299. specifics->mutable_history();
  300. break;
  301. }
  302. }
  303. ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) {
  304. ModelTypeSet protocol_types = ProtocolTypes();
  305. for (ModelType type : protocol_types) {
  306. if (GetSpecificsFieldNumberFromModelType(type) == field_number)
  307. return type;
  308. }
  309. return UNSPECIFIED;
  310. }
  311. int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
  312. DCHECK(ProtocolTypes().Has(model_type))
  313. << "Only protocol types have field values.";
  314. return kModelTypeInfoMap[model_type].specifics_field_number;
  315. }
  316. ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
  317. static_assert(40 == syncer::GetNumModelTypes(),
  318. "When adding new protocol types, the following type lookup "
  319. "logic must be updated.");
  320. if (specifics.has_bookmark())
  321. return BOOKMARKS;
  322. if (specifics.has_preference())
  323. return PREFERENCES;
  324. if (specifics.has_password())
  325. return PASSWORDS;
  326. if (specifics.has_autofill_profile())
  327. return AUTOFILL_PROFILE;
  328. if (specifics.has_autofill())
  329. return AUTOFILL;
  330. if (specifics.has_autofill_wallet())
  331. return AUTOFILL_WALLET_DATA;
  332. if (specifics.has_wallet_metadata())
  333. return AUTOFILL_WALLET_METADATA;
  334. if (specifics.has_theme())
  335. return THEMES;
  336. if (specifics.has_typed_url())
  337. return TYPED_URLS;
  338. if (specifics.has_extension())
  339. return EXTENSIONS;
  340. if (specifics.has_search_engine())
  341. return SEARCH_ENGINES;
  342. if (specifics.has_session())
  343. return SESSIONS;
  344. if (specifics.has_app())
  345. return APPS;
  346. if (specifics.has_app_setting())
  347. return APP_SETTINGS;
  348. if (specifics.has_extension_setting())
  349. return EXTENSION_SETTINGS;
  350. if (specifics.has_history_delete_directive())
  351. return HISTORY_DELETE_DIRECTIVES;
  352. if (specifics.has_dictionary())
  353. return DICTIONARY;
  354. if (specifics.has_device_info())
  355. return DEVICE_INFO;
  356. if (specifics.has_priority_preference())
  357. return PRIORITY_PREFERENCES;
  358. if (specifics.has_managed_user_setting())
  359. return SUPERVISED_USER_SETTINGS;
  360. if (specifics.has_app_list())
  361. return APP_LIST;
  362. if (specifics.has_arc_package())
  363. return ARC_PACKAGE;
  364. if (specifics.has_printer())
  365. return PRINTERS;
  366. if (specifics.has_reading_list())
  367. return READING_LIST;
  368. if (specifics.has_user_event())
  369. return USER_EVENTS;
  370. if (specifics.has_user_consent())
  371. return USER_CONSENTS;
  372. if (specifics.has_nigori())
  373. return NIGORI;
  374. if (specifics.has_send_tab_to_self())
  375. return SEND_TAB_TO_SELF;
  376. if (specifics.has_security_event())
  377. return SECURITY_EVENTS;
  378. if (specifics.has_web_app())
  379. return WEB_APPS;
  380. if (specifics.has_wifi_configuration())
  381. return WIFI_CONFIGURATIONS;
  382. if (specifics.has_os_preference())
  383. return OS_PREFERENCES;
  384. if (specifics.has_os_priority_preference())
  385. return OS_PRIORITY_PREFERENCES;
  386. if (specifics.has_sharing_message())
  387. return SHARING_MESSAGE;
  388. if (specifics.has_autofill_offer())
  389. return AUTOFILL_WALLET_OFFER;
  390. if (specifics.has_workspace_desk())
  391. return WORKSPACE_DESK;
  392. if (specifics.has_history())
  393. return HISTORY;
  394. if (specifics.has_printers_authorization_server())
  395. return PRINTERS_AUTHORIZATION_SERVERS;
  396. // This client version doesn't understand |specifics|.
  397. DVLOG(1) << "Unknown datatype in sync proto.";
  398. return UNSPECIFIED;
  399. }
  400. ModelTypeSet EncryptableUserTypes() {
  401. static_assert(40 == syncer::GetNumModelTypes(),
  402. "If adding an unencryptable type, remove from "
  403. "encryptable_user_types below.");
  404. ModelTypeSet encryptable_user_types = UserTypes();
  405. // Wallet data is not encrypted since it actually originates on the server.
  406. encryptable_user_types.Remove(AUTOFILL_WALLET_DATA);
  407. encryptable_user_types.Remove(AUTOFILL_WALLET_OFFER);
  408. // Commit-only types are never encrypted since they are consumed server-side.
  409. encryptable_user_types.RemoveAll(CommitOnlyTypes());
  410. // Other types that are never encrypted because consumed server-side.
  411. encryptable_user_types.Remove(HISTORY);
  412. encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
  413. encryptable_user_types.Remove(DEVICE_INFO);
  414. // Never encrypted because also written server-side.
  415. encryptable_user_types.Remove(PRIORITY_PREFERENCES);
  416. encryptable_user_types.Remove(OS_PRIORITY_PREFERENCES);
  417. encryptable_user_types.Remove(SUPERVISED_USER_SETTINGS);
  418. // Proxy types have no sync representation and are therefore not encrypted.
  419. // Note however that proxy types map to one or more protocol types, which
  420. // may or may not be encrypted themselves.
  421. encryptable_user_types.RetainAll(ProtocolTypes());
  422. return encryptable_user_types;
  423. }
  424. const char* ModelTypeToDebugString(ModelType model_type) {
  425. // This is used for displaying debug information.
  426. return kModelTypeInfoMap[model_type].model_type_debug_string;
  427. }
  428. const char* ModelTypeToHistogramSuffix(ModelType model_type) {
  429. // We use the same string that is used for notification types because they
  430. // satisfy all we need (being stable and explanatory).
  431. return kModelTypeInfoMap[model_type].notification_type;
  432. }
  433. ModelTypeForHistograms ModelTypeHistogramValue(ModelType model_type) {
  434. return kModelTypeInfoMap[model_type].model_type_histogram_val;
  435. }
  436. int ModelTypeToStableIdentifier(ModelType model_type) {
  437. // Make sure the value is stable and positive.
  438. return static_cast<int>(ModelTypeHistogramValue(model_type)) + 1;
  439. }
  440. std::unique_ptr<base::Value> ModelTypeToValue(ModelType model_type) {
  441. return std::make_unique<base::Value>(ModelTypeToDebugString(model_type));
  442. }
  443. std::string ModelTypeSetToDebugString(ModelTypeSet model_types) {
  444. std::string result;
  445. for (ModelType type : model_types) {
  446. if (!result.empty()) {
  447. result += ", ";
  448. }
  449. result += ModelTypeToDebugString(type);
  450. }
  451. return result;
  452. }
  453. std::ostream& operator<<(std::ostream& out, ModelTypeSet model_type_set) {
  454. return out << ModelTypeSetToDebugString(model_type_set);
  455. }
  456. std::unique_ptr<base::ListValue> ModelTypeSetToValue(ModelTypeSet model_types) {
  457. std::unique_ptr<base::ListValue> value(new base::ListValue());
  458. for (ModelType type : model_types) {
  459. value->Append(ModelTypeToDebugString(type));
  460. }
  461. return value;
  462. }
  463. // TODO(zea): remove all hardcoded tags in model associators and have them use
  464. // this instead.
  465. std::string ModelTypeToRootTag(ModelType type) {
  466. DCHECK(ProtocolTypes().Has(type));
  467. DCHECK(IsRealDataType(type));
  468. const std::string root_tag = std::string(kModelTypeInfoMap[type].root_tag);
  469. DCHECK(!root_tag.empty());
  470. return "google_chrome_" + root_tag;
  471. }
  472. const char* GetModelTypeRootTag(ModelType model_type) {
  473. return kModelTypeInfoMap[model_type].root_tag;
  474. }
  475. bool RealModelTypeToNotificationType(ModelType model_type,
  476. std::string* notification_type) {
  477. if (ProtocolTypes().Has(model_type)) {
  478. *notification_type = kModelTypeInfoMap[model_type].notification_type;
  479. return true;
  480. }
  481. notification_type->clear();
  482. return false;
  483. }
  484. bool NotificationTypeToRealModelType(const std::string& notification_type,
  485. ModelType* model_type) {
  486. auto* iter = base::ranges::find(kModelTypeInfoMap, notification_type,
  487. &ModelTypeInfo::notification_type);
  488. if (iter == std::end(kModelTypeInfoMap)) {
  489. return false;
  490. }
  491. if (!IsRealDataType(iter->model_type)) {
  492. return false;
  493. }
  494. *model_type = iter->model_type;
  495. return true;
  496. }
  497. bool IsRealDataType(ModelType model_type) {
  498. return model_type >= FIRST_REAL_MODEL_TYPE &&
  499. model_type <= LAST_REAL_MODEL_TYPE;
  500. }
  501. bool IsActOnceDataType(ModelType model_type) {
  502. return model_type == HISTORY_DELETE_DIRECTIVES;
  503. }
  504. bool IsTypeWithServerGeneratedRoot(ModelType model_type) {
  505. return model_type == BOOKMARKS || model_type == NIGORI;
  506. }
  507. bool IsTypeWithClientGeneratedRoot(ModelType model_type) {
  508. return IsRealDataType(model_type) &&
  509. !IsTypeWithServerGeneratedRoot(model_type);
  510. }
  511. } // namespace syncer