Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / sync / syncable / model_type.cc
blob806b6f2a71673a288a6c90409123b89c0e200bb5
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.
5 #include "sync/internal_api/public/base/model_type.h"
7 #include "base/strings/string_split.h"
8 #include "base/values.h"
9 #include "sync/protocol/app_notification_specifics.pb.h"
10 #include "sync/protocol/app_setting_specifics.pb.h"
11 #include "sync/protocol/app_specifics.pb.h"
12 #include "sync/protocol/autofill_specifics.pb.h"
13 #include "sync/protocol/bookmark_specifics.pb.h"
14 #include "sync/protocol/extension_setting_specifics.pb.h"
15 #include "sync/protocol/extension_specifics.pb.h"
16 #include "sync/protocol/nigori_specifics.pb.h"
17 #include "sync/protocol/password_specifics.pb.h"
18 #include "sync/protocol/preference_specifics.pb.h"
19 #include "sync/protocol/search_engine_specifics.pb.h"
20 #include "sync/protocol/session_specifics.pb.h"
21 #include "sync/protocol/sync.pb.h"
22 #include "sync/protocol/theme_specifics.pb.h"
23 #include "sync/protocol/typed_url_specifics.pb.h"
24 #include "sync/syncable/syncable_proto_util.h"
26 namespace syncer {
28 // Notes:
29 // 1) This list must contain exactly the same elements as the set returned by
30 // UserSelectableTypes().
31 // 2) This list must be in the same order as the respective values in the
32 // ModelType enum.
33 const char* kUserSelectableDataTypeNames[] = {
34 "bookmarks",
35 "preferences",
36 "passwords",
37 "autofill",
38 "themes",
39 "typedUrls",
40 "extensions",
41 "apps",
42 "wifiCredentials",
43 "tabs",
46 static_assert(
47 35 == MODEL_TYPE_COUNT,
48 "update kUserSelectableDataTypeName to match UserSelectableTypes");
50 void AddDefaultFieldValue(ModelType datatype,
51 sync_pb::EntitySpecifics* specifics) {
52 if (!ProtocolTypes().Has(datatype)) {
53 NOTREACHED() << "Only protocol types have field values.";
54 return;
56 switch (datatype) {
57 case BOOKMARKS:
58 specifics->mutable_bookmark();
59 break;
60 case PASSWORDS:
61 specifics->mutable_password();
62 break;
63 case PREFERENCES:
64 specifics->mutable_preference();
65 break;
66 case AUTOFILL:
67 specifics->mutable_autofill();
68 break;
69 case AUTOFILL_PROFILE:
70 specifics->mutable_autofill_profile();
71 break;
72 case AUTOFILL_WALLET_DATA:
73 specifics->mutable_autofill_wallet();
74 break;
75 case THEMES:
76 specifics->mutable_theme();
77 break;
78 case TYPED_URLS:
79 specifics->mutable_typed_url();
80 break;
81 case EXTENSIONS:
82 specifics->mutable_extension();
83 break;
84 case NIGORI:
85 specifics->mutable_nigori();
86 break;
87 case SEARCH_ENGINES:
88 specifics->mutable_search_engine();
89 break;
90 case SESSIONS:
91 specifics->mutable_session();
92 break;
93 case APPS:
94 specifics->mutable_app();
95 break;
96 case APP_LIST:
97 specifics->mutable_app_list();
98 break;
99 case APP_SETTINGS:
100 specifics->mutable_app_setting();
101 break;
102 case EXTENSION_SETTINGS:
103 specifics->mutable_extension_setting();
104 break;
105 case APP_NOTIFICATIONS:
106 specifics->mutable_app_notification();
107 break;
108 case HISTORY_DELETE_DIRECTIVES:
109 specifics->mutable_history_delete_directive();
110 break;
111 case SYNCED_NOTIFICATIONS:
112 specifics->mutable_synced_notification();
113 break;
114 case SYNCED_NOTIFICATION_APP_INFO:
115 specifics->mutable_synced_notification_app_info();
116 break;
117 case DEVICE_INFO:
118 specifics->mutable_device_info();
119 break;
120 case EXPERIMENTS:
121 specifics->mutable_experiments();
122 break;
123 case PRIORITY_PREFERENCES:
124 specifics->mutable_priority_preference();
125 break;
126 case DICTIONARY:
127 specifics->mutable_dictionary();
128 break;
129 case FAVICON_IMAGES:
130 specifics->mutable_favicon_image();
131 break;
132 case FAVICON_TRACKING:
133 specifics->mutable_favicon_tracking();
134 break;
135 case SUPERVISED_USER_SETTINGS:
136 specifics->mutable_managed_user_setting();
137 break;
138 case SUPERVISED_USERS:
139 specifics->mutable_managed_user();
140 break;
141 case SUPERVISED_USER_SHARED_SETTINGS:
142 specifics->mutable_managed_user_shared_setting();
143 break;
144 case SUPERVISED_USER_WHITELISTS:
145 specifics->mutable_managed_user_whitelist();
146 break;
147 case ARTICLES:
148 specifics->mutable_article();
149 break;
150 case WIFI_CREDENTIALS:
151 specifics->mutable_wifi_credential();
152 break;
153 default:
154 NOTREACHED() << "No known extension for model type.";
158 ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) {
159 ModelTypeSet protocol_types = ProtocolTypes();
160 for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
161 iter.Inc()) {
162 if (GetSpecificsFieldNumberFromModelType(iter.Get()) == field_number)
163 return iter.Get();
165 return UNSPECIFIED;
168 int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
169 DCHECK(ProtocolTypes().Has(model_type))
170 << "Only protocol types have field values.";
171 switch (model_type) {
172 case BOOKMARKS:
173 return sync_pb::EntitySpecifics::kBookmarkFieldNumber;
174 case PASSWORDS:
175 return sync_pb::EntitySpecifics::kPasswordFieldNumber;
176 case PREFERENCES:
177 return sync_pb::EntitySpecifics::kPreferenceFieldNumber;
178 case AUTOFILL:
179 return sync_pb::EntitySpecifics::kAutofillFieldNumber;
180 case AUTOFILL_PROFILE:
181 return sync_pb::EntitySpecifics::kAutofillProfileFieldNumber;
182 case AUTOFILL_WALLET_DATA:
183 return sync_pb::EntitySpecifics::kAutofillWalletFieldNumber;
184 case THEMES:
185 return sync_pb::EntitySpecifics::kThemeFieldNumber;
186 case TYPED_URLS:
187 return sync_pb::EntitySpecifics::kTypedUrlFieldNumber;
188 case EXTENSIONS:
189 return sync_pb::EntitySpecifics::kExtensionFieldNumber;
190 case NIGORI:
191 return sync_pb::EntitySpecifics::kNigoriFieldNumber;
192 case SEARCH_ENGINES:
193 return sync_pb::EntitySpecifics::kSearchEngineFieldNumber;
194 case SESSIONS:
195 return sync_pb::EntitySpecifics::kSessionFieldNumber;
196 case APPS:
197 return sync_pb::EntitySpecifics::kAppFieldNumber;
198 case APP_LIST:
199 return sync_pb::EntitySpecifics::kAppListFieldNumber;
200 case APP_SETTINGS:
201 return sync_pb::EntitySpecifics::kAppSettingFieldNumber;
202 case EXTENSION_SETTINGS:
203 return sync_pb::EntitySpecifics::kExtensionSettingFieldNumber;
204 case APP_NOTIFICATIONS:
205 return sync_pb::EntitySpecifics::kAppNotificationFieldNumber;
206 case HISTORY_DELETE_DIRECTIVES:
207 return sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber;
208 case SYNCED_NOTIFICATIONS:
209 return sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber;
210 case SYNCED_NOTIFICATION_APP_INFO:
211 return sync_pb::EntitySpecifics::kSyncedNotificationAppInfoFieldNumber;
212 case DEVICE_INFO:
213 return sync_pb::EntitySpecifics::kDeviceInfoFieldNumber;
214 case EXPERIMENTS:
215 return sync_pb::EntitySpecifics::kExperimentsFieldNumber;
216 case PRIORITY_PREFERENCES:
217 return sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber;
218 case DICTIONARY:
219 return sync_pb::EntitySpecifics::kDictionaryFieldNumber;
220 case FAVICON_IMAGES:
221 return sync_pb::EntitySpecifics::kFaviconImageFieldNumber;
222 case FAVICON_TRACKING:
223 return sync_pb::EntitySpecifics::kFaviconTrackingFieldNumber;
224 case SUPERVISED_USER_SETTINGS:
225 return sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber;
226 case SUPERVISED_USERS:
227 return sync_pb::EntitySpecifics::kManagedUserFieldNumber;
228 case SUPERVISED_USER_SHARED_SETTINGS:
229 return sync_pb::EntitySpecifics::kManagedUserSharedSettingFieldNumber;
230 case SUPERVISED_USER_WHITELISTS:
231 return sync_pb::EntitySpecifics::kManagedUserWhitelistFieldNumber;
232 case ARTICLES:
233 return sync_pb::EntitySpecifics::kArticleFieldNumber;
234 case WIFI_CREDENTIALS:
235 return sync_pb::EntitySpecifics::kWifiCredentialFieldNumber;
236 default:
237 NOTREACHED() << "No known extension for model type.";
238 return 0;
242 FullModelTypeSet ToFullModelTypeSet(ModelTypeSet in) {
243 FullModelTypeSet out;
244 for (ModelTypeSet::Iterator i = in.First(); i.Good(); i.Inc()) {
245 out.Put(i.Get());
247 return out;
250 // Note: keep this consistent with GetModelType in entry.cc!
251 ModelType GetModelType(const sync_pb::SyncEntity& sync_entity) {
252 DCHECK(!IsRoot(sync_entity)); // Root shouldn't ever go over the wire.
254 // Backwards compatibility with old (pre-specifics) protocol.
255 if (sync_entity.has_bookmarkdata())
256 return BOOKMARKS;
258 ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics());
259 if (specifics_type != UNSPECIFIED)
260 return specifics_type;
262 // Loose check for server-created top-level folders that aren't
263 // bound to a particular model type.
264 if (!sync_entity.server_defined_unique_tag().empty() &&
265 IsFolder(sync_entity)) {
266 return TOP_LEVEL_FOLDER;
269 // This is an item of a datatype we can't understand. Maybe it's
270 // from the future? Either we mis-encoded the object, or the
271 // server sent us entries it shouldn't have.
272 NOTREACHED() << "Unknown datatype in sync proto.";
273 return UNSPECIFIED;
276 ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
277 if (specifics.has_bookmark())
278 return BOOKMARKS;
280 if (specifics.has_password())
281 return PASSWORDS;
283 if (specifics.has_preference())
284 return PREFERENCES;
286 if (specifics.has_autofill())
287 return AUTOFILL;
289 if (specifics.has_autofill_profile())
290 return AUTOFILL_PROFILE;
292 if (specifics.has_autofill_wallet())
293 return AUTOFILL_WALLET_DATA;
295 if (specifics.has_theme())
296 return THEMES;
298 if (specifics.has_typed_url())
299 return TYPED_URLS;
301 if (specifics.has_extension())
302 return EXTENSIONS;
304 if (specifics.has_nigori())
305 return NIGORI;
307 if (specifics.has_app())
308 return APPS;
310 if (specifics.has_app_list())
311 return APP_LIST;
313 if (specifics.has_search_engine())
314 return SEARCH_ENGINES;
316 if (specifics.has_session())
317 return SESSIONS;
319 if (specifics.has_app_setting())
320 return APP_SETTINGS;
322 if (specifics.has_extension_setting())
323 return EXTENSION_SETTINGS;
325 if (specifics.has_app_notification())
326 return APP_NOTIFICATIONS;
328 if (specifics.has_history_delete_directive())
329 return HISTORY_DELETE_DIRECTIVES;
331 if (specifics.has_synced_notification())
332 return SYNCED_NOTIFICATIONS;
334 if (specifics.has_synced_notification_app_info())
335 return SYNCED_NOTIFICATION_APP_INFO;
337 if (specifics.has_device_info())
338 return DEVICE_INFO;
340 if (specifics.has_experiments())
341 return EXPERIMENTS;
343 if (specifics.has_priority_preference())
344 return PRIORITY_PREFERENCES;
346 if (specifics.has_dictionary())
347 return DICTIONARY;
349 if (specifics.has_favicon_image())
350 return FAVICON_IMAGES;
352 if (specifics.has_favicon_tracking())
353 return FAVICON_TRACKING;
355 if (specifics.has_managed_user_setting())
356 return SUPERVISED_USER_SETTINGS;
358 if (specifics.has_managed_user())
359 return SUPERVISED_USERS;
361 if (specifics.has_managed_user_shared_setting())
362 return SUPERVISED_USER_SHARED_SETTINGS;
364 if (specifics.has_managed_user_whitelist())
365 return SUPERVISED_USER_WHITELISTS;
367 if (specifics.has_article())
368 return ARTICLES;
370 if (specifics.has_wifi_credential())
371 return WIFI_CREDENTIALS;
373 return UNSPECIFIED;
376 ModelTypeSet ProtocolTypes() {
377 ModelTypeSet set = ModelTypeSet::All();
378 set.RemoveAll(ProxyTypes());
379 return set;
382 ModelTypeSet UserTypes() {
383 ModelTypeSet set;
384 // TODO(sync): We should be able to build the actual enumset's internal
385 // bitset value here at compile time, rather than performing an iteration
386 // every time.
387 for (int i = FIRST_USER_MODEL_TYPE; i <= LAST_USER_MODEL_TYPE; ++i) {
388 set.Put(ModelTypeFromInt(i));
390 return set;
393 ModelTypeSet UserSelectableTypes() {
394 ModelTypeSet set;
395 // Although the order doesn't technically matter here, it's clearer to keep
396 // these in the same order as their definition in the ModelType enum.
397 set.Put(BOOKMARKS);
398 set.Put(PREFERENCES);
399 set.Put(PASSWORDS);
400 set.Put(AUTOFILL);
401 set.Put(THEMES);
402 set.Put(TYPED_URLS);
403 set.Put(EXTENSIONS);
404 set.Put(APPS);
405 set.Put(WIFI_CREDENTIALS);
406 set.Put(PROXY_TABS);
407 return set;
410 bool IsUserSelectableType(ModelType model_type) {
411 return UserSelectableTypes().Has(model_type);
414 ModelTypeNameMap GetUserSelectableTypeNameMap() {
415 ModelTypeNameMap type_names;
416 ModelTypeSet type_set = UserSelectableTypes();
417 ModelTypeSet::Iterator it = type_set.First();
418 DCHECK_EQ(arraysize(kUserSelectableDataTypeNames), type_set.Size());
419 for (size_t i = 0; i < arraysize(kUserSelectableDataTypeNames) && it.Good();
420 ++i, it.Inc()) {
421 type_names[it.Get()] = kUserSelectableDataTypeNames[i];
423 return type_names;
426 ModelTypeSet EncryptableUserTypes() {
427 ModelTypeSet encryptable_user_types = UserTypes();
428 // We never encrypt history delete directives.
429 encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
430 // Synced notifications are not encrypted since the server must see changes.
431 encryptable_user_types.Remove(SYNCED_NOTIFICATIONS);
432 // Synced Notification App Info does not have private data, so it is not
433 // encrypted.
434 encryptable_user_types.Remove(SYNCED_NOTIFICATION_APP_INFO);
435 // Device info data is not encrypted because it might be synced before
436 // encryption is ready.
437 encryptable_user_types.Remove(DEVICE_INFO);
438 // Priority preferences are not encrypted because they might be synced before
439 // encryption is ready.
440 encryptable_user_types.Remove(PRIORITY_PREFERENCES);
441 // Supervised user settings are not encrypted since they are set server-side.
442 encryptable_user_types.Remove(SUPERVISED_USER_SETTINGS);
443 // Supervised users are not encrypted since they are managed server-side.
444 encryptable_user_types.Remove(SUPERVISED_USERS);
445 // Supervised user shared settings are not encrypted since they are managed
446 // server-side and shared between manager and supervised user.
447 encryptable_user_types.Remove(SUPERVISED_USER_SHARED_SETTINGS);
448 // Supervised user whitelists are not encrypted since they are managed
449 // server-side.
450 encryptable_user_types.Remove(SUPERVISED_USER_WHITELISTS);
451 // Proxy types have no sync representation and are therefore not encrypted.
452 // Note however that proxy types map to one or more protocol types, which
453 // may or may not be encrypted themselves.
454 encryptable_user_types.RemoveAll(ProxyTypes());
455 // Wallet data is not encrypted since it actually originates on the server.
456 encryptable_user_types.Remove(AUTOFILL_WALLET_DATA);
457 return encryptable_user_types;
460 ModelTypeSet PriorityUserTypes() {
461 return ModelTypeSet(DEVICE_INFO, PRIORITY_PREFERENCES);
464 ModelTypeSet ControlTypes() {
465 ModelTypeSet set;
466 // TODO(sync): We should be able to build the actual enumset's internal
467 // bitset value here at compile time, rather than performing an iteration
468 // every time.
469 for (int i = FIRST_CONTROL_MODEL_TYPE; i <= LAST_CONTROL_MODEL_TYPE; ++i) {
470 set.Put(ModelTypeFromInt(i));
473 return set;
476 ModelTypeSet ProxyTypes() {
477 ModelTypeSet set;
478 set.Put(PROXY_TABS);
479 return set;
482 bool IsControlType(ModelType model_type) {
483 return ControlTypes().Has(model_type);
486 ModelTypeSet CoreTypes() {
487 syncer::ModelTypeSet result;
488 result.PutAll(PriorityCoreTypes());
490 // The following are low priority core types.
491 result.Put(SYNCED_NOTIFICATIONS);
492 result.Put(SYNCED_NOTIFICATION_APP_INFO);
493 result.Put(SUPERVISED_USER_SHARED_SETTINGS);
494 result.Put(SUPERVISED_USER_WHITELISTS);
496 return result;
499 ModelTypeSet PriorityCoreTypes() {
500 syncer::ModelTypeSet result;
501 result.PutAll(ControlTypes());
503 // The following are non-control core types.
504 result.Put(SUPERVISED_USERS);
505 result.Put(SUPERVISED_USER_SETTINGS);
507 return result;
510 ModelTypeSet BackupTypes() {
511 ModelTypeSet result;
512 result.Put(BOOKMARKS);
513 result.Put(PREFERENCES);
514 result.Put(THEMES);
515 result.Put(EXTENSIONS);
516 result.Put(SEARCH_ENGINES);
517 result.Put(APPS);
518 result.Put(APP_LIST);
519 result.Put(APP_SETTINGS);
520 result.Put(EXTENSION_SETTINGS);
521 result.Put(PRIORITY_PREFERENCES);
522 return result;
525 const char* ModelTypeToString(ModelType model_type) {
526 // This is used in serialization routines as well as for displaying debug
527 // information. Do not attempt to change these string values unless you know
528 // what you're doing.
529 switch (model_type) {
530 case TOP_LEVEL_FOLDER:
531 return "Top Level Folder";
532 case UNSPECIFIED:
533 return "Unspecified";
534 case BOOKMARKS:
535 return "Bookmarks";
536 case PREFERENCES:
537 return "Preferences";
538 case PASSWORDS:
539 return "Passwords";
540 case AUTOFILL:
541 return "Autofill";
542 case THEMES:
543 return "Themes";
544 case TYPED_URLS:
545 return "Typed URLs";
546 case EXTENSIONS:
547 return "Extensions";
548 case NIGORI:
549 return "Encryption keys";
550 case SEARCH_ENGINES:
551 return "Search Engines";
552 case SESSIONS:
553 return "Sessions";
554 case APPS:
555 return "Apps";
556 case APP_LIST:
557 return "App List";
558 case AUTOFILL_PROFILE:
559 return "Autofill Profiles";
560 case APP_SETTINGS:
561 return "App settings";
562 case EXTENSION_SETTINGS:
563 return "Extension settings";
564 case APP_NOTIFICATIONS:
565 return "App Notifications";
566 case HISTORY_DELETE_DIRECTIVES:
567 return "History Delete Directives";
568 case SYNCED_NOTIFICATIONS:
569 return "Synced Notifications";
570 case SYNCED_NOTIFICATION_APP_INFO:
571 return "Synced Notification App Info";
572 case DEVICE_INFO:
573 return "Device Info";
574 case EXPERIMENTS:
575 return "Experiments";
576 case PRIORITY_PREFERENCES:
577 return "Priority Preferences";
578 case DICTIONARY:
579 return "Dictionary";
580 case FAVICON_IMAGES:
581 return "Favicon Images";
582 case FAVICON_TRACKING:
583 return "Favicon Tracking";
584 case SUPERVISED_USER_SETTINGS:
585 return "Managed User Settings";
586 case SUPERVISED_USERS:
587 return "Managed Users";
588 case SUPERVISED_USER_SHARED_SETTINGS:
589 return "Managed User Shared Settings";
590 case SUPERVISED_USER_WHITELISTS:
591 return "Managed User Whitelists";
592 case ARTICLES:
593 return "Articles";
594 case WIFI_CREDENTIALS:
595 return "WiFi Credentials";
596 case PROXY_TABS:
597 return "Tabs";
598 case AUTOFILL_WALLET_DATA:
599 return "Autofill Wallet";
600 default:
601 break;
603 NOTREACHED() << "No known extension for model type.";
604 return "INVALID";
607 // The normal rules about histograms apply here. Always append to the bottom of
608 // the list, and be careful to not reuse integer values that have already been
609 // assigned.
611 // Don't forget to update the "SyncModelTypes" enum in histograms.xml when you
612 // make changes to this list.
613 int ModelTypeToHistogramInt(ModelType model_type) {
614 switch (model_type) {
615 case UNSPECIFIED:
616 return 0;
617 case TOP_LEVEL_FOLDER:
618 return 1;
619 case BOOKMARKS:
620 return 2;
621 case PREFERENCES:
622 return 3;
623 case PASSWORDS:
624 return 4;
625 case AUTOFILL_PROFILE:
626 return 5;
627 case AUTOFILL:
628 return 6;
629 case THEMES:
630 return 7;
631 case TYPED_URLS:
632 return 8;
633 case EXTENSIONS:
634 return 9;
635 case SEARCH_ENGINES:
636 return 10;
637 case SESSIONS:
638 return 11;
639 case APPS:
640 return 12;
641 case APP_SETTINGS:
642 return 13;
643 case EXTENSION_SETTINGS:
644 return 14;
645 case APP_NOTIFICATIONS:
646 return 15;
647 case HISTORY_DELETE_DIRECTIVES:
648 return 16;
649 case NIGORI:
650 return 17;
651 case DEVICE_INFO:
652 return 18;
653 case EXPERIMENTS:
654 return 19;
655 case SYNCED_NOTIFICATIONS:
656 return 20;
657 case PRIORITY_PREFERENCES:
658 return 21;
659 case DICTIONARY:
660 return 22;
661 case FAVICON_IMAGES:
662 return 23;
663 case FAVICON_TRACKING:
664 return 24;
665 case PROXY_TABS:
666 return 25;
667 case SUPERVISED_USER_SETTINGS:
668 return 26;
669 case SUPERVISED_USERS:
670 return 27;
671 case ARTICLES:
672 return 28;
673 case APP_LIST:
674 return 29;
675 case SUPERVISED_USER_SHARED_SETTINGS:
676 return 30;
677 case SYNCED_NOTIFICATION_APP_INFO:
678 return 31;
679 case WIFI_CREDENTIALS:
680 return 32;
681 case SUPERVISED_USER_WHITELISTS:
682 return 33;
683 case AUTOFILL_WALLET_DATA:
684 return 34;
685 // Silence a compiler warning.
686 case MODEL_TYPE_COUNT:
687 return 0;
689 return 0;
692 base::StringValue* ModelTypeToValue(ModelType model_type) {
693 if (model_type >= FIRST_REAL_MODEL_TYPE) {
694 return new base::StringValue(ModelTypeToString(model_type));
695 } else if (model_type == TOP_LEVEL_FOLDER) {
696 return new base::StringValue("Top-level folder");
697 } else if (model_type == UNSPECIFIED) {
698 return new base::StringValue("Unspecified");
700 NOTREACHED();
701 return new base::StringValue(std::string());
704 ModelType ModelTypeFromValue(const base::Value& value) {
705 if (value.IsType(base::Value::TYPE_STRING)) {
706 std::string result;
707 CHECK(value.GetAsString(&result));
708 return ModelTypeFromString(result);
709 } else if (value.IsType(base::Value::TYPE_INTEGER)) {
710 int result;
711 CHECK(value.GetAsInteger(&result));
712 return ModelTypeFromInt(result);
713 } else {
714 NOTREACHED() << "Unsupported value type: " << value.GetType();
715 return UNSPECIFIED;
719 ModelType ModelTypeFromString(const std::string& model_type_string) {
720 if (model_type_string == "Bookmarks")
721 return BOOKMARKS;
722 else if (model_type_string == "Preferences")
723 return PREFERENCES;
724 else if (model_type_string == "Passwords")
725 return PASSWORDS;
726 else if (model_type_string == "Autofill")
727 return AUTOFILL;
728 else if (model_type_string == "Autofill Profiles")
729 return AUTOFILL_PROFILE;
730 else if (model_type_string == "Autofill Wallet")
731 return AUTOFILL_WALLET_DATA;
732 else if (model_type_string == "Themes")
733 return THEMES;
734 else if (model_type_string == "Typed URLs")
735 return TYPED_URLS;
736 else if (model_type_string == "Extensions")
737 return EXTENSIONS;
738 else if (model_type_string == "Encryption keys")
739 return NIGORI;
740 else if (model_type_string == "Search Engines")
741 return SEARCH_ENGINES;
742 else if (model_type_string == "Sessions")
743 return SESSIONS;
744 else if (model_type_string == "Apps")
745 return APPS;
746 else if (model_type_string == "App List")
747 return APP_LIST;
748 else if (model_type_string == "App settings")
749 return APP_SETTINGS;
750 else if (model_type_string == "Extension settings")
751 return EXTENSION_SETTINGS;
752 else if (model_type_string == "App Notifications")
753 return APP_NOTIFICATIONS;
754 else if (model_type_string == "History Delete Directives")
755 return HISTORY_DELETE_DIRECTIVES;
756 else if (model_type_string == "Synced Notifications")
757 return SYNCED_NOTIFICATIONS;
758 else if (model_type_string == "Synced Notification App Info")
759 return SYNCED_NOTIFICATION_APP_INFO;
760 else if (model_type_string == "Device Info")
761 return DEVICE_INFO;
762 else if (model_type_string == "Experiments")
763 return EXPERIMENTS;
764 else if (model_type_string == "Priority Preferences")
765 return PRIORITY_PREFERENCES;
766 else if (model_type_string == "Dictionary")
767 return DICTIONARY;
768 else if (model_type_string == "Favicon Images")
769 return FAVICON_IMAGES;
770 else if (model_type_string == "Favicon Tracking")
771 return FAVICON_TRACKING;
772 else if (model_type_string == "Managed User Settings")
773 return SUPERVISED_USER_SETTINGS;
774 else if (model_type_string == "Managed Users")
775 return SUPERVISED_USERS;
776 else if (model_type_string == "Managed User Shared Settings")
777 return SUPERVISED_USER_SHARED_SETTINGS;
778 else if (model_type_string == "Managed User Whitelists")
779 return SUPERVISED_USER_WHITELISTS;
780 else if (model_type_string == "Articles")
781 return ARTICLES;
782 else if (model_type_string == "WiFi Credentials")
783 return WIFI_CREDENTIALS;
784 else if (model_type_string == "Tabs")
785 return PROXY_TABS;
786 else
787 NOTREACHED() << "No known model type corresponding to "
788 << model_type_string << ".";
789 return UNSPECIFIED;
792 std::string ModelTypeSetToString(ModelTypeSet model_types) {
793 std::string result;
794 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
795 if (!result.empty()) {
796 result += ", ";
798 result += ModelTypeToString(it.Get());
800 return result;
803 ModelTypeSet ModelTypeSetFromString(const std::string& model_types_string) {
804 std::string working_copy = model_types_string;
805 ModelTypeSet model_types;
806 while (!working_copy.empty()) {
807 // Remove any leading spaces.
808 working_copy = working_copy.substr(working_copy.find_first_not_of(' '));
809 if (working_copy.empty())
810 break;
811 std::string type_str;
812 size_t end = working_copy.find(',');
813 if (end == std::string::npos) {
814 end = working_copy.length() - 1;
815 type_str = working_copy;
816 } else {
817 type_str = working_copy.substr(0, end);
819 syncer::ModelType type = ModelTypeFromString(type_str);
820 if (IsRealDataType(type))
821 model_types.Put(type);
822 working_copy = working_copy.substr(end + 1);
824 return model_types;
827 base::ListValue* ModelTypeSetToValue(ModelTypeSet model_types) {
828 base::ListValue* value = new base::ListValue();
829 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
830 value->Append(new base::StringValue(ModelTypeToString(it.Get())));
832 return value;
835 ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value) {
836 ModelTypeSet result;
837 for (base::ListValue::const_iterator i = value.begin();
838 i != value.end(); ++i) {
839 result.Put(ModelTypeFromValue(**i));
841 return result;
844 // TODO(zea): remove all hardcoded tags in model associators and have them use
845 // this instead.
846 // NOTE: Proxy types should return empty strings (so that we don't NOTREACHED
847 // in tests when we verify they have no root node).
848 std::string ModelTypeToRootTag(ModelType type) {
849 switch (type) {
850 case BOOKMARKS:
851 return "google_chrome_bookmarks";
852 case PREFERENCES:
853 return "google_chrome_preferences";
854 case PASSWORDS:
855 return "google_chrome_passwords";
856 case AUTOFILL:
857 return "google_chrome_autofill";
858 case THEMES:
859 return "google_chrome_themes";
860 case TYPED_URLS:
861 return "google_chrome_typed_urls";
862 case EXTENSIONS:
863 return "google_chrome_extensions";
864 case NIGORI:
865 return "google_chrome_nigori";
866 case SEARCH_ENGINES:
867 return "google_chrome_search_engines";
868 case SESSIONS:
869 return "google_chrome_sessions";
870 case APPS:
871 return "google_chrome_apps";
872 case APP_LIST:
873 return "google_chrome_app_list";
874 case AUTOFILL_PROFILE:
875 return "google_chrome_autofill_profiles";
876 case AUTOFILL_WALLET_DATA:
877 return "google_chrome_autofill_wallet";
878 case APP_SETTINGS:
879 return "google_chrome_app_settings";
880 case EXTENSION_SETTINGS:
881 return "google_chrome_extension_settings";
882 case APP_NOTIFICATIONS:
883 return "google_chrome_app_notifications";
884 case HISTORY_DELETE_DIRECTIVES:
885 return "google_chrome_history_delete_directives";
886 case SYNCED_NOTIFICATIONS:
887 return "google_chrome_synced_notifications";
888 case SYNCED_NOTIFICATION_APP_INFO:
889 return "google_chrome_synced_notification_app_info";
890 case DEVICE_INFO:
891 return "google_chrome_device_info";
892 case EXPERIMENTS:
893 return "google_chrome_experiments";
894 case PRIORITY_PREFERENCES:
895 return "google_chrome_priority_preferences";
896 case DICTIONARY:
897 return "google_chrome_dictionary";
898 case FAVICON_IMAGES:
899 return "google_chrome_favicon_images";
900 case FAVICON_TRACKING:
901 return "google_chrome_favicon_tracking";
902 case SUPERVISED_USER_SETTINGS:
903 return "google_chrome_managed_user_settings";
904 case SUPERVISED_USERS:
905 return "google_chrome_managed_users";
906 case SUPERVISED_USER_SHARED_SETTINGS:
907 return "google_chrome_managed_user_shared_settings";
908 case SUPERVISED_USER_WHITELISTS:
909 return "google_chrome_managed_user_whitelists";
910 case ARTICLES:
911 return "google_chrome_articles";
912 case WIFI_CREDENTIALS:
913 return "google_chrome_wifi_credentials";
914 case PROXY_TABS:
915 return std::string();
916 default:
917 break;
919 NOTREACHED() << "No known extension for model type.";
920 return "INVALID";
923 // TODO(akalin): Figure out a better way to do these mappings.
924 // Note: Do not include proxy types in this list. They should never receive
925 // or trigger notifications.
926 namespace {
927 const char kBookmarkNotificationType[] = "BOOKMARK";
928 const char kPreferenceNotificationType[] = "PREFERENCE";
929 const char kPasswordNotificationType[] = "PASSWORD";
930 const char kAutofillNotificationType[] = "AUTOFILL";
931 const char kThemeNotificationType[] = "THEME";
932 const char kTypedUrlNotificationType[] = "TYPED_URL";
933 const char kExtensionNotificationType[] = "EXTENSION";
934 const char kExtensionSettingNotificationType[] = "EXTENSION_SETTING";
935 const char kNigoriNotificationType[] = "NIGORI";
936 const char kAppSettingNotificationType[] = "APP_SETTING";
937 const char kAppNotificationType[] = "APP";
938 const char kAppListNotificationType[] = "APP_LIST";
939 const char kSearchEngineNotificationType[] = "SEARCH_ENGINE";
940 const char kSessionNotificationType[] = "SESSION";
941 const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE";
942 const char kAutofillWalletNotificationType[] = "AUTOFILL_WALLET";
943 const char kAppNotificationNotificationType[] = "APP_NOTIFICATION";
944 const char kHistoryDeleteDirectiveNotificationType[] =
945 "HISTORY_DELETE_DIRECTIVE";
946 const char kSyncedNotificationType[] = "SYNCED_NOTIFICATION";
947 const char kSyncedNotificationAppInfoType[] = "SYNCED_NOTIFICATION_APP_INFO";
948 const char kDeviceInfoNotificationType[] = "DEVICE_INFO";
949 const char kExperimentsNotificationType[] = "EXPERIMENTS";
950 const char kPriorityPreferenceNotificationType[] = "PRIORITY_PREFERENCE";
951 const char kDictionaryNotificationType[] = "DICTIONARY";
952 const char kFaviconImageNotificationType[] = "FAVICON_IMAGE";
953 const char kFaviconTrackingNotificationType[] = "FAVICON_TRACKING";
954 const char kSupervisedUserSettingNotificationType[] = "MANAGED_USER_SETTING";
955 const char kSupervisedUserNotificationType[] = "MANAGED_USER";
956 const char kSupervisedUserSharedSettingNotificationType[] =
957 "MANAGED_USER_SHARED_SETTING";
958 const char kSupervisedUserWhitelistNotificationType[] =
959 "MANAGED_USER_WHITELIST";
960 const char kArticleNotificationType[] = "ARTICLE";
961 const char kWifiCredentialNotificationType[] = "WIFI_CREDENTIAL";
962 } // namespace
964 bool RealModelTypeToNotificationType(ModelType model_type,
965 std::string* notification_type) {
966 switch (model_type) {
967 case BOOKMARKS:
968 *notification_type = kBookmarkNotificationType;
969 return true;
970 case PREFERENCES:
971 *notification_type = kPreferenceNotificationType;
972 return true;
973 case PASSWORDS:
974 *notification_type = kPasswordNotificationType;
975 return true;
976 case AUTOFILL:
977 *notification_type = kAutofillNotificationType;
978 return true;
979 case THEMES:
980 *notification_type = kThemeNotificationType;
981 return true;
982 case TYPED_URLS:
983 *notification_type = kTypedUrlNotificationType;
984 return true;
985 case EXTENSIONS:
986 *notification_type = kExtensionNotificationType;
987 return true;
988 case NIGORI:
989 *notification_type = kNigoriNotificationType;
990 return true;
991 case APP_SETTINGS:
992 *notification_type = kAppSettingNotificationType;
993 return true;
994 case APPS:
995 *notification_type = kAppNotificationType;
996 return true;
997 case APP_LIST:
998 *notification_type = kAppListNotificationType;
999 return true;
1000 case SEARCH_ENGINES:
1001 *notification_type = kSearchEngineNotificationType;
1002 return true;
1003 case SESSIONS:
1004 *notification_type = kSessionNotificationType;
1005 return true;
1006 case AUTOFILL_PROFILE:
1007 *notification_type = kAutofillProfileNotificationType;
1008 return true;
1009 case AUTOFILL_WALLET_DATA:
1010 *notification_type = kAutofillWalletNotificationType;
1011 return true;
1012 case EXTENSION_SETTINGS:
1013 *notification_type = kExtensionSettingNotificationType;
1014 return true;
1015 case APP_NOTIFICATIONS:
1016 *notification_type = kAppNotificationNotificationType;
1017 return true;
1018 case HISTORY_DELETE_DIRECTIVES:
1019 *notification_type = kHistoryDeleteDirectiveNotificationType;
1020 return true;
1021 case SYNCED_NOTIFICATIONS:
1022 *notification_type = kSyncedNotificationType;
1023 return true;
1024 case SYNCED_NOTIFICATION_APP_INFO:
1025 *notification_type = kSyncedNotificationAppInfoType;
1026 return true;
1027 case DEVICE_INFO:
1028 *notification_type = kDeviceInfoNotificationType;
1029 return true;
1030 case EXPERIMENTS:
1031 *notification_type = kExperimentsNotificationType;
1032 return true;
1033 case PRIORITY_PREFERENCES:
1034 *notification_type = kPriorityPreferenceNotificationType;
1035 return true;
1036 case DICTIONARY:
1037 *notification_type = kDictionaryNotificationType;
1038 return true;
1039 case FAVICON_IMAGES:
1040 *notification_type = kFaviconImageNotificationType;
1041 return true;
1042 case FAVICON_TRACKING:
1043 *notification_type = kFaviconTrackingNotificationType;
1044 return true;
1045 case SUPERVISED_USER_SETTINGS:
1046 *notification_type = kSupervisedUserSettingNotificationType;
1047 return true;
1048 case SUPERVISED_USERS:
1049 *notification_type = kSupervisedUserNotificationType;
1050 return true;
1051 case SUPERVISED_USER_SHARED_SETTINGS:
1052 *notification_type = kSupervisedUserSharedSettingNotificationType;
1053 return true;
1054 case SUPERVISED_USER_WHITELISTS:
1055 *notification_type = kSupervisedUserWhitelistNotificationType;
1056 return true;
1057 case ARTICLES:
1058 *notification_type = kArticleNotificationType;
1059 return true;
1060 case WIFI_CREDENTIALS:
1061 *notification_type = kWifiCredentialNotificationType;
1062 return true;
1063 default:
1064 break;
1066 notification_type->clear();
1067 return false;
1070 bool NotificationTypeToRealModelType(const std::string& notification_type,
1071 ModelType* model_type) {
1072 if (notification_type == kBookmarkNotificationType) {
1073 *model_type = BOOKMARKS;
1074 return true;
1075 } else if (notification_type == kPreferenceNotificationType) {
1076 *model_type = PREFERENCES;
1077 return true;
1078 } else if (notification_type == kPasswordNotificationType) {
1079 *model_type = PASSWORDS;
1080 return true;
1081 } else if (notification_type == kAutofillNotificationType) {
1082 *model_type = AUTOFILL;
1083 return true;
1084 } else if (notification_type == kThemeNotificationType) {
1085 *model_type = THEMES;
1086 return true;
1087 } else if (notification_type == kTypedUrlNotificationType) {
1088 *model_type = TYPED_URLS;
1089 return true;
1090 } else if (notification_type == kExtensionNotificationType) {
1091 *model_type = EXTENSIONS;
1092 return true;
1093 } else if (notification_type == kNigoriNotificationType) {
1094 *model_type = NIGORI;
1095 return true;
1096 } else if (notification_type == kAppNotificationType) {
1097 *model_type = APPS;
1098 return true;
1099 } else if (notification_type == kAppListNotificationType) {
1100 *model_type = APP_LIST;
1101 return true;
1102 } else if (notification_type == kSearchEngineNotificationType) {
1103 *model_type = SEARCH_ENGINES;
1104 return true;
1105 } else if (notification_type == kSessionNotificationType) {
1106 *model_type = SESSIONS;
1107 return true;
1108 } else if (notification_type == kAutofillProfileNotificationType) {
1109 *model_type = AUTOFILL_PROFILE;
1110 return true;
1111 } else if (notification_type == kAutofillWalletNotificationType) {
1112 *model_type = AUTOFILL_WALLET_DATA;
1113 return true;
1114 } else if (notification_type == kAppSettingNotificationType) {
1115 *model_type = APP_SETTINGS;
1116 return true;
1117 } else if (notification_type == kExtensionSettingNotificationType) {
1118 *model_type = EXTENSION_SETTINGS;
1119 return true;
1120 } else if (notification_type == kAppNotificationNotificationType) {
1121 *model_type = APP_NOTIFICATIONS;
1122 return true;
1123 } else if (notification_type == kHistoryDeleteDirectiveNotificationType) {
1124 *model_type = HISTORY_DELETE_DIRECTIVES;
1125 return true;
1126 } else if (notification_type == kSyncedNotificationType) {
1127 *model_type = SYNCED_NOTIFICATIONS;
1128 return true;
1129 } else if (notification_type == kSyncedNotificationAppInfoType) {
1130 *model_type = SYNCED_NOTIFICATION_APP_INFO;
1131 return true;
1132 } else if (notification_type == kDeviceInfoNotificationType) {
1133 *model_type = DEVICE_INFO;
1134 return true;
1135 } else if (notification_type == kExperimentsNotificationType) {
1136 *model_type = EXPERIMENTS;
1137 return true;
1138 } else if (notification_type == kPriorityPreferenceNotificationType) {
1139 *model_type = PRIORITY_PREFERENCES;
1140 return true;
1141 } else if (notification_type == kDictionaryNotificationType) {
1142 *model_type = DICTIONARY;
1143 return true;
1144 } else if (notification_type == kFaviconImageNotificationType) {
1145 *model_type = FAVICON_IMAGES;
1146 return true;
1147 } else if (notification_type == kFaviconTrackingNotificationType) {
1148 *model_type = FAVICON_TRACKING;
1149 return true;
1150 } else if (notification_type == kSupervisedUserSettingNotificationType) {
1151 *model_type = SUPERVISED_USER_SETTINGS;
1152 return true;
1153 } else if (notification_type == kSupervisedUserNotificationType) {
1154 *model_type = SUPERVISED_USERS;
1155 return true;
1156 } else if (notification_type ==
1157 kSupervisedUserSharedSettingNotificationType) {
1158 *model_type = SUPERVISED_USER_SHARED_SETTINGS;
1159 return true;
1160 } else if (notification_type == kSupervisedUserWhitelistNotificationType) {
1161 *model_type = SUPERVISED_USER_WHITELISTS;
1162 return true;
1163 } else if (notification_type == kArticleNotificationType) {
1164 *model_type = ARTICLES;
1165 return true;
1166 } else if (notification_type == kWifiCredentialNotificationType) {
1167 *model_type = WIFI_CREDENTIALS;
1168 return true;
1170 *model_type = UNSPECIFIED;
1171 return false;
1174 bool IsRealDataType(ModelType model_type) {
1175 return model_type >= FIRST_REAL_MODEL_TYPE && model_type < MODEL_TYPE_COUNT;
1178 bool IsProxyType(ModelType model_type) {
1179 return model_type >= FIRST_PROXY_TYPE && model_type <= LAST_PROXY_TYPE;
1182 bool IsActOnceDataType(ModelType model_type) {
1183 return model_type == HISTORY_DELETE_DIRECTIVES;
1186 bool IsTypeWithServerGeneratedRoot(ModelType model_type) {
1187 return model_type == BOOKMARKS || model_type == NIGORI;
1190 bool IsTypeWithClientGeneratedRoot(ModelType model_type) {
1191 return IsRealDataType(model_type) &&
1192 !IsTypeWithServerGeneratedRoot(model_type);
1195 } // namespace syncer