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