Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: sync/syncable/model_type.cc

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sync/syncable/model_neutral_mutable_entry.cc ('k') | sync/syncable/model_type_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
5 #include "sync/internal_api/public/base/model_type.h"
6
7 #include <stddef.h>
8
9 #include "base/macros.h"
10 #include "base/strings/string_split.h"
11 #include "base/values.h"
12 #include "sync/protocol/app_notification_specifics.pb.h"
13 #include "sync/protocol/app_setting_specifics.pb.h"
14 #include "sync/protocol/app_specifics.pb.h"
15 #include "sync/protocol/autofill_specifics.pb.h"
16 #include "sync/protocol/bookmark_specifics.pb.h"
17 #include "sync/protocol/extension_setting_specifics.pb.h"
18 #include "sync/protocol/extension_specifics.pb.h"
19 #include "sync/protocol/nigori_specifics.pb.h"
20 #include "sync/protocol/password_specifics.pb.h"
21 #include "sync/protocol/preference_specifics.pb.h"
22 #include "sync/protocol/search_engine_specifics.pb.h"
23 #include "sync/protocol/session_specifics.pb.h"
24 #include "sync/protocol/sync.pb.h"
25 #include "sync/protocol/theme_specifics.pb.h"
26 #include "sync/protocol/typed_url_specifics.pb.h"
27 #include "sync/syncable/syncable_proto_util.h"
28
29 namespace syncer {
30
31 struct ModelTypeInfo {
32 const ModelType model_type;
33 // Model Type notification string.
34 // This needs to match the corresponding proto message name in sync.proto
35 const char* const notification_type;
36 // Root tag for Model Type
37 // This should be the same as the model type but all lowercase.
38 const char* const root_tag;
39 // String value for Model Type
40 // This should be the same as the model type but space separated and the
41 // first letter of every word capitalized.
42 const char* const model_type_string;
43 // SpecificsFieldNumber for Model Type
44 const int specifics_field_number;
45 // Histogram value should be unique for the Model Type, Existing histogram
46 // values should never be modified without updating "SyncModelTypes" enum in
47 // histograms.xml to maintain backward compatibility.
48 const int model_type_histogram_val;
49 };
50
51 // Below struct entries are in the same order as their definition in the
52 // ModelType enum. Don't forget to update the ModelType enum when you make
53 // changes to this list.
54 // Struct field values should be unique across the entire map.
55 const ModelTypeInfo kModelTypeInfoMap[] = {
56 {UNSPECIFIED, "", "", "Unspecified", -1, 0},
57 {TOP_LEVEL_FOLDER, "", "", "Top Level Folder", -1, 1},
58 {BOOKMARKS, "BOOKMARK", "bookmarks", "Bookmarks",
59 sync_pb::EntitySpecifics::kBookmarkFieldNumber, 2},
60 {PREFERENCES, "PREFERENCE", "preferences", "Preferences",
61 sync_pb::EntitySpecifics::kPreferenceFieldNumber, 3},
62 {PASSWORDS, "PASSWORD", "passwords", "Passwords",
63 sync_pb::EntitySpecifics::kPasswordFieldNumber, 4},
64 {AUTOFILL_PROFILE, "AUTOFILL_PROFILE", "autofill_profiles",
65 "Autofill Profiles", sync_pb::EntitySpecifics::kAutofillProfileFieldNumber,
66 5},
67 {AUTOFILL, "AUTOFILL", "autofill", "Autofill",
68 sync_pb::EntitySpecifics::kAutofillFieldNumber, 6},
69 {AUTOFILL_WALLET_DATA, "AUTOFILL_WALLET", "autofill_wallet",
70 "Autofill Wallet", sync_pb::EntitySpecifics::kAutofillWalletFieldNumber,
71 34},
72 {AUTOFILL_WALLET_METADATA, "WALLET_METADATA",
73 "autofill_wallet_metadata", "Autofill Wallet Metadata",
74 sync_pb::EntitySpecifics::kWalletMetadataFieldNumber, 35},
75 {THEMES, "THEME", "themes", "Themes",
76 sync_pb::EntitySpecifics::kThemeFieldNumber, 7},
77 {TYPED_URLS, "TYPED_URL", "typed_urls", "Typed URLs",
78 sync_pb::EntitySpecifics::kTypedUrlFieldNumber, 8},
79 {EXTENSIONS, "EXTENSION", "extensions", "Extensions",
80 sync_pb::EntitySpecifics::kExtensionFieldNumber, 9},
81 {SEARCH_ENGINES, "SEARCH_ENGINE", "search_engines", "Search Engines",
82 sync_pb::EntitySpecifics::kSearchEngineFieldNumber, 10},
83 {SESSIONS, "SESSION", "sessions", "Sessions",
84 sync_pb::EntitySpecifics::kSessionFieldNumber, 11},
85 {APPS, "APP", "apps", "Apps", sync_pb::EntitySpecifics::kAppFieldNumber,
86 12},
87 {APP_SETTINGS, "APP_SETTING", "app_settings", "App settings",
88 sync_pb::EntitySpecifics::kAppSettingFieldNumber, 13},
89 {EXTENSION_SETTINGS, "EXTENSION_SETTING", "extension_settings",
90 "Extension settings",
91 sync_pb::EntitySpecifics::kExtensionSettingFieldNumber, 14},
92 {APP_NOTIFICATIONS, "APP_NOTIFICATION", "app_notifications",
93 "App Notifications", sync_pb::EntitySpecifics::kAppNotificationFieldNumber,
94 15},
95 {HISTORY_DELETE_DIRECTIVES, "HISTORY_DELETE_DIRECTIVE",
96 "history_delete_directives", "History Delete Directives",
97 sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber, 16},
98 {SYNCED_NOTIFICATIONS, "SYNCED_NOTIFICATION", "synced_notifications",
99 "Synced Notifications",
100 sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber, 20},
101 {SYNCED_NOTIFICATION_APP_INFO, "SYNCED_NOTIFICATION_APP_INFO",
102 "synced_notification_app_info", "Synced Notification App Info",
103 sync_pb::EntitySpecifics::kSyncedNotificationAppInfoFieldNumber, 31},
104 {DICTIONARY, "DICTIONARY", "dictionary", "Dictionary",
105 sync_pb::EntitySpecifics::kDictionaryFieldNumber, 22},
106 {FAVICON_IMAGES, "FAVICON_IMAGE", "favicon_images", "Favicon Images",
107 sync_pb::EntitySpecifics::kFaviconImageFieldNumber, 23},
108 {FAVICON_TRACKING, "FAVICON_TRACKING", "favicon_tracking",
109 "Favicon Tracking", sync_pb::EntitySpecifics::kFaviconTrackingFieldNumber,
110 24},
111 {DEVICE_INFO, "DEVICE_INFO", "device_info", "Device Info",
112 sync_pb::EntitySpecifics::kDeviceInfoFieldNumber, 18},
113 {PRIORITY_PREFERENCES, "PRIORITY_PREFERENCE", "priority_preferences",
114 "Priority Preferences",
115 sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber, 21},
116 {SUPERVISED_USER_SETTINGS, "MANAGED_USER_SETTING", "managed_user_settings",
117 "Managed User Settings",
118 sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber, 26},
119 {SUPERVISED_USERS, "MANAGED_USER", "managed_users", "Managed Users",
120 sync_pb::EntitySpecifics::kManagedUserFieldNumber, 27},
121 {SUPERVISED_USER_SHARED_SETTINGS, "MANAGED_USER_SHARED_SETTING",
122 "managed_user_shared_settings", "Managed User Shared Settings",
123 sync_pb::EntitySpecifics::kManagedUserSharedSettingFieldNumber, 30},
124 {ARTICLES, "ARTICLE", "articles", "Articles",
125 sync_pb::EntitySpecifics::kArticleFieldNumber, 28},
126 {APP_LIST, "APP_LIST", "app_list", "App List",
127 sync_pb::EntitySpecifics::kAppListFieldNumber, 29},
128 {WIFI_CREDENTIALS, "WIFI_CREDENTIAL", "wifi_credentials",
129 "WiFi Credentials", sync_pb::EntitySpecifics::kWifiCredentialFieldNumber,
130 32},
131 {SUPERVISED_USER_WHITELISTS, "MANAGED_USER_WHITELIST",
132 "managed_user_whitelists", "Managed User Whitelists",
133 sync_pb::EntitySpecifics::kManagedUserWhitelistFieldNumber, 33},
134 {ARC_PACKAGE, "ARC_PACKAGE", "arc_package", "Arc Package",
135 sync_pb::EntitySpecifics::kArcPackageFieldNumber, 36},
136 {PROXY_TABS, "", "", "Tabs", -1, 25},
137 {NIGORI, "NIGORI", "nigori", "Encryption keys",
138 sync_pb::EntitySpecifics::kNigoriFieldNumber, 17},
139 {EXPERIMENTS, "EXPERIMENTS", "experiments", "Experiments",
140 sync_pb::EntitySpecifics::kExperimentsFieldNumber, 19},
141 };
142
143 static_assert(arraysize(kModelTypeInfoMap) == MODEL_TYPE_COUNT,
144 "kModelTypeInfoMap should have MODEL_TYPE_COUNT elements");
145
146 // Notes:
147 // 1) This list must contain exactly the same elements as the set returned by
148 // UserSelectableTypes().
149 // 2) This list must be in the same order as the respective values in the
150 // ModelType enum.
151 const char* kUserSelectableDataTypeNames[] = {
152 "bookmarks",
153 "preferences",
154 "passwords",
155 "autofill",
156 "themes",
157 "typedUrls",
158 "extensions",
159 "apps",
160 "tabs",
161 };
162
163 static_assert(
164 37 == MODEL_TYPE_COUNT,
165 "update kUserSelectableDataTypeName to match UserSelectableTypes");
166
167 void AddDefaultFieldValue(ModelType datatype,
168 sync_pb::EntitySpecifics* specifics) {
169 if (!ProtocolTypes().Has(datatype)) {
170 NOTREACHED() << "Only protocol types have field values.";
171 return;
172 }
173 switch (datatype) {
174 case BOOKMARKS:
175 specifics->mutable_bookmark();
176 break;
177 case PASSWORDS:
178 specifics->mutable_password();
179 break;
180 case PREFERENCES:
181 specifics->mutable_preference();
182 break;
183 case AUTOFILL:
184 specifics->mutable_autofill();
185 break;
186 case AUTOFILL_PROFILE:
187 specifics->mutable_autofill_profile();
188 break;
189 case AUTOFILL_WALLET_DATA:
190 specifics->mutable_autofill_wallet();
191 break;
192 case AUTOFILL_WALLET_METADATA:
193 specifics->mutable_wallet_metadata();
194 break;
195 case THEMES:
196 specifics->mutable_theme();
197 break;
198 case TYPED_URLS:
199 specifics->mutable_typed_url();
200 break;
201 case EXTENSIONS:
202 specifics->mutable_extension();
203 break;
204 case NIGORI:
205 specifics->mutable_nigori();
206 break;
207 case SEARCH_ENGINES:
208 specifics->mutable_search_engine();
209 break;
210 case SESSIONS:
211 specifics->mutable_session();
212 break;
213 case APPS:
214 specifics->mutable_app();
215 break;
216 case APP_LIST:
217 specifics->mutable_app_list();
218 break;
219 case APP_SETTINGS:
220 specifics->mutable_app_setting();
221 break;
222 case ARC_PACKAGE:
223 specifics->mutable_arc_package();
224 break;
225 case EXTENSION_SETTINGS:
226 specifics->mutable_extension_setting();
227 break;
228 case APP_NOTIFICATIONS:
229 specifics->mutable_app_notification();
230 break;
231 case HISTORY_DELETE_DIRECTIVES:
232 specifics->mutable_history_delete_directive();
233 break;
234 case SYNCED_NOTIFICATIONS:
235 specifics->mutable_synced_notification();
236 break;
237 case SYNCED_NOTIFICATION_APP_INFO:
238 specifics->mutable_synced_notification_app_info();
239 break;
240 case DEVICE_INFO:
241 specifics->mutable_device_info();
242 break;
243 case EXPERIMENTS:
244 specifics->mutable_experiments();
245 break;
246 case PRIORITY_PREFERENCES:
247 specifics->mutable_priority_preference();
248 break;
249 case DICTIONARY:
250 specifics->mutable_dictionary();
251 break;
252 case FAVICON_IMAGES:
253 specifics->mutable_favicon_image();
254 break;
255 case FAVICON_TRACKING:
256 specifics->mutable_favicon_tracking();
257 break;
258 case SUPERVISED_USER_SETTINGS:
259 specifics->mutable_managed_user_setting();
260 break;
261 case SUPERVISED_USERS:
262 specifics->mutable_managed_user();
263 break;
264 case SUPERVISED_USER_SHARED_SETTINGS:
265 specifics->mutable_managed_user_shared_setting();
266 break;
267 case SUPERVISED_USER_WHITELISTS:
268 specifics->mutable_managed_user_whitelist();
269 break;
270 case ARTICLES:
271 specifics->mutable_article();
272 break;
273 case WIFI_CREDENTIALS:
274 specifics->mutable_wifi_credential();
275 break;
276 default:
277 NOTREACHED() << "No known extension for model type.";
278 }
279 }
280
281 ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) {
282 ModelTypeSet protocol_types = ProtocolTypes();
283 for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
284 iter.Inc()) {
285 if (GetSpecificsFieldNumberFromModelType(iter.Get()) == field_number)
286 return iter.Get();
287 }
288 return UNSPECIFIED;
289 }
290
291 int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
292 DCHECK(ProtocolTypes().Has(model_type))
293 << "Only protocol types have field values.";
294 if (ProtocolTypes().Has(model_type))
295 return kModelTypeInfoMap[model_type].specifics_field_number;
296 NOTREACHED() << "No known extension for model type.";
297 return 0;
298 }
299
300 FullModelTypeSet ToFullModelTypeSet(ModelTypeSet in) {
301 FullModelTypeSet out;
302 for (ModelTypeSet::Iterator i = in.First(); i.Good(); i.Inc()) {
303 out.Put(i.Get());
304 }
305 return out;
306 }
307
308 // Note: keep this consistent with GetModelType in entry.cc!
309 ModelType GetModelType(const sync_pb::SyncEntity& sync_entity) {
310 DCHECK(!IsRoot(sync_entity)); // Root shouldn't ever go over the wire.
311
312 // Backwards compatibility with old (pre-specifics) protocol.
313 if (sync_entity.has_bookmarkdata())
314 return BOOKMARKS;
315
316 ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics());
317 if (specifics_type != UNSPECIFIED)
318 return specifics_type;
319
320 // Loose check for server-created top-level folders that aren't
321 // bound to a particular model type.
322 if (!sync_entity.server_defined_unique_tag().empty() &&
323 IsFolder(sync_entity)) {
324 return TOP_LEVEL_FOLDER;
325 }
326
327 // This is an item of a datatype we can't understand. Maybe it's
328 // from the future? Either we mis-encoded the object, or the
329 // server sent us entries it shouldn't have.
330 NOTREACHED() << "Unknown datatype in sync proto.";
331 return UNSPECIFIED;
332 }
333
334 ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
335 if (specifics.has_bookmark())
336 return BOOKMARKS;
337
338 if (specifics.has_password())
339 return PASSWORDS;
340
341 if (specifics.has_preference())
342 return PREFERENCES;
343
344 if (specifics.has_autofill())
345 return AUTOFILL;
346
347 if (specifics.has_autofill_profile())
348 return AUTOFILL_PROFILE;
349
350 if (specifics.has_autofill_wallet())
351 return AUTOFILL_WALLET_DATA;
352
353 if (specifics.has_wallet_metadata())
354 return AUTOFILL_WALLET_METADATA;
355
356 if (specifics.has_theme())
357 return THEMES;
358
359 if (specifics.has_typed_url())
360 return TYPED_URLS;
361
362 if (specifics.has_extension())
363 return EXTENSIONS;
364
365 if (specifics.has_nigori())
366 return NIGORI;
367
368 if (specifics.has_app())
369 return APPS;
370
371 if (specifics.has_app_list())
372 return APP_LIST;
373
374 if (specifics.has_arc_package())
375 return ARC_PACKAGE;
376
377 if (specifics.has_search_engine())
378 return SEARCH_ENGINES;
379
380 if (specifics.has_session())
381 return SESSIONS;
382
383 if (specifics.has_app_setting())
384 return APP_SETTINGS;
385
386 if (specifics.has_extension_setting())
387 return EXTENSION_SETTINGS;
388
389 if (specifics.has_app_notification())
390 return APP_NOTIFICATIONS;
391
392 if (specifics.has_history_delete_directive())
393 return HISTORY_DELETE_DIRECTIVES;
394
395 if (specifics.has_synced_notification())
396 return SYNCED_NOTIFICATIONS;
397
398 if (specifics.has_synced_notification_app_info())
399 return SYNCED_NOTIFICATION_APP_INFO;
400
401 if (specifics.has_device_info())
402 return DEVICE_INFO;
403
404 if (specifics.has_experiments())
405 return EXPERIMENTS;
406
407 if (specifics.has_priority_preference())
408 return PRIORITY_PREFERENCES;
409
410 if (specifics.has_dictionary())
411 return DICTIONARY;
412
413 if (specifics.has_favicon_image())
414 return FAVICON_IMAGES;
415
416 if (specifics.has_favicon_tracking())
417 return FAVICON_TRACKING;
418
419 if (specifics.has_managed_user_setting())
420 return SUPERVISED_USER_SETTINGS;
421
422 if (specifics.has_managed_user())
423 return SUPERVISED_USERS;
424
425 if (specifics.has_managed_user_shared_setting())
426 return SUPERVISED_USER_SHARED_SETTINGS;
427
428 if (specifics.has_managed_user_whitelist())
429 return SUPERVISED_USER_WHITELISTS;
430
431 if (specifics.has_article())
432 return ARTICLES;
433
434 if (specifics.has_wifi_credential())
435 return WIFI_CREDENTIALS;
436
437 return UNSPECIFIED;
438 }
439
440 ModelTypeSet ProtocolTypes() {
441 ModelTypeSet set = ModelTypeSet::All();
442 set.RemoveAll(ProxyTypes());
443 return set;
444 }
445
446 ModelTypeSet UserTypes() {
447 ModelTypeSet set;
448 // TODO(sync): We should be able to build the actual enumset's internal
449 // bitset value here at compile time, rather than performing an iteration
450 // every time.
451 for (int i = FIRST_USER_MODEL_TYPE; i <= LAST_USER_MODEL_TYPE; ++i) {
452 set.Put(ModelTypeFromInt(i));
453 }
454 return set;
455 }
456
457 ModelTypeSet UserSelectableTypes() {
458 ModelTypeSet set;
459 // Although the order doesn't technically matter here, it's clearer to keep
460 // these in the same order as their definition in the ModelType enum.
461 set.Put(BOOKMARKS);
462 set.Put(PREFERENCES);
463 set.Put(PASSWORDS);
464 set.Put(AUTOFILL);
465 set.Put(THEMES);
466 set.Put(TYPED_URLS);
467 set.Put(EXTENSIONS);
468 set.Put(APPS);
469 set.Put(PROXY_TABS);
470 return set;
471 }
472
473 bool IsUserSelectableType(ModelType model_type) {
474 return UserSelectableTypes().Has(model_type);
475 }
476
477 ModelTypeNameMap GetUserSelectableTypeNameMap() {
478 ModelTypeNameMap type_names;
479 ModelTypeSet type_set = UserSelectableTypes();
480 ModelTypeSet::Iterator it = type_set.First();
481 DCHECK_EQ(arraysize(kUserSelectableDataTypeNames), type_set.Size());
482 for (size_t i = 0; i < arraysize(kUserSelectableDataTypeNames) && it.Good();
483 ++i, it.Inc()) {
484 type_names[it.Get()] = kUserSelectableDataTypeNames[i];
485 }
486 return type_names;
487 }
488
489 ModelTypeSet EncryptableUserTypes() {
490 ModelTypeSet encryptable_user_types = UserTypes();
491 // We never encrypt history delete directives.
492 encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
493 // Synced notifications are not encrypted since the server must see changes.
494 encryptable_user_types.Remove(SYNCED_NOTIFICATIONS);
495 // Synced Notification App Info does not have private data, so it is not
496 // encrypted.
497 encryptable_user_types.Remove(SYNCED_NOTIFICATION_APP_INFO);
498 // Device info data is not encrypted because it might be synced before
499 // encryption is ready.
500 encryptable_user_types.Remove(DEVICE_INFO);
501 // Priority preferences are not encrypted because they might be synced before
502 // encryption is ready.
503 encryptable_user_types.Remove(PRIORITY_PREFERENCES);
504 // Supervised user settings are not encrypted since they are set server-side.
505 encryptable_user_types.Remove(SUPERVISED_USER_SETTINGS);
506 // Supervised users are not encrypted since they are managed server-side.
507 encryptable_user_types.Remove(SUPERVISED_USERS);
508 // Supervised user shared settings are not encrypted since they are managed
509 // server-side and shared between manager and supervised user.
510 encryptable_user_types.Remove(SUPERVISED_USER_SHARED_SETTINGS);
511 // Supervised user whitelists are not encrypted since they are managed
512 // server-side.
513 encryptable_user_types.Remove(SUPERVISED_USER_WHITELISTS);
514 // Proxy types have no sync representation and are therefore not encrypted.
515 // Note however that proxy types map to one or more protocol types, which
516 // may or may not be encrypted themselves.
517 encryptable_user_types.RemoveAll(ProxyTypes());
518 // Wallet data is not encrypted since it actually originates on the server.
519 encryptable_user_types.Remove(AUTOFILL_WALLET_DATA);
520 return encryptable_user_types;
521 }
522
523 ModelTypeSet PriorityUserTypes() {
524 return ModelTypeSet(DEVICE_INFO, PRIORITY_PREFERENCES);
525 }
526
527 ModelTypeSet ControlTypes() {
528 ModelTypeSet set;
529 // TODO(sync): We should be able to build the actual enumset's internal
530 // bitset value here at compile time, rather than performing an iteration
531 // every time.
532 for (int i = FIRST_CONTROL_MODEL_TYPE; i <= LAST_CONTROL_MODEL_TYPE; ++i) {
533 set.Put(ModelTypeFromInt(i));
534 }
535
536 return set;
537 }
538
539 ModelTypeSet ProxyTypes() {
540 ModelTypeSet set;
541 set.Put(PROXY_TABS);
542 return set;
543 }
544
545 bool IsControlType(ModelType model_type) {
546 return ControlTypes().Has(model_type);
547 }
548
549 ModelTypeSet CoreTypes() {
550 syncer::ModelTypeSet result;
551 result.PutAll(PriorityCoreTypes());
552
553 // The following are low priority core types.
554 result.Put(SYNCED_NOTIFICATIONS);
555 result.Put(SYNCED_NOTIFICATION_APP_INFO);
556 result.Put(SUPERVISED_USER_SHARED_SETTINGS);
557 result.Put(SUPERVISED_USER_WHITELISTS);
558
559 return result;
560 }
561
562 ModelTypeSet PriorityCoreTypes() {
563 syncer::ModelTypeSet result;
564 result.PutAll(ControlTypes());
565
566 // The following are non-control core types.
567 result.Put(SUPERVISED_USERS);
568 result.Put(SUPERVISED_USER_SETTINGS);
569
570 return result;
571 }
572
573 const char* ModelTypeToString(ModelType model_type) {
574 // This is used in serialization routines as well as for displaying debug
575 // information. Do not attempt to change these string values unless you know
576 // what you're doing.
577 if (model_type >= UNSPECIFIED && model_type < MODEL_TYPE_COUNT)
578 return kModelTypeInfoMap[model_type].model_type_string;
579 NOTREACHED() << "No known extension for model type.";
580 return "INVALID";
581 }
582
583 // The normal rules about histograms apply here. Always append to the bottom of
584 // the list, and be careful to not reuse integer values that have already been
585 // assigned.
586 //
587 // Don't forget to update the "SyncModelTypes" enum in histograms.xml when you
588 // make changes to this list.
589 int ModelTypeToHistogramInt(ModelType model_type) {
590 if (model_type >= UNSPECIFIED && model_type < MODEL_TYPE_COUNT)
591 return kModelTypeInfoMap[model_type].model_type_histogram_val;
592 return 0;
593 }
594
595 base::StringValue* ModelTypeToValue(ModelType model_type) {
596 if (model_type >= FIRST_REAL_MODEL_TYPE) {
597 return new base::StringValue(ModelTypeToString(model_type));
598 } else if (model_type == TOP_LEVEL_FOLDER) {
599 return new base::StringValue("Top-level folder");
600 } else if (model_type == UNSPECIFIED) {
601 return new base::StringValue("Unspecified");
602 }
603 NOTREACHED();
604 return new base::StringValue(std::string());
605 }
606
607 ModelType ModelTypeFromValue(const base::Value& value) {
608 if (value.IsType(base::Value::TYPE_STRING)) {
609 std::string result;
610 CHECK(value.GetAsString(&result));
611 return ModelTypeFromString(result);
612 } else if (value.IsType(base::Value::TYPE_INTEGER)) {
613 int result;
614 CHECK(value.GetAsInteger(&result));
615 return ModelTypeFromInt(result);
616 } else {
617 NOTREACHED() << "Unsupported value type: " << value.GetType();
618 return UNSPECIFIED;
619 }
620 }
621
622 ModelType ModelTypeFromString(const std::string& model_type_string) {
623 if (model_type_string != "Unspecified" &&
624 model_type_string != "Top Level Folder") {
625 for (size_t i = 0; i < arraysize(kModelTypeInfoMap); ++i) {
626 if (kModelTypeInfoMap[i].model_type_string == model_type_string)
627 return kModelTypeInfoMap[i].model_type;
628 }
629 }
630 NOTREACHED() << "No known model type corresponding to " << model_type_string
631 << ".";
632 return UNSPECIFIED;
633 }
634
635 std::string ModelTypeSetToString(ModelTypeSet model_types) {
636 std::string result;
637 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
638 if (!result.empty()) {
639 result += ", ";
640 }
641 result += ModelTypeToString(it.Get());
642 }
643 return result;
644 }
645
646 std::ostream& operator<<(std::ostream& out, ModelTypeSet model_type_set) {
647 return out << ModelTypeSetToString(model_type_set);
648 }
649
650 ModelTypeSet ModelTypeSetFromString(const std::string& model_types_string) {
651 std::string working_copy = model_types_string;
652 ModelTypeSet model_types;
653 while (!working_copy.empty()) {
654 // Remove any leading spaces.
655 working_copy = working_copy.substr(working_copy.find_first_not_of(' '));
656 if (working_copy.empty())
657 break;
658 std::string type_str;
659 size_t end = working_copy.find(',');
660 if (end == std::string::npos) {
661 end = working_copy.length() - 1;
662 type_str = working_copy;
663 } else {
664 type_str = working_copy.substr(0, end);
665 }
666 syncer::ModelType type = ModelTypeFromString(type_str);
667 if (IsRealDataType(type))
668 model_types.Put(type);
669 working_copy = working_copy.substr(end + 1);
670 }
671 return model_types;
672 }
673
674 std::unique_ptr<base::ListValue> ModelTypeSetToValue(ModelTypeSet model_types) {
675 std::unique_ptr<base::ListValue> value(new base::ListValue());
676 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
677 value->AppendString(ModelTypeToString(it.Get()));
678 }
679 return value;
680 }
681
682 ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value) {
683 ModelTypeSet result;
684 for (base::ListValue::const_iterator i = value.begin();
685 i != value.end(); ++i) {
686 result.Put(ModelTypeFromValue(**i));
687 }
688 return result;
689 }
690
691 // TODO(zea): remove all hardcoded tags in model associators and have them use
692 // this instead.
693 // NOTE: Proxy types should return empty strings (so that we don't NOTREACHED
694 // in tests when we verify they have no root node).
695 std::string ModelTypeToRootTag(ModelType type) {
696 if (IsProxyType(type))
697 return std::string();
698 if (IsRealDataType(type))
699 return "google_chrome_" + std::string(kModelTypeInfoMap[type].root_tag);
700 NOTREACHED() << "No known extension for model type.";
701 return "INVALID";
702 }
703
704 const char* GetModelTypeRootTag(ModelType model_type) {
705 return kModelTypeInfoMap[model_type].root_tag;
706 }
707
708 bool RealModelTypeToNotificationType(ModelType model_type,
709 std::string* notification_type) {
710 if (ProtocolTypes().Has(model_type)) {
711 *notification_type = kModelTypeInfoMap[model_type].notification_type;
712 return true;
713 }
714 notification_type->clear();
715 return false;
716 }
717
718 bool NotificationTypeToRealModelType(const std::string& notification_type,
719 ModelType* model_type) {
720 if (notification_type.empty()) {
721 *model_type = UNSPECIFIED;
722 return false;
723 }
724 for (size_t i = 0; i < arraysize(kModelTypeInfoMap); ++i) {
725 if (kModelTypeInfoMap[i].notification_type == notification_type) {
726 *model_type = kModelTypeInfoMap[i].model_type;
727 return true;
728 }
729 }
730 *model_type = UNSPECIFIED;
731 return false;
732 }
733
734 bool IsRealDataType(ModelType model_type) {
735 return model_type >= FIRST_REAL_MODEL_TYPE && model_type < MODEL_TYPE_COUNT;
736 }
737
738 bool IsProxyType(ModelType model_type) {
739 return model_type >= FIRST_PROXY_TYPE && model_type <= LAST_PROXY_TYPE;
740 }
741
742 bool IsActOnceDataType(ModelType model_type) {
743 return model_type == HISTORY_DELETE_DIRECTIVES;
744 }
745
746 bool IsTypeWithServerGeneratedRoot(ModelType model_type) {
747 return model_type == BOOKMARKS || model_type == NIGORI;
748 }
749
750 bool IsTypeWithClientGeneratedRoot(ModelType model_type) {
751 return IsRealDataType(model_type) &&
752 !IsTypeWithServerGeneratedRoot(model_type);
753 }
754
755 bool TypeSupportsHierarchy(ModelType model_type) {
756 // TODO(stanisc): crbug/438313: Should this also include TOP_LEVEL_FOLDER?
757 return model_type == BOOKMARKS;
758 }
759
760 bool TypeSupportsOrdering(ModelType model_type) {
761 return model_type == BOOKMARKS;
762 }
763
764 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/syncable/model_neutral_mutable_entry.cc ('k') | sync/syncable/model_type_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698